Docker Swarm (容器集群,高可用,安全)

 

一,简介

Swarm 是 Docker 官方提供的一款集群管理工具,其主要作用是把若干台 Docker 主机抽象为一个整体,并且通过一个入口统一管理这些 Docker 主机上的各种 Docker 资源。Swarm 和 Kubernetes 比较类似,但是更加轻,具有的功能也较 kubernetes 更少一些。

Docker Swarm 包含两方面:一个企业级的 Docker 安全集群,以及一个微服务应用编排引擎。

集群方面,Swarm 将一个或多个 Docker 节点组织起来,使得用户能够以集群方式管理它们。Swarm 默认内置有加密的分布式集群存储(encrypted distributed cluster store)、加密网络(Encrypted Network)、公用TLS(Mutual TLS)、安全集群接入令牌 Secure Cluster Join Token)以及一套简化数字证书管理的 PKI(Public Key Infrastructure)。我们可以自如地添加或删除节点。

编排方面,Swarm 提供了一套丰富的 API 使得部署和管理复杂的微服务应用变得易如反掌。通过将应用定义在声明式配置文件中,就可以使用原生的 Docker 命令完成部署。

此外,甚至还可以执行滚动升级、回滚以及扩缩容操作,同样基于简单的命令即可完成。以往,Docker Swarm 是一个基于 Docker 引擎之上的独立产品。自 Docker 1.12 版本之后,它已经完全集成在 Docker 引擎中,执行一条命令即可启用。到 2018 年,除了原生 Swarm 应用,它还可以部署和管理 Kubernetes 应用。

二,Docker Swarm集群搭建

Docker Swarm (容器集群,高可用,安全)_第1张图片

2.1 准备

在集群中有管理节点和工作节点。(管理节点最少一个,管理节点当即之后集群将不能正常工作)。

由于资源有限我们这里用一个管理节点和两个工作节点来演示。

Docker Swarm (容器集群,高可用,安全)_第2张图片

ssh工具FinalShell

Docker Swarm (容器集群,高可用,安全)_第3张图片

如上图我们有两个主机,ip主机位分别是50,51,52,分别修改主机名为 manager1,worker1,worker2

hostnamectl set-hostname 

每个节点都需要安装 Docker,并且能够与 Swarm 的其他节点通信。由于前面的文章已经说到Docker的安装,这里不再描述。

2377/tcp:用于客户端与 Swarm 进行安全通信。

7946/tcp 与 7946/udp:用于控制面 gossip 分发。

4789/udp:用于基于 VXLAN 的覆盖网络。

在网络方面,需要在路由器和防火墙中开放如下端口。这里为了方便直接关闭防火墙。

sudo systemctl stop firewalld.service && sudo systemctl disable firewalld.service

如果满足以上前提,就可以着手开始搭建 Swarm 集群了。

搭建 Swarm 的过程有时也被称为初始化 Swarm,大体流程包括初始化第一个管理节点 -> 加入额外的管理节点 -> 加入工作节点 -> 完成。

2.2 初始化一个全新的 Swarm

不包含在任何 Swarm 中的 Docker 节点,称为运行于单引擎(Single-Engine)模式。一旦被加入 Swarm 集群,则切换为 Swarm 模式,如下图所示。

Docker Swarm (容器集群,高可用,安全)_第4张图片

在单引擎模式下的 Docker 主机上运行 docker swarm init会将其切换到 Swarm 模式,并创建一个新的 Swarm,将自身设置为 Swarm 的第一个管理节点。

更多的节点可以作为管理节点或工作节点加入进来。这一操作也会将新加入的节点切换为 Swarm 模式。

2.2.1 初始化集群

docker swarm init [OPTIONS]

--advertise-addr: 多网卡的情况下,指定需要使用的ip

--listen-addr: 指定监听的 ip 与端口

--availability: 节点的有效性("active"|"pause"|"drain")

Active:集群中该Node可以被指派Task
Pause:集群中该Node不可以被指派新的Task,但是其他已经存在的Task保持运行
Drain:集群中该Node不可以被指派新的Task,Swarm Scheduler停掉已经存在的Task,并将它们调度到可用的Node上

我们切换到50(manager1)下执行,执行完之后我们已经创建了一个主节点。

docker swarm init --advertise-addr 192.168.1.50 --listen-addr 192.168.1.50:2377

2.2.2 添加节点

docker swarm join [OPTIONS] HOST:PORT

--token: 所需加入集群的token

--advertise-addr: 多网卡的情况下,指定需要使用的ip

--listen-addr: 指定监听的 ip 与端口

--availability: 节点的有效性("active"|"pause"|"drain")

Active:集群中该Node可以被指派Task
Pause:集群中该Node不可以被指派新的Task,但是其他已经存在的Task保持运行
Drain:集群中该Node不可以被指派新的Task,Swarm Scheduler停掉已经存在的Task,并将它们调度到可用的Node上

首先在50(manager1)上执行docker swarm join-token

docker swarm join-token 命令用来获取添加新的工作节点和管理节点到 Swarm 的命令和 Token。

Docker Swarm (容器集群,高可用,安全)_第5张图片

 

请注意,工作节点和管理节点的接入命令中使用的接入 Token(SWMTKN...)是不同的。因此,一个节点是作为工作节点还是管理节点接入,完全依赖于使用了哪个 Token。接入 Token 应该被妥善保管,因为这是将一个节点加入 Swarm 的唯一所需!

分别为50添加主节点和为51,52添加工作节点

