docker compose 主要用于单机容器编排,docker swarm 则用于跨主机容器编排。
docker compose 需要单独下载执行脚本,docker swarm 系统自带无需安装。
docker swarm 属于需要了解得东西,毕竟生产中大多选择还是 Kubernetes(K8S)。
说明:
在 docker swarm 中包含了两个角色,Manager 和 Worker。Manager 是一个集群的核心,起着调度作用,建议部署多节点,且节点数量为奇数,防止脑裂。
在 Mnager 之间通信方式采取的是 Raft 进行数据信息同步,Worker 则是工作节点。
docker swarm 创建
这里准备了 4 台虚拟机:192.168.200.101(Manager),192.168.200.102-104(Worker)
首先在 4 台机器上都安装配置启动好 docker。
1. 101 Manager 节点初始化:
docker swarm init --advertise-addr=192.168.200.101
结果如图:
注意:红色部分将是其它节点加入该集群的依据,要保存好!
2. 在 102-104 节点上面执行该命令加入集群:
docker swarm join --token SWMTKN-1-4ht8hjdp73jrkguh7ux8e5uneq2mm1ovi91oko5a8vpearh5ss-8wn5u0kf9jxd0xj6wg29wq3bq 192.168.200.101:2377
结果如下:
可以看到接入集群成功,并且是作为 worker 存在!
3. 查看集群节点情况:
docker node ls
结果如图:
从这里也可以发现主机名不一致的重要性。
此时,docker 集群中所有对于容器的处理命令都应该在 Manager 节点上面执行,再由 Manager 分发调度到各个 Worker 节点。
几种加节点常见的报错:
1. 节点加错了想删除,去该节点执行退出集群:
docker swarm leave --force
但是这并会在 Manager 节点上面删除该节点,只是将节点状态换成 Down:
重新加入该节点则会新增一个:
可以 Manager 节点上手动删除 Down 的节点:
docker node rm pdfimxsip775w7pz9hhonzatd
再度查看:
2. 加入集群时候报错:Error response from daemon: error while validating Root CA Certificate: x509: certificate has expired or is not yet valid
原因为几台机器的时间可能不一致,可以使用 ntp 同步时间后再度添加。
3. 加入等待很久没反应,报错:connect: no route to host
可能是防火墙没有关闭导致网络不通,关闭防火墙再试。
docker swarm 操作
在 docker swarm 中,容器都是 service,所以 docker swarm 的操作都是 docker service xxx 操作。
注意:所以操作都是在 Manager 节点执行的。
1. 创建一个 service:
docker service create --name b1 busybox /bin/sh -c "while true;do sleep 3000;done"
执行方式和 docker run 其实差不多。
2. 查看运行的容器:
docker service ls
结果如图:
查看运行的容器中最重要的就是这个副本数,可以知道该容器运行了几个。
3. 查看容器运行在那个具体节点:
docker service ps b1
结果如图:
可以看到运行在了 node 1 节点上。而这个 node 1 节点也是 Manager 本身。
4. 删除容器测试:
docker container rm -f f190b31bbc90
此时再度查看:
可以看到再度启动了一个容器顶替了删掉的那个。
这就看出了 swarm 的好处,它运行的容器是被 service 管理的,只要 service 不删除,下面的容器你删除之后还是能够自动重建。
5. 删除 service:
docker service rm b1
结果如图:
docker swarm 实战
再开始之前先删除掉多余的网络,volume 干扰。
其中两个是 docker swarm 需要用到的网络,在构建的时候已经自动生成。
1. 创建本次实战的专属 overlay 网络,为了和其它服务网络隔离:
docker network create -d overlay wordpress-overlay
结果如图:
2. 通过 docker swarm 创建 mysql 数据库:
docker service create --name wordpress-db --env MYSQL_ROOT_PASSWORD=123456 --env MYSQL_DATABASE=wordpress --network wordpress-overlay --mount type=volume,source=wordpress-db-data,destination=/var/lib/mysql mysql:5.7
结果如图:
3. 创建 wordpress:
docker service create --name wordpress-web -p 8000:80 --network wordpress-overlay --env WORDPRESS_DB_PASSWORD=123456 --env WORDPRESS_DB_HOST=wordpress-db wordpress
结果如图:
可以看到此时 wordpress 的服务被调度到了 node-02 节点上面。
4. 访问测试:
Manager 节点 IP 访问:
Worker 节点访问:
发现集群内所有节点的 IP 通过制定的端口都能访问到该服务。
5. 集群扩容:
当业务量上来的时候,单节点的服务器已经带不动了,就可以运行多借点的 WEB。
docker service scale wordpress-web=3
结果如图:
可以看到其余节点也被分配到了 web 服务。
关于为啥一个集群节点运行了 web 服务器所以节点的 IP 都能访问的原理:Routing mesh
1. 当一个 service 访问另外一个 service 的时候,容器之间采用的是 overlay 网络。
2. 当外部访问容器服务,其实是访问到 LVS 上面的虚拟 IP,这个 IP 和服务做了绑定,并实现了负载均衡。所以无论哪个 IP 进来,都是通过 gwbridge 网络调度到指定网络名称空间,最终都能到达 LVS 调度器。
docker swarm 中的 docker-compose.yml
和单机运行一样,docker swarm 运行多个复杂关系的容器的时候每次都需要手动敲命令,那显然是不合理的,所以它也引入了 docker-compose 文件。
https://docs.docker.com/compose/compose-file/
删除掉之前的 wordpress 项目,这次试用 docker-compose 来定义:
version: "3" # 容器 services: # 数据库 wordpress-db-demo: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: 123456 MYSQL_DATABASE: wordpress networks: - wordpress-overlay-demo volumes: - wordpress-db-data-demo:/var/lib/mysql deploy: mode: global placement: constraints: # 指定运行的节点 - node.role == manager # web wordpress-web-demo: image: wordpress ports: - 8000:80 environment: WORDPRESS_DB_PASSWORD: 123456 WORDPRESS_DB_HOST: wordpress-db-demo depends_on: - wordpress-db-demo networks: - wordpress-overlay-demo deploy: mode: replicated replicas: 3 restart_policy: condition: on-failure delay: 5s max_attempts: 3 update_config: parallelism: 2 delay: 10s placement: constraints: - node.role == worker volumes: wordpress-db-data-demo: networks: wordpress-overlay-demo: driver: overlay
相较于 docker 直接使用的 docker-compose 配置,在 docker swarm 中多了 deploy 字段。
该字段一般用于定义运行规则,如运行的类型,指定节点,运行的数量,重启规则等等。
执行运行改配置:
docker stack deploy wordpress --compose-file=docker-compose.yml
注意,在使用 docker-compose 配置的时候需要使用 stack 命令,而不再是 service 和 swarm 命令。
查看运行的容器信息:
1. 查看运行了哪些 stack:
docker stack ls
2. 查看指定 stack 运行的节点信息:
docker stack services wordpress
3. 查看容器运行的具体节点:
docker stack ps wordpress
结果如下:
当然删除同理!
服务灰度更新
1. 在所以节点上面都新增目录,app.py,Dockerfile:
mkdir flask-update-demo
cd flask-update-demo/
app.py:
from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return "Version 1.0 " if __name__=="__main__": app.run(host="0.0.0.0", port=5000)
Dockerfile:
FROM python:2.7 LABEL author="Dylan" mail="1214966109@qq.com" RUN pip install flask COPY app.py /app/ WORKDIR /app/ EXPOSE 5000 CMD ["python", "app.py"]
2. 将 Dockerfile 构建成镜像:
docker build -t dylan/flask-update-demo:v1.0 .
3. 将 app.py 中 Version 改为 2.0 再度构建镜像:
docker build -t dylan/flask-update-demo:v2.0 .
结果如图:
4. 此时部署 v1 版本:
docker network create -d overlay flask-overlay-demo
docker service create --name flask-demo -p 8000:5000 --network flask-overlay-demo dylan/flask-update-demo:v1.0
此时新开窗口访问测试:
sh -c "while true;do curl 127.0.0.1:8000 && sleep 1;done"
结果如图:
5. 扩容升级:
docker service scale flask-demo=3
docker service update --image dylan/flask-update-demo:v2.0 flask-demo
结果如图:
可以发现升级过程中两个版本并排运行:
升级完成后版本统一!
6. 版本回滚:
docker service rollback flask-demo
结果如图:
再次回到两个版本并排运行:
最终回滚完成!
以上就是 docker swarm 需要了解的内容,也是对于 docker 自带的容器编排需要了解的内容。不需要刻意去记,了解这些特征即可。
毕竟,学习这些的目的其实还是为了学习 Kubernetes 做准备。