上一章使用了Docker Compose编排单机多容器的Docker。但是当规模越来越大时,容器规模也会逐渐增大。所以,这章来使用Docker官方为了解决多容器管理的问题推出的Docker Swarm
Docker Swarm与K8s的比较与选择
Docker Swarm架构
Swarm 的架构整体分为管理节点(Manager Nodes)和工作节点(Worker Nodes),整体架构如下图:
管理节点: 管理节点负责接受用户的请求,用户的请求中包含用户定义的容器运行状态描述,然后 Swarm 负责调度和管理容器,并且努力达到用户所期望的状态。
工作节点: 工作节点运行执行器(Executor)负责执行具体的容器管理任务(Task),例如容器的启动、停止、删除等操作。
管理节点和工作节点的角色并不是一成不变的,你可以手动将工作节点转换为管理节点,也可以将管理节点转换为工作节点。
Docker Swarm核心概念
名称 | 描述 |
Swarm 集群 | Swarm 集群是一组被 Swarm 统一管理和调度的节点,被 Swarm纳管的节点可以是物理机或者虚拟机,其中一部分节点作为管理节点,负责集群状态的管理和协调,另一部分作为工作节点,负责执行具体的任务来管理容器,实现用户服务的启停等功能 |
节点 | Swarm 集群中的每一台物理机或者虚拟机称为节点, 节点按照工作职责分为管理节点和工作节点,管理节点由于需要使用 Raft 协议来协商节点状态,生产环境中通常建议将管理节点的数量设置为奇数个,一般为 3 个、5 个或 7 个。 |
服务 | 服务是为了支持容器编排所提出的概念,它是一系列复杂容器环境互相协作的统称, 一个服务的声明通常包含容器的启动方式、启动的副本数、环境变量、存储、配置、网络等一系列配置,用户通过声明一个服务,将它交给 Swarm,Swarm 负责将用户声明的服务实现 |
任务 | 任务是集群中的最小调度单位,它包含一个真正运行中的 Docker 容器, 当管理节点根据服务中声明的副本数将任务调度到节点时,任务则开始在该节点启动和运行,当节点出现异常时,任务会运行失败。此时调度器会把失败的任务重新调度到其他正常的节点上正常运行,以确保运行中的容器副本数满足用户所期望的副本数 |
服务外部访问 | 由于容器的 IP 只能在集群内部访问到,而且容器又是用后马上销毁,这样容器的 IP 也会动态变化,因此容器集群内部的服务想要被集群外部的用户访问到,服务必须要映射到主机上的固定端口。Swarm 使用入口负载均衡(ingress load balancing)的模式将服务暴露在主机上,该模式下,每一个服务会被分配一个公开端口(PublishedPort),你可以指定使用某个未被占用的公开端口,也可以让 Swarm 自动分配一个。 |
搭建Swarm集群
环境要求
- Docker 版本大于 1.12,推荐使用最新稳定版 Docker;
- 主机需要开放一些端口(TCP:2377 UDP:4789 TCP 和 UDP:7946)。
Swarm集群节点规划:
节点名称 | 节点IP | 角色 |
swarm-manager | 10.10.10.118 | manager |
swarm-node01 | 10.10.10.122 | node |
swarm-node02 | 10.10.10.126 | node |
swarm-node03 | 10.10.10.138 | node |
生产环境中推荐使用至少三个 manager 作为管理节点。
1. 初始化集群
Docker 1.12 版本后, Swarm 已经默认集成到了 Docker 中,因此我们可以直接使用 Docker 命令来初始化 Swarm,集群初始化的命令格式如下:
docker swarm init --advertise-addr <YOUR-IP>
advertise-addr 一般用于主机有多块网卡的情况,如果你的主机只有一块网卡,可以忽略此参数。
在管理节点上,用命令docker swarm init
初始化集群
[root@centeros ~]# docker swarm init
Swarm initialized: current node (dffavr13cspslx6z48jpnazjn) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-62uxmsszipbbnz26n17dyvj9i9jzciyg8a7wwdfteh8l41uyqu-6mz65p1x1ltvj0p9padac0rvs 10.10.10.118:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
2.加入工作节点
按照第一步集群初始化后输出的提示,只需要复制其中的命令即可,然后在剩余的三台工作节点上分别执行如下命令:
docker swarm join --token SWMTKN-1-62uxmsszipbbnz26n17dyvj9i9jzciyg8a7wwdfteh8l41uyqu-6mz65p1x1ltvj0p9padac0rvs 10.10.10.118:2377
默认加入的节点为工作节点,若要加入管理节点,请在主节点使用以下命令查看如何增加管理节点:
docker swarm join-token manager
若关闭终端后还需要加入新的工作节点,使用命令docker swarm join-token worker
重新获取令牌
注意:管理节点的数量必须为奇数,生产环境推荐使用3个、5个或7个管理节点来管理 Swarm 集群。
3.查看集群节点
使用命令docker node ls
查看节点
[root@centeros ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
dffavr13cspslx6z48jpnazjn * centeros.esricd.local Ready Active Leader 20.10.0
tiwcdwv9is3mf9twhdr8iv87m swarm-node01 Ready Active 20.10.0
x7yu2s955fc7tqk06nqlzjwhg swarm-node02 Ready Active 20.10.0
yrjgugpnazct0xjujxw3yu9ot swarm-node03 Ready Active 20.10.0
4. 使用Swarm
使用docker service create
创建服务,如下:
docker service create --replicas 4 -p 80:80 --name hello-world nginx
使用命令docker service ls
查看已经启动的有4个副本的Nginx服务
[root@centeros ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
yb3fsqy99o8y hello-world replicated 4/4 nginx:latest
使用命令docker service rm
删除启动的服务
使用浏览器打开各节点地址,发现均已启动Nginx
在各节点使用命令docker ps
可发现每个节点都分配了一个nginx容器
[root@centeros ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e827c8ca2890 nginx:latest "/docker-entrypoint.…" 51 seconds ago Up 48 seconds 80/tcp hello-world.1.1xvh5668a69fnv3ezw4rwksks
[root@swarm-node01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
75e252a5f386 nginx:latest "/docker-entrypoint.…" 54 seconds ago Up 52 seconds 80/tcp hello-world.2.emplxi67cbnb6fk6nmgnutf1i
[root@swarm-node02 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b4283a99756b nginx:latest "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 80/tcp hello-world.3.bf4avbo6cvgmxurkhipw1mppi
[root@swarm-node03 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dd51e76d7990 nginx:latest "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 80/tcp hello-world.4.fmhlayb8mb3oaumxdabf2lvw0
以上搭建完成之后,docker swarm将开启负载均衡,访问仍一节点即可。
更多搭建集群可参考:链接
使用docker stack启动swarm集群
使用docker compose时使用的yaml文件作为模板并作出稍微改造,如下:
version: '3'
services:
mysql:
image: mysql:5.7
volumes:
- mysql_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: mywordpress
MYSQL_USER: mywordpress
MYSQL_PASSWORD: mywordpress
wordpress:
depends_on:
- mysql
image: wordpress:php7.4
deploy:
mode: replicated
replicas: 4
ports:
- "8080:80"
restart: always
environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_USER: mywordpress
WORDPRESS_DB_PASSWORD: mywordpress
WORDPRESS_DB_NAME: mywordpress
volumes:
mysql_data: {}
与原文件不同的是,增加了deploy指令,并制定了副本数量
使用命令docker stack deploy -c docker-compose.yaml wordpress
启动
[root@centeros ~]# docker stack deploy -c docker-compose.yaml wordpress
Ignoring unsupported options: restart
Creating network wordpress_default
Creating service wordpress_wordpress
Creating service wordpress_mysql
成功启动4个副本的wordpress