docker高级02
1.Docker Swarm
1.1 简介
Docker Swarm 是由 Docker 公司推出的 Docker 的原生集群管理系统,它将一个 Docker主机池变成了一个单独的虚拟主机,用户只需通过简单的 API 即可实现与 Docker 集群的通信。
Docker swarm 使用 GO 语言开发,从 Docker 1.12.0版本开始,Docker swarm 已经内置于Docker引擎中,无需再专门的进行安装配置。
官网: https://docs.docker.com/engine/swarm/
1.1.1 节点
在 Docker Swarm 中,Manager 节点是集群的核心管理组件,负责维护集群状态、调度任务、处理 API 请求以及确保集群的高可用性。Manager 节点通过 Raft 一致性算法实现分布式一致性,确保集群的稳定运行。
Manager 节点的作用
- 集群管理:
- Manager 节点负责管理整个 Swarm 集群,包括节点的加入、离开、状态监控等。
- 它维护集群的全局状态,并确保所有节点的一致性。
- 任务调度:
- Manager 节点根据服务的定义和资源需求,将任务(Tasks)调度到合适的 Worker 节点上运行。
- 调度策略包括节点资源、约束条件(constraints)和偏好(preferences)等。
- 高可用性:
- Manager 节点通过 Raft 一致性算法实现高可用性。
- 多个 Manager 节点组成一个高可用集群,确保即使某个 Manager 节点失效,集群仍能正常运行。
- API 服务:
- Manager 节点提供 Docker API 服务,用于接收用户的管理请求(如创建服务、更新配置等)。
- 所有对 Swarm 集群的操作(如
docker service create
)都通过 Manager 节点执行。
- 维护集群状态:
- Manager 节点维护集群的全局状态,包括服务、网络、卷、配置和密钥等信息。
- 这些状态信息通过 Raft 日志在多个 Manager 节点之间同步。
- Leader 选举:
- 在多个 Manager 节点中,会选举出一个 Leader 节点,负责处理集群的管理任务。
- 如果 Leader 节点失效,剩余的 Manager 节点会重新选举一个新的 Leader。
- 安全性:
- Manager 节点负责管理 Swarm 集群的安全配置,如 TLS 证书、加密密钥等。
- 它还控制节点的加入和权限管理。
在 Docker Swarm 中,Worker 节点是 Swarm 集群的重要组成部分,主要负责运行和管理由 Swarm 调度的容器化任务(Tasks)。Worker 节点不参与 Swarm 集群的管理和决策,而是专注于执行实际的工作负载。
Worker 节点的作用
- 运行服务任务:
- Worker 节点负责运行由 Swarm Manager 节点调度的服务任务(Tasks)。
- 每个任务通常对应一个容器实例。
- 负载均衡:
- Worker 节点通过 Swarm 的内置负载均衡机制,确保服务的高可用性和性能。
- Swarm 会自动将任务分配到可用的 Worker 节点上。
- 扩展性和弹性:
- Worker 节点可以根据需要动态扩展或缩减,以应对工作负载的变化。
- 如果某个 Worker 节点失效,Swarm 会将该节点上的任务重新调度到其他健康的 Worker 节点上。
- 资源提供:
- Worker 节点提供计算、存储和网络资源,用于运行容器化应用。
- 与 Manager 节点协作:
- Worker 节点从 Manager 节点接收任务指令,并定期向 Manager 节点报告状态。
- Worker 节点不参与集群管理决策(如 Leader 选举、服务调度策略等)。
1.1.2 服务、任务、容器
- Service(服务)
-
定义:
- Service 是 Swarm 中部署和管理的核心单元,代表一个长期运行的应用或微服务。
- 它定义了应用的镜像、副本数量、网络配置、存储卷、环境变量等。
-
特点:
-
Service 是面向用户的抽象,用户通过创建和管理 Service 来部署应用。
-
Service 可以指定副本数量(Replicated Mode)或全局模式(Global Mode)。
-
Replicated Mode:指定固定数量的任务副本。
-
Global Mode:在每个符合条件的节点上运行一个任务。
-
-
- Task(任务)
-
定义:
- Task 是 Service 的具体实例化单位,代表一个容器化的任务。
- 每个 Task 对应一个容器,由 Swarm Manager 调度到某个节点上运行。
-
特点:
- Task 是 Swarm 调度的最小单位。
- 每个 Task 包含容器的配置信息(如镜像、网络、存储卷等)。
- Task 的状态由 Swarm Manager 监控和管理(如运行中、失败、完成等)。
-
示例:
- 如果一个 Service 定义了 3 个副本,Swarm 会创建 3 个 Task,每个 Task 对应一个容器。
- Container(容器)
- 定义:
- Container 是 Task 的实际运行实例,是 Docker 容器化的具体表现。
- 它是基于镜像创建的运行时环境,包含应用代码、依赖和配置。
- 特点:
- Container 是 Task 的具体实现,由 Task 定义其配置。
- 每个 Container 在某个节点上运行,由 Docker 引擎管理。
- 示例:
- 如果一个 Task 被调度到某个节点上,Docker 会在该节点上启动一个对应的容器。
三者的关系
- 层次结构:
- Service > Task > Container
- 一个 Service 包含多个 Task,每个 Task 对应一个 Container。
- 创建流程:
- 用户创建一个 Service,并指定副本数量。
- Swarm Manager 根据 Service 的定义,创建相应数量的 Task。
- 每个 Task 被调度到某个节点上,并由 Docker 引擎启动对应的 Container。
- 状态管理:
- Swarm Manager 监控 Service、Task 和 Container 的状态。
- 如果某个 Container 失效,Swarm 会重新调度对应的 Task,并在其他节点上启动新的 Container。
1.2 swarm集群
现要搭建一个 docker swarm 集群,包含5个swarm 节点。这5个swarm 节点的IP与暂时的角色分配如下(注意,是暂时的):
hostname | ip | role | required |
---|---|---|---|
docker1 | 192.168.9.3 | manager | 2核2G |
docker2 | 192.168.9.4 | manager | 2核2G |
docker3 | 192.168.9.5 | manager | 2核2G |
docker4 | 192.168.9.6 | worker | 1核1G |
docker5 | 192.168.9.7 | worker | 1核1G |
先了解以下命令:
docker1:
初始化swarm,默认自己会成为 manager 节点。
# 在 docker1 初始化 swarm
docker swarm init
注:用 docker info 查看信息
docker4:
把 docker4 作为 worker节点加入swarm
# To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-5pj3mb6esgm13y7u2dvyre7jyaw2an7g628yg9nkgynp55ewhd-15di9u6twoea9ghapqmk99ozt 192.168.9.3:2377
docker2 和 docker3:
把 docker2和docker3 作为 manager 节点加入 swarm
# 在docker1上
# To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
docker swarm join-token manager
# 在docker2 和 docker3 上
docker swarm join --token SWMTKN-1-5pj3mb6esgm13y7u2dvyre7jyaw2an7g628yg9nkgynp55ewhd-0b465wi3hij8yqjea9qoqybm1 192.168.9.3:2377
查看命令说明
docker5:
把 docker5 作为 worker节点加入swarm
同理,也可以在docker1 运行:
# 在docker1上
docker swarm join-token worker
# 在docker5上
docker swarm join --token SWMTKN-1-5pj3mb6esgm13y7u2dvyre7jyaw2an7g628yg9nkgynp55ewhd-15di9u6twoea9ghapqmk99ozt 192.168.9.3:2377
查看节点信息:
docker node ls
1.3 节点维护
1.3.1 退群进群
worker 节点
worker 节点退群,以docker5 为例
# 在docker5上
docker swarm leave
在其他主机如docker1,查看节点信息(发现 docker5 的状态为 down)
docker5 重新加入 swarm
在docker1,查看节点信息,发现有两个 docker5 节点,但是ID不同。
这也就说明节点其实是逻辑概念,某台docker主机上可以存在若干节点。
要删除down节点,可以:docker node rm
再次查看节点
manager 节点
manager 节点退群,以docker3 为例:
这个错误表明你正在尝试从 Docker Swarm 集群中的一个 Manager 节点上执行 docker swarm leave
命令,而该节点当前是 Swarm 集群的管理者之一。由于 Manager 节点在 Swarm 中负责维护集群状态和一致性(通过 Raft 算法),直接离开可能会导致集群失去法定人数(quorum),从而无法正常工作。
错误原因
- Manager 节点的重要性:
- Swarm 集群需要多数(quorum)的 Manager 节点在线才能正常工作。如果过多的 Manager 节点离开,集群将无法达成共识,导致无法管理服务。
- 例如,如果你有 3 个 Manager 节点,至少需要 2 个在线才能维持集群的正常运行。
- 直接离开的后果:
- 如果你从一个 Manager 节点上直接执行
docker swarm leave
,可能会导致集群失去 quorum,从而无法继续运行。
- 如果你从一个 Manager 节点上直接执行
解决方法
方法 1:降级 Manager 节点
如果你希望该节点离开 Swarm 集群,但不影响集群的正常运行,可以先将该节点从 Manager 降级为 Worker 节点,然后再离开。
-
降级节点:
docker node demote <NODE-ID>
- 将
<NODE-ID>
替换为你要降级的节点的 ID(可以通过docker node ls
查看)。
- 将
-
离开 Swarm:
docker swarm leave
方法 2:强制离开
如果你确定要强制该节点离开 Swarm 集群,可以使用 --force
参数。但请注意,这可能会导致集群失去 quorum,从而无法正常工作。
-
强制离开:
docker swarm leave --force
-
如果集群因此失去 quorum,你需要手动恢复集群:
-
在剩余的 Manager 节点上执行以下命令,强制重新初始化集群:
docker swarm init --force-new-cluster
-
这将使当前节点成为新的 Swarm 集群的 Leader,并尝试恢复集群状态。
-
方法 3:恢复集群
如果集群已经失去 quorum 且无法正常工作,可以尝试以下步骤恢复:
-
在剩余的 Manager 节点上执行:
docker swarm init --force-new-cluster
- 这会强制重新初始化 Swarm 集群,并使当前节点成为新的 Leader。
-
重新加入其他节点:
- 使用
docker swarm join-token
获取新的加入令牌,然后让其他节点重新加入集群。
- 使用
测试方法1
把 docker3 降级
此时 docker3 已经从 manager 变为了 worker,从docker1 查看信息如下:
也可以在 docker1 把 docker3 提升为 manager:
1.3.2 更改角色 (升级降级)
在 manager 节点上可以更新节点信息
docker3 降级为 worker:
docker3 升级为 manager:
1.3.3 节点标签
可以给节点添加、更改、删除标签
1.4 manager 自动锁定
在 manager 集群中,swarm 通过 Raft 日志方式维护了 manager 集群中数据的一致性。即在 manager 集群中每个节点通过 manager 间通信方式维护着自己的 Raft 日志。
但在通信过程中存在有一种风险:Raft 日志攻击者会通过 Raft日志数据的传递来访问篡改 manager 节点中的配置或数据。为了防止被攻击,swarm 开启了一种集群自动锁定功能,为 manager 间的通信启用了 TLS 加密。用于加密和解密的公钥与私钥,全部都维护在各个节点的 Docker 内存中。
开启了自动锁定后,一旦节点的 Docker 重启,则密钥丢失,那么集群就会出问题。
swarm 中通过 autolock 标志来设置集群的自动锁定功能:为 true 则开启自动锁定,为 false 则关闭自动锁定。
1.4.1 开启 autolock
在初始化时可以用 --autolock=true 开启自动锁定:
如果已经初始化过了,但未开启自动锁定,可以通过 docker swarm update 命令进行更新开启自动锁定
用 docker info 查询,之前的案例中,autolock 并未开启:
在任意一台 manager 执行 update 都可开启 autolock:
此时 docker info:
如果 unlock-key 忘记了,可用以下命令查询:
1.4.2 状况模拟
假设 docker3 宕机了:
在其他 manager 查看节点信息:
假设 docker3 故障排除又开机了:
发现它不会自动成为 manager 节点,因为自动锁定的问题,需要对其进行解锁
此时用 docker info 查看也会发现 swarm 已锁定:
解锁:
注:在生产环境中会开启自动锁定,但为了学习方便,还是不开启自动锁定了。
(docker swarm update --autolock=false)
1.5 服务创建
在 Docker Swarm 中创建服务非常简单,下面以部署 tomcat 服务为例,详细讲解如何创建和管理服务。
使用 docker service create
命令创建 Tomcat 服务。
docker service create --name tomcat -p 8081:8080 --replicas 3 tomcat:8.5.32
参数说明:
--name tomcat
:指定服务名称为tomcat
。-p 8081:8080
:将宿主机的 8080 端口映射到容器的 8080 端口(Tomcat 默认端口)。- 也可以写成
--publish published=8080,target=8080
- 也可以写成
--replicas 3
:指定运行 3 个副本(即 3 个 Tomcat 容器)。tomcat:8.5.32
:使用官方 Tomcat 8.5.32 镜像。--limit-cpu 0.5
--limit-memory 512m
查看服务情况:
查看日志:
访问对应主机的tomcat服务:(docker3、docker2、docker5)
deepseek:docker swarm 怎么创建服务,请以tomcat为例讲解
1.6 服务的负载均衡
1.7 task伸缩与容错
1.8 服务回滚与全局部署
2.CI/CD与Jenkins
器)。
tomcat:8.5.32
:使用官方 Tomcat 8.5.32 镜像。--limit-cpu 0.5
--limit-memory 512m
[外链图片转存中…(img-jHnsxNZg-1740033627423)]
查看服务情况:
[外链图片转存中…(img-cL5JYT6D-1740033627423)]
查看日志:
[外链图片转存中…(img-drmHIsdn-1740033627423)]
访问对应主机的tomcat服务:(docker3、docker2、docker5)
[外链图片转存中…(img-EwKr7ct5-1740033627423)]
deepseek:docker swarm 怎么创建服务,请以tomcat为例讲解
1.6 服务的负载均衡
1.7 task伸缩与容错
[外链图片转存中…(img-q12wbMfJ-1740033627423)]