使用Docker搭建集群,快速部署
随着项目的成长,业务的需要。集群\分布式\负载均衡便是必不可少。以前的单机“玩具”,也一去不复返了。那么改如何快速部署,搭建集群、实时更新。相信是你,当然也是我非常关心的问题。
那么该如何去做呢?
- 建议:
拥有一定的Docker基础,查阅本文一定会收获的更多。
同时我也希望能与你探讨相关问题
环境准备
- 两台或多台服务器。(当然虚拟机也可,注意需要两台或多台以上)
- 均以完成docker、docker-compose 安装。
- 验证docker安装
docker run hello-world
单机Dockerfile
编写业务代码
新建文件夹-webDemo, 并进入
编辑业务代码 -> app.py
# mkdir webDemo && cd webDemo vim app.py
业务代码如下
from flask import Flaskfrom redis import Redis app = Flask(__name__) redis = Redis(host='redis', port=6379)@app.route('/')def hello(): count = redis.incr('hits') return 'Hello World! I have been seen {} times.\n'.format(count)if __name__ == "__main__": app.run(host="0.0.0.0", port=8000, debug=True)
编写requirements.txt
由于容器中为
干净
的目录,仅有基础的Linux镜像
requirements.txt 如下
flask # python 中 web框架redis # 数据库Redis远程字典,此项目中用于web做缓存
编写Dockerfile
FROM python:3.7-alpine # 基于 python:3.7-alpine 容器 ADD . /code # 将本目录下所有的文件复制到容器中code目录下(code目录若不存在则自动创建) WORKDIR /code # 将工作目录设为code RUN pip install -r requirements.txt # 安装所需第三方包(构建容器时运行) CMD ["python", "app.py"] # 容器启动时运行
构建、运行、验证
# 构建容器名为 webDemo的容器 docker build -t webdome .# 运行 -d 为后台运行, --name web 此次运行webdemo容器的服务备注webdocker build -d -p 8000:8000 -name web webdemo
构建效果如下
运行效果如下
当然,你也可以定制端口
单机测试-docker-compose
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
在原有的文件夹中新增docker-compse.yaml
docker-compse.yaml 内容如下
version: "3.3" services: web: image: webdemo # 镜像名 build: . ports: - "8000:8000" redis: image: redis:alpine
构建、运行、验证
单机多台
主要改写如下,
deploy:
replicas: 5
单机部署5⃣️台
version: "3.3" services: web: image: webdemo # 镜像名 build: . deploy: replicas: 5 ports: - "8000:8000" redis: image: redis:alpine
为什么需要使用分布式、集群、负载均衡?
单机局限性
单台服务器的性能毕竟有限,综合利用多个节点的处理能力,才能提高整体的服务能力
只要是满足指定的是交互协议,各模块可以根据各自的业务特点,选择不同的处理方式
为什么需要使用分布式?
高可用、高性能、高可脱
海量、多样、实时
分布式系统与集群的关系
分布式:不同的业务模块部署在不同的服务器上或者同一个业务模块分拆多个子业务,部署在不同的服务器上,解决高并发的问题
集群:同一个业务部署在多台机器上,提高系统可用性
分布式是指将不同的业务分布在不同的地方。而集群指的是将几台服务器集中在一起,实现同一业务。
分布式中的每一个节点,都可以做集群。而集群并不一定就是分布式的。
分布式是以缩短单个任务的执行时间来提升效率的,而集群则是通过提高单位时间内执行的任务数来提升效率
请思考 分布式、集群、分布式之间的枢纽是什么?,如何保证他们的“共同作战”?
Docker swarm
Docker Swarm是Docker自带的一个集群管理模块。他能够实现Docker集群的创建和管理。
它主要的包含两个部署模块
- service create
- stack
分别是依赖于Dockerfile,以及docker-compose
初始化节点-创建Manager节点
docker swarm init docker swarm init --advertise-addr string # 多个网卡需加advertise-addr指定网卡
创建manager节点完成,并获取到了join-token
,直接将自己生成的token复制到其他集群上,即可加入
(若不小心clear掉了之后,只需在manager节点上一下命令即可获取。注请在manager节点上进行操作)
# 获取加入管理节点令牌 docker swarm join-token manager # 获取加入工作节点令牌 docker swarm join-token worker
加入完成后,效果如下
构建私有仓库(可选)
建议构建私人仓库,理由如下
- 保证源码安全
- 极速动态更新(加速项目构建、迭代)
创建 docker service create --name registry --publish published=5000,target=5000 registry:2 验证 docker service ls curl http://localhost:5000/v2/
docker service 部署
- 注意
如果您要在本地开发环境中尝试操作,则可以使用来将引擎置于群集模式
docker swarm init
。
如果您已经在运行多节点群集,请记住,所有 命令
docker stack
和docker service
命令都必须从管理器节点运行。
新建一个文件夹(demo),由于之前以及做过一次了,此次快速完成
# mkdir webDemo && cd webDemo vim app.py
业务代码如下
from flask import Flaskfrom redis import Redis app = Flask(__name__) redis = Redis(host='redis', port=6379)@app.route('/')def hello(): count = redis.incr('hits') return 'Hello World! I have been seen {} times.\n'.format(count)if __name__ == "__main__": app.run(host="0.0.0.0", port=8000, debug=True)
编写requirements.txt
由于容器中为
干净
的目录,仅有基础的Linux镜像
requirements.txt 如下
flask # python 中 web框架redis # 数据库Redis远程字典,此项目中用于web做缓存
编写Dockerfile
FROM python:3.7-alpine # 基于 python:3.7-alpine 容器 ADD . /code # 将本目录下所有的文件复制到容器中code目录下(code目录若不存在则自动创建) WORKDIR /code # 将工作目录设为code RUN pip install -r requirements.txt # 安装所需第三方包(构建容器时运行) CMD ["python", "app.py"] # 容器启动时运行
⚠️构建,推送
docker build -t 127.0.0.1:5000/demo:1 . docker push 127.0.0.1:5000/demo:1
创建服务
docker service create --name crawler 127.0.0.1:5000/demo:1 # 查看服务docker service ls
动态扩所容
# 五十台机器的分布式集群搭建完成docker service scale crawler=50# 停止docker service scale crawler=0# 更新推送新版本内容至127.0.0.1:5000例如:docker push 127.0.0.1:5000/demo:2# 方法一:docker service scale crawler=0docker service update --image 127.0.0.1:5000/demo:2 crawler docker service scale =3# 方法二:docker service update --image 127.0.0.1:5000/demo:2 crawler# 二者的区别是,直接执行更新命令时,正在运行的容器会一个一个更新。
docker stack 部署
新增docker-compose.yaml
version: "3.3" services: web: image: 127.0.0.1:5000/stackdemo build: . ports: - "8000:8000" redis: image: redis
运行测试一台机器
docker-compose up -d# 停止并保存docker-compose down --volumes # docker-compose.yaml中已经制定了images,所以它是直接推送到私有仓库中到# 推送至私有仓库docker-compose push
部署
docker stack deploy --compose-file docker-compose.yaml stackdemo# 查看运行状态docker stack services stackdemo# 五十台机器的分布式集群搭建完成docker service scale stackdemo=50# 停止docker service scale stackdemo=0# 更新推送新版本内容至127.0.0.1:5000例如:docker-compose push 127.0.0.1:5000/stackdemo:2# 方法一:docker service scale stackdemo=0docker service update --image 127.0.0.1:5000/stackdemo:2docker service scale =3# 方法二:docker service update --image 127.0.0.1:5000/stackdemo:2# 二者的区别是,直接执行更新命令时,正在运行的容器会一个一个更新。
一键退出
docker stack rm stackdemo docker service rm registry
分布式、集群、的枢纽是什么,如何保证他们的“共同作战”?
关于这两个问题个人认为
枢纽是当然是网络啦,
保证”共同作战“的核心为统一的信号量
集群:多个人在一起做同样的事 。
分布式 :多个人在一起做不同的事 。