前言
在学 docker-swarm 时,我们必定会接触到docker-stack 命令
它的具体作用和和docker-compose相似,只不过docker-compose只能单机编排。而 docker stack 可以利用 docker-swarm 的优势实现多机编排。
举个最简单的例子:我可以利用docker-compose 命令迅速实现单机下多容器的部署。但是如果遇到应用程序在A服务器,而数据库在B服务器,那么该命令就有点力不从心了。
此外每当我看到网上有很多文章介绍docker-swarm时,都会引入dokcer-machine,让你开启虚拟化。但是对于云服务器用户来说,其实单机模式下也是可以使用docker swarm。只不过他会在 leader 节点中部署所有的应用容器罢了。所以你在使用docker swarm 时不需要有太多的心智负担。
使用方式
docker stack 命令也是需要我们编写 docker-compose 文件。
但执行该命令前,你需要先执行以下命令,来初始化你的 swarm 的 leader 节点
1 2 3 |
docker swarm init 或 docker swarm init --advertise-addr=192.168.0.8 ## 这里请带上你 leader 节点的IP |
此时它将生成一串如下图所示
1 |
docker swarm join --token SWMTKN-1-1oqmdyd72qw7itpq0ewzjnmsa08o4trglzupc0hkph9n0m2na0-5wffubtmrg4ofqj1pew8qkwgo 192.168.0.8:2377 |

这是worker节点加入的命令,你只需要将其复制到 worker 节点中执行就好。当在worker节点中执行了该命令,那么这就代表着该节点成功加入了 swarm 集群。(当然,如果你用的单机云服务器ECS就不存在worker节点了,但实现还是可以继续下去。)
此时编写docker-compose.yml 文件如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
version: '3' services: go-server: image: "registry.cn-hangzhou.aliyuncs.com/xhyonline/my_centos:go-server" deploy: replicas: 2 restart_policy: condition: on-failure ports: - "80:80" networks: - "my-network" depends_on: - mysql mysql: image: "registry.cn-hangzhou.aliyuncs.com/xhyonline/repo:mysql-8.0.22-ubuntu" ports: - "3306:3306" deploy: restart_policy: condition: on-failure volumes: - "/mysql:/var/lib/mysql" networks: - "my-network" networks: my-network: |
启动命令:
1 |
docker stack deploy -c ./docker-compose.yml my-stack |
当你执行了这条命令后,它会自动分配容器在哪些 worker 节点中运行。
docker 的神奇之处在于它的负载均衡模式,假设如果你有三台机器:192.168.0.8、192.168.0.9、192.168.0.10。如果 go-server 部署在了前两台,而尾号为10的这台机器没有该服务,你会发现当你访问10这台机器的80端口时,它也能带你访问到正确的内容。这涉及到了docker的虚拟IP,也就是LVS层,有兴趣的朋友可以自行了解一下。
突发奇想(多机编排时的MySQL副本问题)
既然服务可以使用 replicas 关键字来定义副本,且docker-swarm自带负载均衡模式,那么假设我的 mysql 有多个副本,那么应用程序写入 mysql 时会发生什么呢?是数据同步形式还是数据分片形式呢?
因此我做了如下的事儿......
1 2 3 4 5 6 7 8 9 10 11 12 |
mysql: image: "registry.cn-hangzhou.aliyuncs.com/xhyonline/repo:mysql-8.0.22-ubuntu" ports: - "3306:3306" deploy: replicas: 2 restart_policy: condition: on-failure volumes: - "/mysql:/var/lib/mysql" networks: - "my-network" |
我将mysql的副本修改为2。
启动后如下图所示

当我访问80端口应用程序时,应用程序往mysql中写数据我发现它也是负载均衡的。也就是数据分片形式......部分数据被写入到了第一个mysql节点中,有部分数据被写入到了第二个节点中......
怪不得大家一般编写这种文件时,都会选择用一个mysql节点,以免数据混乱。
最后提交上我较为常用的几条命令
1 2 3 4 5 6 7 8 9 10 11 12 |
// 初始化一个 swarm 集群 docker swarm init // 部署 docker swarm 模式下的多个容器 docker stack deploy -c ./docker-compose.yml [自定义stack名字] // 查看 stack 的容器运行情况 docker stack ps [自定义stack名字] // 查看 stack docker stack ls // 删除 stack docker stack rm [自定义stack名字] // 查看该 stack 下的 service 情况,该命令与 docker stack ps 相似,只不过 docker stack ps 还能看到容器运行在哪几个节点下 docker stack services [自定义stack名字] |
文章评论(0)