1、Docker Swarm简介
说到集群,第一个想到的就是k8s,但docker官方也提供了集群和编排解决方案,它允许你将多个 Docker 主机连接在一起,形成一个“群集”(Swarm),并可以在这个 Swarm 上运行和管理你的服务。
与Kubernetes相比,Docker Swarm的群集管理功能相对简单,Swarm更适合于小型到中型的容器部署,并且通常用于简单的应用程序部署和管理。
如果经常用docker-compose 的人员来说,可以这样容易理解。
- docker-compose:可以在一台机器上使用docker-compose.yml轻松部署多个服务(如nginx,php,mysql)
- docker swarm:将一个服务部署至多台机器(如nginx,部署到机器1,机器2,机器3)
2、使用Docker Swarm部署应用
这里用swarm部署一个简单的应用nginx,测试并熟悉swarm。
2.1、准备工作
两台机器,系统ubuntu。
192.168.203.129,192.168.203.130,1台作为manage主服务器,1台作为worker节点。
注:生产环境建议是 3个manager 以上,如果只有2台
manager,当主manager挂掉之后,另一台从manager是不会升级为主manager的
,因为从manager升级为主manager的条件是存活的从manager节点个数必须大于1。
安装docker最新版本默认安装有docker swarm。
防火墙,如果是云服务器,请开放端口2377,允许与工作节点服务器通讯。
一般而言,如果是在多台物理机上搭建swarm集群,那么port就是2377,如果是在docker虚拟机上搭建的,那么port就是2376。
2.2、初始化swarm集群,创建主管理节点
我这里测试129为manager服务器,直接用命令初始化。这将在当前主机上创建一个 Swarm,并将其设置为 Swarm 的管理节点。在此过程中,Docker 会生成一个用于其他节点加入的 token,务必妥善保管这个 token。
sudo docker swarm init --advertise-addr 192.168.203.129
运行结果:
ubuntu@ubuntu:~$ sudo docker swarm init --advertise-addr 192.168.203.129
Swarm initialized: current node (xcpn4el8vvs2hymojpbay8m6q) is now a manager.To add a worker to this swarm, run the following command:docker swarm join --token SWMTKN-1-08hc7u7ed38xnli6ikqzq8flfrr7kzn0bi7d2qiekdsxnstqlm-ed7h0bzk2dno6dmn8luzssj84 192.168.203.129:2377To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
输出文字的意思是此地址已经加入到了这个swarm,你可以使用 docker swarm join --token xxxxx 命令将其它节点加入到这个swarm中来成为工作节点。
查看节点信息:sudo docker node ls
,管理节点已经起来了。
ubuntu@ubuntu:~$ sudo docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
xcpn4el8vvs2hymojpbay8m6q * ubuntu Ready Active Leader 26.0.0
2.3、添加工作节点
在工作节点服务器,执行上面提示的token即可加入。
sudo docker swarm join --token SWMTKN-1-08hc7u7ed38xnli6ikqzq8flfrr7kzn0bi7d2qiekdsxnstqlm-ed7h0bzk2dno6dmn8luzssj84 192.168.203.129:2377
提示This node joined a swarm as a worker,没有报错说明已经加入管理节点。
住管理节点服务器,再次运行sudo docker node ls
,查看节点,已经成功添加。
ubuntu@ubuntu:~$ sudo docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
iha4vzuoyihcblayk08v7mya4 ubuntu Ready Active 26.0.0
xcpn4el8vvs2hymojpbay8m6q * ubuntu Ready Active Leader 26.0.0
这里swarm集群就已经搭建完了,是不是很简单。
节点类型转换,如果想将worker节点转换为manager节点,可以运行如下命令。
sudo docker node promote worker-nodename
worker-nodename为自己节点的名称,我这里也可以用ID操作,显示如下,切换成功,状态为Reachable。如果另外一台管理节点挂掉,则新加入的manager节点状态由reachable变为leader, 之前的manager节点状态为unreachable.
ubuntu@ubuntu:~$ sudo docker node promote iha4vzuoyihcblayk08v7mya4
Node iha4vzuoyihcblayk08v7mya4 promoted to a manager in the swarm.
ubuntu@ubuntu:~$ sudo docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
iha4vzuoyihcblayk08v7mya4 ubuntu Ready Active Reachable 26.0.0
xcpn4el8vvs2hymojpbay8m6q * ubuntu Ready Active Leader 26.0.0
如果想要节点降级,可以用以下命令:
docker node demote worker-nodename
如果工作节点脱离swarm集群,切换到工作节点服务器,执行命令,
sudo dokcer swarm leave
如果管理器节点脱离swarm集群,增加参数–force即可
sudo docker swarm leave --force
2.4、用swarm部署服务(nginx为例)
集群搭建完成,现在用集群部署nginx服务,以下全部在管理节点操作。
创建网络
在 managmer 上创建一个 overlay 为驱动的网络(默认使用的网络连接为ingress),查看集群环境下的网络列表:docker network ls
sudo docker network create -d overlay nginx_net
部署服务
部署nginx服务命令
sudo docker service create
//指定了使用网络,如上面创建的nginx_net网络
--network nginx_net \//创建的容器名
--name my-nginx \
//端口映射
--p 8080:80 \
//创建副本的数量,这里两台机器,就两个副本即可
--replicas 2 \
//镜像
nginx
在管理节点执行
sudo docker service create --network nginx_net --name my-nginx -p 8080:80 --replicas 2 nginx
运行完后,可以用以下命令查看相关信息。
//查看服务列表命令
sudo docker service ls
//服务运行节点命令
sudo docker service ps
//查看my-nginx服务的详细信息:
docker service inspect my-nginx
运行结果如下,nginx已经在两台机器成功运行。
ubuntu@ubuntu:~$ sudo docker service create --network nginx_net --name my-nginx -p 8080:80 --replicas 2 nginx
s07fiokkcgka28tfmwxozouj3
overall progress: 2 out of 2 tasks
1/2: running [==================================================>]
2/2: running [==================================================>]
verify: Service s07fiokkcgka28tfmwxozouj3 converged
ubuntu@ubuntu:~$ sudo docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
s07fiokkcgka my-nginx replicated 2/2 nginx:latest *:8080->80/tcp
ubuntu@ubuntu:~$ sudo docker service ps my-nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
l8aiihhyy6sb my-nginx.1 nginx:latest ubuntu Running Running about a minute ago
rx77s1hpyg62 my-nginx.2 nginx:latest ubuntu Running Running about a minute ago
ubuntu@ubuntu:~$
浏览器测试,分别输入两台机器IP访问,可以看到已经搭建成功。
扩容和缩容
如上,现在只有两台机器,所以只创建了两个副本,如果增加机器或者减少机器,就需要扩容和缩容。
扩容:将my-nginx服务副本数量扩容至6个,命令如下:
sudo docker service update --replicas 6 my-nginx
或者
sudo docker service scale my-nginx=6
扩容完成后,会平均分配副本数量到其他服务器中。
缩容:将副本数从6个缩容至3个,也是使用 docker service update --replicas 或 docker service scale 命令:
sudo docker service update --replicas 3 my-nginx
或者
sudo docker service scale my-nginx=3
移除my-nginx服务:
sudo docker service rm my-nginx
3、Docker Stack简介
Docker Stack(堆栈) 是在 Swarm 上管理服务堆栈的工具。而在上面文章 中介绍的 Docker Swarm 只能实现对单个服务的简单部署,于是就引出了Docker Stack。
上面我们介绍到
- docker-compose:可以在一台机器上使用docker-compose.yml轻松部署多个服务(如nginx,php,mysql)
- docker swarm:将一个服务部署至多台机器(如nginx,部署到机器1,机器2,机器3)
那Docker Stack(堆栈) 是将docker-compose和docker swarm结合起来,在多台服务器集群,部署多个服务。Docker Stack 使用与 Docker Compose 相同的 YAML 文件格式来定义服务堆栈。
4、Docker Stack部署应用
同样以部署nginx为例子,用YAML文件格式编排来部署应用。
4.1、编写YAML文件
创建文件夹,在此文件夹进行工作
mkdir stack-web
cd stack-web
编辑docker-compose.yml
vim docker-compose.yml
内容如下:
version: '3.6'
services:nginx:image: nginx:latestenvironment:- TZ=Asia/Shanghaideploy:replicas: 2restart_policy:condition: on-failureupdate_config: parallelism: 2delay: 10smonitor: 30smax_failure_ratio: 0.1order: start-firstports:- 80:80- 443:443networks:- nginx_netnetworks:nginx_net:external: true
在 Swarm 中,你可以使用相同的 Compose 文件来部署这个应用。但有些参数是 Swarm 特有的配置,比如副本数量和部署模式,如deploy标签下是针对堆栈我们在原有 Compose 文件里增加的内容。
上面关于deploy的参数说明:
- restart_policy
配置容器的重新启动,代替 restart
condition:值可以为 none 、on-failure 以及 any(默认)
delay:尝试重启的等待时间,默认为 0
max_attempts:在放弃之前尝试重新启动容器次数(默认:从不放弃)。如果重新启动在配置中没有成功 window,则此尝试不计入配置 max_attempts 值。例如,如果 max_attempts 值为 2,并且第一次尝试重新启动失败,则可能会尝试重新启动两次以上。windows:在决定重新启动是否成功之前的等时间,指定为持续时间(默认值:立即决定)。
- update_config
配置更新服务,用于无缝更新应用(rolling update)
parallelism:一次性更新的容器数量
delay:更新一组容器之间的等待时间。
failure_action:如果更新失败,可以执行的的是 continue、rollback 或 pause (默认)
monitor:每次任务更新后监视失败的时间(ns|us|ms|s|m|h)(默认为 0)
max_failure_ratio:在更新期间能接受的失败率
order:更新次序设置,top-first(旧的任务在开始新任务之前停止)、start-first(新的任务首先启动,并且正在运行的任务短暂重叠)(默认 stop-first)
4.2、部署堆栈
接下来用以下命令运行部署堆栈
sudo docker stack deploy -c docker-compose.yml nginx-stack
这个命令会创建一个名为 nginx-stack 的堆栈,并根据 Compose 文件中的定义创建服务。
参数说明:
–bundle-file:【实验阶段】分布式应用程序包文件的路径
-c --compose-file :Stack File 路径
–prune:删除不再被引用的服务
–resolve-image: 查询 Registry 以解决镜像摘要和支持的平台可选值:always(默认)、changed、never
–with-registry-auth:向 Swarm 代理发送 Registry 认证详细信息
部署完成后可以用docker stack ls 和 docker stack ps 查看服务节点。
也可以用上面的swarm命令查看服务,docker service ls 和docker service ps。
运行结果如下显示,部署完成。
ubuntu@ubuntu:~/stack-web$ sudo docker stack deploy -c docker-compose.yml nginx-stack
Since --detach=false was not specified, tasks will be created in the background.
In a future release, --detach=false will become the default.
Creating service nginx-stack_nginxubuntu@ubuntu:~/stack-web$ sudo docker stack ls
NAME SERVICES
nginx-stack 1ubuntu@ubuntu:~/stack-web$ sudo docker stack ps nginx-stack
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
wexhzl04qrr0 nginx-stack_nginx.1 nginx:latest ubuntu Running Running 7 minutes ago
wxt7ovydh38t nginx-stack_nginx.2 nginx:latest ubuntu Running Running 7 minutes ago ubuntu@ubuntu:~/stack-web$ sudo docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
qme9n3kq0zxu nginx-stack_nginx replicated 2/2 nginx:latest *:80->80/tcp, *:443->443/tcpubuntu@ubuntu:~/stack-web$ sudo docker service ps nginx-stack_nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
wexhzl04qrr0 nginx-stack_nginx.1 nginx:latest ubuntu Running Running 31 seconds ago
wxt7ovydh38t nginx-stack_nginx.2 nginx:latest ubuntu Running Running 31 seconds ago
浏览器输入IP访问测试,部署完成。
常用命令:
docker stack deploy 部署新的堆栈或更新现有堆栈
docker stack ls 列出现有堆栈
docker stack ps 列出堆栈中的任务
docker stack rm 删除一个或多个堆栈
docker stack services 列出堆栈中的服务
docker stack和docker service 命令有点类似,实际上,Docker Stack是建立在Docker Service之上的一种更高级的抽象。
使用Docker Service时,可以单独管理每个服务,并对其进行伸缩、更新和删除。而使用Docker Stack时,可以将一组相关的服务捆绑在一起,并通过编排文件定义它们之间的关系和依赖性,方便一次性部署和管理整个应用程序。根据您的需求选择合适的工具,单个服务使用Docker Service,复杂应用程序使用Docker Stack。
5、Docker Stack部署多服务应用
上面我们部署了单服务nginx应用,有点简单,为了实现stack更大的左右,我们可以同时部署多服务应用。
示例,同时部署wordpress和mysql服务
编辑YAML文件
vim docker-compose.yml
内容如下
version: '3.8'services:wordpress:image: wordpress:latestports:- "80:80"environment:WORDPRESS_DB_HOST: dbWORDPRESS_DB_NAME: wordpressWORDPRESS_DB_USER: wordpressWORDPRESS_DB_PASSWORD: qwe12345networks:- web-networkdeploy:replicas: 2restart_policy:condition: on-failuredelay: 5smax_attempts: 3update_config:parallelism: 1delay: 10sdb:image: mysql:latestenvironment:MYSQL_ROOT_PASSWORD: exampleMYSQL_DATABASE: wordpressMYSQL_USER: wordpressMYSQL_PASSWORD: qwe12345volumes:- ./mysql-data:/var/lib/mysql#设置网络networks:- web-networkdeploy:#当前容器的扩展类型 replicated可扩展,global不可扩展mode: globalplacement:constraints:# 指定容器部署节点manager- node.role == managernetworks:web-network:driver: overlay
以上mysql的deploy有所不同,因为这里考虑mysql只需要一个就行,不需要多个服务器,所以部署在管理节点即可,根据使用情况调整。
由于上面mysql挂载了文件夹存储数据,所以在当前创建文件夹,否则会因找不到文件夹mysql启动失败。
mkdir mysql-data
启动部署编排
sudo docker stack deploy -c docker-compose.yml wordpress-stack
用docker stack ls 和docker stack ps wordpress-stack查看启动服务信息
ubuntu@ubuntu:~/stack-web$ sudo docker stack ls
NAME SERVICES
wordpress-stack 2ubuntu@ubuntu:~/stack-web$ sudo docker stack ps wordpress-stack
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
9e8ustjfy021 wordpress-stack_db.xcpn4el8vvs2hymojpbay8m6q mysql:latest ubuntu Running Running 7 seconds ago
pzxcwpxoupmw wordpress-stack_wordpress.1 wordpress:latest ubuntu Running Running 12 seconds ago
jjdn4s2a53e8 wordpress-stack_wordpress.2 wordpress:latest ubuntu Running Running 12 seconds ago
也可以用swarm的命令 service,查看每个服务对于的node节点信息,如下显示。
wordpress已经分配2个副本,db按要求只有一个节点。
ubuntu@ubuntu:~/stack-web$ sudo docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
ubgozw57txda wordpress-stack_db global 1/1 mysql:latest
060g92r8f8ys wordpress-stack_wordpress replicated 2/2 wordpress:latest *:80->80/tcp
ubuntu@ubuntu:~/stack-web$ sudo docker service ps 060g92r8f8ys
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
pzxcwpxoupmw wordpress-stack_wordpress.1 wordpress:latest ubuntu Running Running 8 minutes ago
jjdn4s2a53e8 wordpress-stack_wordpress.2 wordpress:latest ubuntu Running Running 8 minutes ago ubuntu@ubuntu:~/stack-web$ sudo docker service ps ubgozw57txda
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
9e8ustjfy021 wordpress-stack_db.xcpn4el8vvs2hymojpbay8m6q mysql:latest ubuntu Running Running 8 minutes ago
浏览器IP访问测试,两个IP都可以正常访问。
这里集群多服务部署就完成了。
6、总结
Docker Swarm 和 Stack,这两者都是 Docker 生态系统中的重要组成部分。Docker Swarm 是 Docker 的原生集群技术,允许你在多个 Docker 主机上部署和管理服务。而 Docker Stack 则是一个管理在 Swarm 集群上运行的服务栈的工具。
虽然 Swarm 和 Stack 可能无法满足所有的用例,例如需要更复杂的调度、网络和安全功能的大规模集群,但对于许多用例,特别是中小规模的项目,Swarm 和 Stack 提供了一种简单、直观的解决方案。
-
Docker Swarm:
容器编排工具:Docker Swarm 是 Docker 官方提供的容器编排工具,用于在多个 Docker 主机上管理和编排容器化应用。集群管理:通过 Docker Swarm,用户可以将多个 Docker 主机组成一个集群,并统一管理这些主机上运行的容器。
服务定义:用户可以使用 Docker Swarm 定义服务,将容器组织成一个逻辑单元,包括容器的镜像、端口映射、副本数量等。
自动负载均衡:Docker Swarm 自动在集群中的节点之间分配容器,并提供负载均衡功能,确保应用程序的高可用性和性能。
扩展性:Docker Swarm 具有良好的扩展性,可以根据需求动态扩展集群的规模,并且可以轻松地与其他 Docker 生态系统集成。
-
Docker Stack:
应用定义:Docker Stack 是用于定义、部署和管理应用程序的工具。它使用 YAML 文件(通常命名为 docker-compose.yml)来描述应用程序的服务、网络和卷等配置。Swarm 集群部署:Docker Stack 是基于 Docker Swarm 构建的,用户可以使用 Docker Stack 将定义好的应用程序部署到 Swarm 集群中。
服务定义:与 Docker Compose 相似,Docker Stack 允许用户使用 YAML 文件定义多个服务,并指定它们之间的依赖关系、网络连接等。
自动伸缩:通过 Docker Stack,用户可以轻松地扩展应用程序的规模,根据需要增加或减少服务的副本数量。
更新管理:Docker Stack 提供了方便的更新管理功能,用户可以定义更新策略,实现无缝地更新应用程序版本。
总的来说,Docker Swarm 是一个用于集群管理和容器编排的工具,而 Docker Stack 则是在 Swarm 集群中定义、部署和管理应用程序的工具。它们共同构成了 Docker 生态系统中的一部分,为用户提供了强大而灵活的容器化解决方案。