#在**上执行添加主节点用,在这我们只演示一个主节点,所以不再执行。
docker swarm join --advertise-addr 192.168.1.50 --listen-addr 192.168.1.50:2377 --token SWMTKN-1-46936r3p7zqg92k1jdx6a80580eo3xy3co1miu5rhx3adgvkyd-bh2yvw8unuvqs98kdijyo3ys9 192.168.1.50:2377
#在51(worker1)上执行
docker swarm join --advertise-addr 192.168.1.51 --listen-addr 192.168.1.51:2377 --token SWMTKN-1-46936r3p7zqg92k1jdx6a80580eo3xy3co1miu5rhx3adgvkyd-4rxm5euft8bhuqixjhe8bg8ta 192.168.1.50:2377
#在52(worker1)上执行
docker swarm join --advertise-addr 192.168.1.52 --listen-addr 192.168.1.52:2377 --token SWMTKN-1-46936r3p7zqg92k1jdx6a80580eo3xy3co1miu5rhx3adgvkyd-4rxm5euft8bhuqixjhe8bg8ta 192.168.1.50:2377

2.2.3 查看

在任意一个管理节点上执行 docker node ls 命令来列出 Swarm 节点。

到这里我们已经完成了集群的搭建,当然关于节点的操作命令还有很多,我们在后面的文章中会做一个总结。

3,Swarm 管理器高可用性(HA)

Swarm 的管理节点内置有对 HA 的支持。这意味着,即使一个或多个节点发生故障,剩余管理节点也会继续保证 Swarm 的运转。

从技术上来说,Swarm 实现了一种主从方式的多管理节点的 HA。这意味着,即使你可能有多个管理节点,也总是仅有一个节点处于活动状态。

通常处于活动状态的管理节点被称为“主节点”(leader),而主节点也是唯一一个会对 Swarm 发送控制命令的节点。也就是说,只有主节点才会变更配置,或发送任务到工作节点。如果一个备用(非活动)管理节点接收到了 Swarm 命令,则它会将其转发给主节点。

这一过程如下图所示。步骤 ① 指命令从一个远程的 Docker 客户端发送给一个管理节点;步骤 ② 指非主节点将命令转发给主节点;步骤 ③ 指主节点对 Swarm 执行命令。

Docker Swarm (容器集群,高可用,安全)_第6张图片

仔细观察上图会发现,管理节点或者是 Leader 或者是 Follower。这是 Raft 的术语,因为 Swarm 使用了 Raft 共识算法的一种具体实现来支持管理节点的HA。

关于 HA,有以下两条最佳实践原则。

部署奇数个管理节点。

不要部署太多管理节点(建议 3 个或 5 个)。


部署奇数个管理节点有利于减少脑裂(Split-Brain)情况的出现机会。假如有 4 个管理节点,当网络发生分区时,可能会在每个分区有两个管理节点。这种情况被称为脑裂。

每个分区都知道曾经有 4 个节点,但是当前网络中仅有两个节点,糟糕的是,每个分区都无法知道其余两个节点是否运行,也无从得知本分区是否掌握大多数(Quorum)。

虽然在脑裂情况下集群依然在运行,但是已经无法变更配置,或增加和管理应用负载了。不过,如果部署有 3 个或 5 个管理节点,并且也发生了网络分区,就不会出现每个分区拥有同样数量的管理节点的情况。

这意味着掌握多数管理节点的分区能够继续对集群进行管理。下图中右侧的例子,阐释了这种情况,左侧的分区知道自己掌握了多数的管理节点。

Docker Swarm (容器集群,高可用,安全)_第7张图片

4,内置的 Swarm 安全机制

Swarm 集群内置有繁多的安全机制,并提供了开箱即用的合理的默认配置——如 CA 设置、接入 Token、公用 TLS、加密集群存储、加密网络、加密节点 ID 等。

5,锁定 Swarm

尽管内置有如此多的原生安全机制,重启一个旧的管理节点或进行备份恢复仍有可能对集群造成影响。

一个旧的管理节点重新接入 Swarm 会自动解密并获得 Raft 数据库中长时间序列的访问权,这会带来安全隐患。

进行备份恢复可能会抹掉最新的 Swarm 配置。

为了规避以上问题,Docker 提供了自动锁机制来锁定 Swarm,这会强制要求重启的管理节点在提供一个集群解锁码之后才有权从新接入集群。

通过在执行 docker swarm init 命令来创建一个新的 Swarm 集群时传入 --autolock 参数可以直接启用锁。

然而,前面已经搭建了一个 Swarm 集群,这时也可以使用 docker swarm update 命令来启用锁。

在某个 Swarm 管理节点上运行如下命令。

docker swarm update --autolock=true

请确保将解锁码妥善保管在安全的地方!

重启某一个管理节点,以便观察其是否能够自动重新接入集群。

service docker restart

尝试列出Swarm中的节点。

docker node ls

Error response from daemon: Swarm is encrypted and needs to be unlocked
before it can be used.

尽管 Docker 服务已经重启,该管理节点仍然未被允许重新接入集群。

为了进一步验证,可以到其他管理节点执行 docker node ls 命令,会发现重启的管理节点会显示 down 以及 unreachable。

执行 docker swarm unlock 命令来为重启的管理节点解锁 Swarm。该命令需要在重启的节点上执行,同时需要提供解锁码。

docker swarm unlock

Please enter unlock key: 

该节点将被允许重新接入 Swarm,并且再次执行 docker node ls 命令会显示 ready 和 reachable。

 

 

 

 

你可能感兴趣的:(docker)