- 初始化集群
- 服务部署
- 副本控制
- 负载均衡
- 滚动更新和归滚
- 节点管理
- 网络管理
- 存储管理
- 服务发现
- Ingress
- 其他命令
- Docker Swarm是 Docker 官方推出的容器编排工具,旨在解决 Docker Compose 单机使用的局限性,满足大规模分布式环境中高效、可靠、管理容器化应用的需求。
- 标准化和生态整合:Docker Swarm和Docker紧密集成,提供Docker CLI一致的使用,用户可用使用熟悉的Docker命令管理Swarm集群,降低了学习成本。
- 资源优化和负载均衡:Docker Swarm自动调度容器,根据定义的服务和策略优化资源利用,提供内置负载均衡,实现水平扩展和性能均衡。
- 集群化和高可用性:Docker Swarm可以实现容器在多台主机上建立集群部署,提高应用容错性和高可用性,内置恢复机制可以确保服务始终可用。
- 容器化管理需求:Docker Swarm提供自动化、集中化的管理,简化容器部署、扩容、缩容、更新、健康检查等操作,解决了手动管理的复杂性。
演示代码存于gitee.com/ft/docker-s... ,包含app代码,构建各版本镜像Dockerfile、compose-nginx.yaml(包含nginx proxy_pass配置文件)、compose.yaml等,可以克隆本地进行练习使用。
今天更新有点晚,由于内容有点多,花费时间有些久。各位见谅。
Docker Swarm与Docker Compose使用相同的docker-compose.yaml
配置,在其上增加的Docker Swarm的独有功能。Docker Swarm不支持build属性,可以将构建好的镜像push到Docker Hub或私有仓库。如果仅在管理节点构建好镜像,未推送到所有节点可访问的公共仓库,当调度到工作节点时,无法拉取到镜像,服务将无法启动成功。
以下使用 1 个主节点(192.168.31.23)和 1 个工作节点(192.168.31.21),演示如何创建集群、加入集群、启动 Docker Swarm 服务、实现负载均衡以及通过标签实现亲和性。
使用Docker Swarm,可以进行如下操作:
1. 初始化集群
使用 Docker Swarm 初始化一个集群,包括设置管理节点(Manager)和工作节点(Worker)。通过运行 docker swarm init
命令创建一个 Swarm 集群:
csharp
➜ ~ docker swarm init
Swarm initialized: current node (hq2zqriske8co4x2b5g2hncvx) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-6cg4dd01sppqhw2deo5h9inxzxho9gzvuarnh7euje2kpts1id-61dilhm0249oihe0wnu2g6xr0 192.168.31.23:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
运行此命令后,会生成一个令牌,使用这个令牌将其他服务器添加到 Swarm 集群中作为工作节点。直接在工作节点运行 docker swarm join --token ...
命令:
csharp
➜ ~ docker swarm join --token SWMTKN-1-6cg4dd01sppqhw2deo5h9inxzxho9gzvuarnh7euje2kpts1id-61dilhm0249oihe0wnu2g6xr0 192.168.31.23:2377
This node joined a swarm as a worker.
此时,消息提示节点已作为工作节点加入 Swarm 集群。通过 docker node ls
命令查看集群中的节点:
bash
➜ ~ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
mquy418xgmsgh5jbrehyhbh0z debian01 Ready Active 26.0.0
hq2zqriske8co4x2b5g2hncvx * debian03 Ready Active Leader 26.0.1
2. 服务部署
定义并部署服务,每个服务可以包含多个容器实例。为部署一个服务,使用 Docker Compose 文件,如以下示例所示的 compose.yaml
文件:
yaml
version: '3'
services:
web:
image: nginx:1.25
ports:
- "80:80"
使用 docker stack deploy
命令部署 Compose 文件中定义的服务:
arduino
docker stack deploy -c compose.yaml hello
这将在集群中部署一个名为 "web" 的服务,使用 Nginx 镜像,并将主机的 80 端口映射到容器的 80 端口。使用 curl localhost:80
进行测试。
3. 副本控制
为服务设定所需的副本数(Replicas),Swarm 将自动确保指定数量的容器实例始终保持运行。使用以下命令设置服务的副本数:
ini
docker service scale hello=2
输出如下:
ini
➜ ~ docker service scale hello_web=2
hello_web scaled to 2
overall progress: 2 out of 2 tasks
1/2: running [==================================================>]
2/2: running [==================================================>]
verify: Service hello_web converged
将 "hello_web" 服务的副本数设置为 2,Swarm 将自动启动或停止容器实例以满足指定的副本数。等待一段时间,让 Swarm 自动调节到设置的副本数。通过 curl 192.168.31.21
和 curl 192.168.31.23
访问节点 IP 地址,发现都可以看到 Nginx 默认页面,表明 Docker Swarm 已按要求的副本数成功部署。
4. 负载均衡
Swarm 内置了负载均衡机制,可以自动为服务分配虚拟 IP(VIP)或使用 DNS 轮询(DNS Round-Robin)方式,将外部客户端的请求分发到服务的不同实例。通过 docker service create
命令创建一个具有负载均衡的服务。当 endpoint_mode
设置为 vip
时,Docker Swarm 会为服务分配一个虚拟 IP(VIP)地址。客户端通过这个 VIP 地址访问服务,Swarm 内部则使用 IPVS 或 iptables 等技术将请求透明地分发到服务的各个容器实例上。
修改之前的 compose.yaml
文件,使用 dockerswarmdemo-app:latest
替换 Nginx,该镜像是使用 Go 编写的 demo,用于获取服务器 IP:
yaml
version: '3.8'
services:
app:
image: dockerswarmdemo-app:latest
ports:
- 3003:3003
deploy:
mode: replicated
replicas: 2
endpoint_mode: vip
使用 docker stack deploy -c compose.yaml hellogo
命令部署,稍等片刻,Docker Swarm 将根据 compose.yaml
的设定启动 2 个副本。查看容器列表:
bash
➜ DockerSwarmDemo git:(main) docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
64447d6d52af dockerswarmdemo-app:latest "/bin/sh -c ./app" 10 minutes ago Up 10 minutes 3003/tcp hellogo3_app.1.i2gyvwhveas9awuwgk7y96h0a
36f947e42095 dockerswarmdemo-app:latest "/bin/sh -c ./app" 12 minutes ago Up 12 minutes 3003/tcp hellogo3_app.2.qnfunvio51beb2lh0cvb93pht
使用 docker service inspect
获取 Docker Swarm 为 hellogo_app
分配的 VIP IP:
yaml
➜ DockerSwarmDemo git:(main) docker service inspect --format '{{range $p := .Endpoint.VirtualIPs}}{{println $p.Addr}}{{end}}' hellogo_app
10.0.0.46/24
10.0.4.2/24
进入其中一个容器的 shell:
bash
➜ DockerSwarmDemo git:(main) docker exec -it hellogo3_app.1.i2gyvwhveas9awuwgk7y96h0a sh
/app # apk add curl
/app # curl 10.0.4.2:3003
{"server_ip":"10.0.4.15"}/app #
/app # curl 10.0.4.2:3003
{"server_ip":"10.0.4.4"}/app #
/app # curl 10.0.4.2:3003
{"server_ip":"10.0.4.15"}/app #
/app # curl 10.0.4.2:3003
{"server_ip":"10.0.4.4"}/app #
/app # curl 10.0.4.2:3003
{"server_ip":"10.0.4.15"}/app
结果显示,每次访问的服务器 IP 在 10.0.4.15 和 10.0.4.4 之间轮询。
5. 滚动更新和回滚
轻松进行服务版本升级,支持滚动更新策略(如分批更新、延迟时间等),并在出现问题时快速回滚到先前版本。
➜ ~ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dockerswarmdemo-app v2 640c0a108907 6 minutes ago 18.1MB
dockerswarmdemo-app v1 483a682ee82a 7 minutes ago 18.1MB
滚动更新
使用docker service update命令来更新服务
sql
docker service update --image <新镜像> <服务名称>
将出发滚动更新,并将服务的容器副本逐步更新为指定镜像,在不停止服务的情况下进行更新。
sql
➜ DockerSwarmDemo git:(main) docker service update --image dockerswarmdemo-app:v2 hellogo_app
image dockerswarmdemo-app:v2 could not be accessed on a registry to record
its digest. Each node will access dockerswarmdemo-app:v2 independently,
possibly leading to different nodes running different
versions of the image.
hellogo_app
overall progress: 1 out of 2 tasks
1/2: running [==================================================>]
2/2: preparing [=================================> ]
回滚
为 dockerswarmdemo-app
镜像构建两个版本。首先使用 docker stack deploy -c compose.yaml hellogo
启动 v1 版本的服务。接着更新 compose.yaml
中的镜像版本为 v2,并再次运行 docker stack deploy -c compose.yaml hellogo
更新现有服务版本为 v2。
当前运行的服务版本
v1
v2 * 当前运行中的版本
使用命令docker service rollback hellogo_app
将回滚到前一个版本`,即为v1版本。
sql
➜ DockerSwarmDemo git:(main) docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
1fwuf3nfi8ef hellogo_app replicated 1/2 dockerswarmdemo-app:v2 *:3003->3003/tcp
➜ DockerSwarmDemo git:(main) docker service rollback hellogo_app
hellogo_app
rollback: manually requested rollback
overall progress: rolling back update: 0 out of 2 tasks 1/2:
2/2: preparing [=================================> ]
service rollback paused: update paused due to failure or early termination of task wv0y6sptgahkwuiewx4v5oues
➜ DockerSwarmDemo git:(main) docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
1fwuf3nfi8ef hellogo_app replicated 2/2 dockerswarmdemo-app:v1 *:3003->3003/tcp
当前运行的服务版本
v1 * 当前运行中的版本
v2
6. 节点管理
添加或移除节点、查看节点状态、设置节点约束与亲和性规则,以控制服务在特定节点上的分布。
csharp
docker swarm join // 加入节点
docker node rm <node-name|node-id> // 移除节点
docker node ls // 查看节点状态
docker node update --label-add [key=value] <node-name|node-id> // 设置节点标签,用于运行指定部署时,为服务指定节点标签,指定服务我们指定节点运行
deploy:
mode: replicated
replicas: 1
endpoint_mode: vip
placement:
constraints: # 添加条件约束
- node.labels.role==web
7. 网络管理
创建和管理覆盖网络(Overlay Networks),实现跨节点的容器间通信,以及为服务提供统一的网络命名空间。
可以通过命令overlay
查看,使用Docker Swarm启动的服务使用的驱动为overlay类型。
sql
➜ ~ docker network ls
NETWORK ID NAME DRIVER SCOPE
js0c41lnvw7e hellogo_default overlay swarm
8. 存储管理
配置持久化存储卷(Volumes),确保服务数据在容器迁移或重启时得以保留。在集群中最好使用网络存储,NFS(Network File System)、ceph及者云厂商提供的相关存储类产品。
9. 服务发现
内置的服务发现机制允许服务间通过服务名进行互相访问,无需关心具体的 IP 地址和端口变化。
例如 :使用Nginx反向代理hellogo_app
服务。
我们不需要知道hellogo_app
服务的IP,在没启动服务前,我们也不知道,在Nginx中添加配置即可代理到后端,hellogo_app
运行了2个副本。Nginx即默认为我们实现了负载均衡。
arduino
location / {
proxy_pass http://hellogo_app:3003/;
}
hellogo_app
会替换为实际hellogo_app
服务的IP地址。
10. Ingress
Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管。
只启动hellogo_app
,创建副本数2
lua
docker service create \
--name hellogo_app \
--replicas 2 \
--publish mode=ingress,target=3003 \
dockerswarmdemo-app:latest
使用docker service create
命令,创建服务名hellogo_app
,副本数2个,用 Ingress 模式将服务内部的端口 3003
发布到外部。外部访问端口由 Swarm 自动分配,并通过 Ingress 网络进行负载均衡。使用镜像dockerswarmdemo-app:latest
css
docker service inspect --format '{{ .Endpoint.Ports }}' hellogo_app
[{ tcp 3003 30000 ingress}]
可以看到我们容器内部的端口为3003,外部访问的端口为30000。
csharp
➜ ~ curl http://192.168.31.21:30000/
{"server_ip":"10.0.0.21"}#
➜ ~ curl http://192.168.31.21:30000/
{"server_ip":"10.0.0.20"}#
➜ ~ curl http://192.168.31.21:30000/
{"server_ip":"10.0.0.21"}#
➜ ~ curl http://192.168.31.21:30000/
{"server_ip":"10.0.0.20"}#
使用任何节点IP+PORT都可以访问,提供curl访问可以看出,每次IP会在2个副本之间进行轮询访问。
11. 其他命令
docker swarm leave
工作节点执行,将离开Docker Swarm集群。
docker swarm leave --force
只有 一个管理节点执行,将失去Docker Swarm集群管理能力。Docker Swarm相关都会停止、断开。
docker service ls
查看Docker Swarm集群中服务,包含ID、名称、模式、副本数、镜像名称、端口映射。
docker service rm <Service ID|Service Name>
删除指定服务。
docker service logs <Service ID|Service Name>
输出指定服务日志。
docker service inspect <Service ID|Service Name>
显示服务详细信息,可使用-f筛选指定内容。
docker service scale <Service Name>=副本数量
缩容或扩容一个服务。
docker create
根据命令参数创建一个服务,可以使用docker service create --help
了解。
docker update
根据命令参数更新一个服务,可以使用docker service update --help
了解。
docker service rollback
命令用于将服务回滚到之前的一个版本。
docker swarm join-token <worker|manager>
命令获取的相应类型(Worker或Manager)的令牌。
Docker Swarm 是 Docker 官方推出的容器编排解决方案,旨在应对大规模分布式环境下的容器管理挑战,通过提供标准化的接口、强大的资源调度、高可用集群架构以及便捷的容器生命周期管理,极大地简化了容器化应用的部署、扩展和维护过程。
读完后,忍不住要加个关注!不是我吹,但你会后悔没关注的!