docker进阶_dockerswarm
DockerSwarm
Docker Swarm简介
Docker Swarm的功能
? Docker Swarm包含两个方面:docker安全集群,以及一个微服务应用引擎
? 集群方面,swarm将一个或多个docker节点组织起来,是的用户能以集群方式管理它,swarm默认内置有加密的分布式集群存储、加密网络、公有TLS、安全集群接入令牌以及一个简化数字证书管理的PKI。用户可以自如的添加或删除节点
? 编排方面,Swarm提供了一套丰富的API使得部署和管理复杂的微服务应用变得易如反掌,通过将应用定义在声明式配置文件中,就可以使用原生docker命令完成部署。甚至可以滚动升级、回滚、扩缩容。
? Docker Swarm 是 Docker 的集群管理工具。它将 Docker 主机池转变为单个虚拟 Docker 主机。 Docker Swarm 提供了标准的 Docker API,所有任何已经与 Docker 守护程序通信的工具都可以使用 Swarm 轻松地扩展到多个主机。dockerswarm是docker为了方便集群管理、容器编排产生的技术。
Docker Swarm 模式介绍
docker-compose up 启动一个项目开启一系列服务 单机模式
docker swarm 集群模式 多个机器
? dockerswarm中有节点的概念,一个节点就可以通俗的理解为一个机器(可以是物理服务器也可以是虚拟机、云等等)。dockerswarm由多个节点组成,节点又分为管理节点(Manager)与工作节点(Worker),管理节点负责集群控制,能过监控集群状态、分发任务到工作节点;工作节点是接收来自管理节点的任务并执行。
? Swarm的配置和状态信息保存在一套位于所有管理节点上的分布式etcd数据库中。该服务器运行在内存中(速度快),并且作为Swarm的一部分被安装,无需管理
? Swarm集群使用了TLS自动秘钥轮换 所以安全性不需要考虑
? 应用编排,Swarm最小的调度单元称为服务,拿redis举例 在一个集群中开启了一个redis服务 然后需要下发到各个节点上生成容器去运行redis ,运行的这个容器就叫任务(副本),一个服务中封装了多个任务。(多加练习)
十台机器以下docker swarm即可 ,机器数量多的时候要用k8s。
[]: https://docs.docker.com/engine/swarm/ "dockerswarm官方文档"
初始化集群
搭建集群是每个节点都需要安装docker!!并且在防火墙开放2377、7946、4789这三个端口
- 2377/tcp:用于客户端与Swarm进行安全通信
- 7946/tcp&&udp:用于控制面板gossip分发
- 4789/udp:用于基于VXLAN的覆盖网络
搭建集群大体流程:初始化第一个管理节点>加入额外的管理节点>加入工作节点>完成
不包含在任何 Swarm 中的 Docker 节点,称为运行于单引擎(Single-Engine)模式。一旦被加入 Swarm 集群,则切换为 Swarm 模式,如下图所示。
在单引擎模式下的 Docker 主机上运行 docker swarm init会将其切换到 Swarm 模式,并创建一个新的 Swarm,将自身设置为 Swarm 的第一个管理节点。
更多的节点可以作为管理节点或工作节点加入进来。这一操作也会将新加入的节点切换为 Swarm 模式
查看docker swarm帮助命令
beginner@beginner-virtual-machine:~$ docker swarm --help
==============================================================
Usage: docker swarm COMMAND
Manage Swarm
Commands:
ca Display and rotate the root CA
init Initialize a swarm
join Join a swarm as a node and/or manager
join-token Manage join tokens
leave Leave the swarm
unlock Unlock swarm
unlock-key Manage the unlock key
update Update the swarm
Run 'docker swarm COMMAND --help' for more information on a command.
==============================================================
初始化集群(这里选择在本地局域网内搭建)
beginner@beginner-virtual-machine:~$ docker swarm init --advertise-addr 192.168.0.106
==============================================================
Swarm initialized: current node (nb4wuodurb7hq0i6yd9r0tzan) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-3l3qurw9tqjlx9uzhgj9fqdpss7hi0ig3yb86iu45u2q1zfxlv-4kw80d9b3ptt22wjfoikb5fej 192.168.0.106:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
==============================================================
# 上面给出了工作节点的加入口令,同时也给出了管理节点的加入方式 在管理节点上运行docker swarm join-token manager 就可以获得加入口令
beginner@beginner-virtual-machine:~$ docker swarm join-token manager
==============================================================
To add a manager to this swarm, run the following command:
docker swarm join --token SWMTKN-1-3l3qurw9tqjlx9uzhgj9fqdpss7hi0ig3yb86iu45u2q1zfxlv-1vwu2sxcqhdr621gn0sv2vdqk 192.168.0.106:2377
==============================================================
- 以工作节点的身份加入集群
beginner2@beginner2-virtual-machine2:~/Desktop$ docker swarm join --token SWMTKN-1-3l3qurw9tqjlx9uzhgj9fqdpss7hi0ig3yb86iu45u2q1zfxlv-4kw80d9b3ptt22wjfoikb5fej 192.168.0.106:2377
This node joined a swarm as a worker.
- 以管理节点的身份加入集群
docker swarm join --token SWMTKN-1-3l3qurw9tqjlx9uzhgj9fqdpss7hi0ig3yb86iu45u2q1zfxlv-1vwu2sxcqhdr621gn0sv2vdqk 192.168.0.106:2377
- 查看节点情况 正常的集群不应该是这样 !!!我偷懒只启动了两个只为了说明效果 注意虽然两个HOSTNAME一样但并不是同一台机器(因为在之前其中的一台虚拟机是复制的另一台虚拟机,现在就顺手拿用)
docker node ls #注意必须是管理节点的身份才可以查看
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
92itu9f5253l4d9syx690cgb2 beginner-virtual-machine Ready Active 20.10.7
nb4wuodurb7hq0i6yd9r0tzan * beginner-virtual-machine Ready Active Leader 20.10.7
Swarm 管理器高可用性(HA)
Raft协议:保证大多数管理节点存活 集群才可以用,集群中管理节点至少大于三台,
假设当前集群中有三个管理节点,当挂了一个管理节点后 还有两个存活(大多数都存活) 所以集群仍可用
Swarm使用了Raft来实现了支持管理节点的HA,即使一个或多个节点发生故障,剩余管理节点也会继续保证 Swarm 的运转。
从技术上来说,Swarm 实现了一种主从方式的多管理节点的 HA。这意味着,即使你可能有多个管理节点,也总是仅有一个节点处于活动状态。
通常处于活动状态的管理节点被称为“主节点”(leader),而主节点也是唯一一个会对 Swarm 发送控制命令的节点。也就是说,只有主节点才会变更配置,或发送任务到工作节点。如果一个备用(非活动)管理节点接收到了 Swarm 命令,则它会将其转发给主节点。
这一过程如下图所示。步骤 ① 指命令从一个远程的 Docker 客户端发送给一个管理节点;步骤 ② 指非主节点将命令转发给主节点;步骤 ③ 指主节点对 Swarm 执行命令。
关于 HA,有以下两条最佳实践原则。
- 部署奇数个管理节点。
- 不要部署太多管理节点(建议 3 个或 5 个)。
部署奇数个管理节点有利于减少脑裂(Split-Brain)情况的出现机会。假如有 4 个管理节点,当网络发生分区时,可能会在每个分区有两个管理节点。这种情况被称为脑裂。
每个分区都知道曾经有 4 个节点,但是当前网络中仅有两个节点,糟糕的是,每个分区都无法知道其余两个节点是否运行,也无从得知本分区是否掌握大多数(Quorum)。
虽然在脑裂情况下集群依然在运行,但是已经无法变更配置,或增加和管理应用负载了。不过,如果部署有 3 个或 5 个管理节点,并且也发生了网络分区,就不会出现每个分区拥有同样数量的管理节点的情况。
这意味着掌握多数管理节点的分区能够继续对集群进行管理。下图中右侧的例子,阐释了这种情况,左侧的分区知道自己掌握了多数的管理节点。
对于所有的共识算法来说,更多的参与节点就意味着需要花费更多的时间来达成共识。这就像决定去哪吃饭,只有3个人的时候总是比有33个人的时候能更快确定。
考虑到这一点,最佳的实践原则是部署 3 个或 5 个节点用于 HA。7 个节点可以工作,但是通常认为 3 个或 5 个是更优的选择。当然绝对不要多于 7 个,因为需要花费更长的时间来达成共识。
关于管理节点的 HA 再补充一点。显然将管理节点分布到不同的可用域(Availability Zone)中是一种不错的实践方式,但是一定要确保它们之间的网络连接是可靠的,否则由于底层网络分区导致的问题将是令人痛苦的。
锁定 Swarm
? 尽管内置有如此多的原生安全机制,重启一个旧的管理节点或进行备份恢复仍有可能对集群造成影响。一个旧的管理节点重新接入 Swarm 会自动解密并获得 Raft 数据库中长时间序列的访问权,这会带来安全隐患。进行备份恢复可能会抹掉最新的 Swarm 配置。
? 为了规避以上问题,Docker 提供了自动锁机制来锁定 Swarm,这会强制要求重启的管理节点在提供一个集群解锁码之后才有权从新接入集群。
通过在执行 docker swarm init
命令来创建一个新的 Swarm 集群时传入 --autolock 参数可以直接启用锁。然而,前面已经搭建了一个 Swarm 集群,这时也可以使用 docker swarm update
命令来启用锁。
在某个 Swarm 管理节点上运行如下命令。
$ docker swarm update --autolock=true
Swarm updated.
To unlock a swarm manager after it restarts, run the
`docker swarm unlock`command and provide the following key:
SWMKEY-1-5+ICW2kRxPxZrVyBDWzBkzZdSd0Yc7Cl2o4Uuf9NPU4
Please remember to store this key in a password manager, since without
it you will not be able to restart the manager.
请确保将解锁码妥善保管在安全的地方!重启某一个管理节点,以便观察其是否能够自动重新接入集群。
$ 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。
Swarm集群创建服务
可以动态扩缩容 屏蔽底层差异
集群服务的相关命令docker service
beginner@beginner-virtual-machine:~$ docker service
Usage: docker service COMMAND
Manage services
Commands:
create Create a new service
inspect Display detailed information on one or more services
logs Fetch the logs of a service or task
ls List services
ps List the tasks of one or more services
rm Remove one or more services
rollback Revert changes to a service's configuration
scale Scale one or multiple replicated services
update Update a service
启动一个示例
docker service create -p 8888:80 --name my-nginx nginx:latest
--mode global所有节点都可以创建任务副本运行
--mode replicas 只有工作节点才能运行
查看服务
docker service ls
动态扩缩容实现高可用
docker service update --relipcas 10 my-nginx #现在让整个项目整体产生10个服务
docker service update --relipcas 2 my-nginx # 将集群缩减为两个服务
docker service scale my-nginx=10
docker service scale my-nginx=2
与上面两个一模一样
滚动更新
docker service update \
--image nginx:2.0 \
--update-parallelism 2 \
--update-delay 20s my-nginx
# 将镜像更新为2.0 每次更新两个副本 每20s更新一次
移除服务
docker service rm my-nginx
命令总结
- docker swarm init 用于创建一个新的 Swarm。执行该命令的节点会成为第一个管理节点,并且会切换到 Swarm 模式。
- docker swarm join-token 用于查询加入管理节点和工作节点到现有 Swarm 时所使用的命令和 Token。 要获取新增管理节点的命令,请执行 docker swarm join-token manager 命令; 要获取新增工作节点的命令,请执行 docker swarm join-token worker 命令。
- docker node ls 用于列出 Swarm 中的所有节点及相关信息,包括哪些是管理节点、哪个是主管理节点。
- docker service create 用于创建一个新服务
- docker service ls 用于列出 Swarm 中运行的服务,以及诸如服务状态、服务副本等基本信息
- docker service ps 该命令会给出更多关于某个服务副本的信息
- docker service inspect 用于获取关于服务的详尽信息。附加 --pretty 参数可限制仅显示重要信息。
- docker service scale 用于对服务副本个数进行增减。
- docker service update 用于对运行中的服务的属性进行变更。
- docker service rm 用于从 Swarm 中删除某服务。该命令会在不做确认的情况下删除服务的所有副本,所以使用时应保持警惕