云原生Swarm解决docker server的集群化管理和部署
Posted Lion Long
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了云原生Swarm解决docker server的集群化管理和部署相关的知识,希望对你有一定的参考价值。
一文理解Swarm解决docker server的集群化管理和部署
一、简介
Docker Swarm 是Docker官方的跨节点的容器编排工具。用户只需要在单一的管理节点上操作,即可管理集群下的所有节点和容器。
主要解决问题:
- 解决docker server的集群化管理和部署。
- Swarm通过对Docker宿主机上添加的标签信息来将宿主机资源进行细粒度分区,通过分区来帮助用户将容器部署到目标宿主机上,同样通过分区方式还能提供更多的资源调度策略扩展。
单对单的Docker宿主机使用方式:
单对多的Docker宿主机使用方式:
swarm能做什么:
- 管理节点高可用,原生支持管理节点高可用,采用raft共识算法来支撑管理节点高可用。
- 应用程序高可用,支持服务伸缩,滚动更新和应用回滚等部署策略。
1.1、涉及到哪些概念?
(1)docker的两种模式,单引擎模式和swarm集群模式。
- 单引擎模式,docker server没有加入任何集群,且自身也没有加入初始化为swarm 节点,简单的说就是我们平时所操作的孤立的docker server。
- swarm模式,当docker server 加入到任意swarm集群,或者通过docker swarm init初始化swarm集群时,docker server会自动切换到swarm 集群模式。
(2)swarm集群中节点分类,分为:manager(管理节点)、node(工作节点)
- manager:是Swarm Daemon工作的节点,包含了调度器、路由、服务发现等功能,负责接收客户端的集群管理请求以及调度Node进行具体工作。manager 本身也是一个node节点。
- Node:接受manager调度,对容器进行创建、扩容和销毁等具体操作。
(3)raft共识算法,是实现分布式共识的一种算法,主要用来管理日志复制的一致性。
-
当Docker引擎在swarm模式下运行时,manager节点实现Raft一致性算法来管理全局集群状态。
-
Docker swarm模式之所以使用一致性算法,是为了确保集群中负责管理和调度任务的所有manager节点都存储相同的一致状态。
-
在整个集群中具有相同的一致状态意味着,如果出现故障,任何管理器节点都可以拾取任务并将服务恢复到稳定状态。例如,如果负责在集群中调度任务的领导管理器意外死亡,则任何其他管理器都可以选择调度任务并重新平衡任务以匹配所需状态。
-
使用一致性算法在分布式系统中复制日志的系统需要特别小心。它们通过要求大多数节点在值上达成一致,确保集群状态在出现故障时保持一致。
-
Raft最多可承受(N-1)/2次故障,需要(N/2)+1名成员的多数或法定人数才能就向集群提议的值达成一致。这意味着,在运行Raft的5个管理器集群中,如果3个节点不可用,系统将无法处理更多的请求来安排其他任务。现有任务保持运行,但如果管理器集不正常,调度程序无法重新平衡任务以应对故障。
(4)Swarm管理节点高可用。
- Swarm管理节点内置有对HA的支持,即使有一个或多个节点发送故障,剩余管理节点也会继续保证Swarm运转。
- Swarm实现了一种主从方式的多管理节点的HA,即使有多个管理节点也只有一个节点出于活动状态,处于活动状态的节点被称为主节点(leader),而主节点也是唯一一个会对Swarm发送控制命令的节点,如果一个备用管理节点接收到了Swarm命令,则它会将其转发给主节点。
(5)集群管理,集群创建和组织。
(6)节点管理,集群下节点角色信息变更,节点任务情况监控。
(7)服务管理,集群服务部署,服务管理等。
1.2、需要注意什么?
manager节点容错。
manager数量最好设置为奇数个,可以减少脑裂(Split-Brain)出现情况。在网络被划分成2个部分情况下,奇数个manager节点能够较高程度的保证有投票结果的可能性。
不要部署太多的manager节点(通常3到5个)。对于所有共识算法来说,更多的参与节点意味着需要花费更多的时间来达成共识,所以最好部署5个或三个节点。
Raft最多可承受(N-1)/2次故障,需要(N/2)+1名成员的多数或法定人数才能就向集群提议的值达成一致。
manager节点数 | 选举票数 | 允许manager不可用个数 |
---|---|---|
1 | 1 | 0 |
2 | 2 | 0 |
3 | 2 | 1 |
4 | 3 | 1 |
5 | 3 | 2 |
6 | 4 | 2 |
7 | 4 | 3 |
8 | 5 | 3 |
9 | 5 | 4 |
二、集群管理
2.1、创建集群
- 不包含在任何Swarm中的Docker节点,该Docker节点被称为运行于单引擎(Single-Engine)模式,一旦加入Swarm集群,则切换为Swarm模式。
- docker swarm init 会通知Docker来初始化一个新的Swarm,并且将自身设置为第一个管理节点。同时也会使该节点开启Swarm模式。
- –advertise-addr IP:2377 指定其他节点用来连接到当前管理节点的IP和端口,这一指令是可选的,当节点有多个IP时,可以指定其中一个。
- –listen-addr 指定用于承载Swarm流量的IP和端口,其设置通常与–advertise-addr相匹配,但是当节点上有多个IP的时候,可用于指定具体某个IP。
- –autolock 启用管理器自动锁定(需要解锁密钥才能启动已停止的管理器)。
- –force-new-cluster 强制从当前状态创建新群集。
docker swarm init
2.2、将节点加入集群
(1)生成join-token。
# 生成work节点 join-token
docker swarm join-token worker
# 生成manager节点 join-token
docker swarm join-token manager
示例:
fly@fly:~/wokspace$ docker swarm join-token worker
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-4zxv2c1ntyjoum1m3x8u6juej6kciexc05f30j9vsvr0hoieg4-19o9myylkb7bg1fb1jqcr1xcf 192.168.11.72:2377
(2)加入集群。
# 此命令为 join-token 命令执行结果,在相应的节点执行该结果即可加入到集群
docker swarm join --token SWMTKN-1-4zxv2c1ntyjoum1m3x8u6juej6kciexc05f30j9vsvr0hoieg4-19o9myylkb7bg1fb1jqcr1xcf 192.168.11.72:2377
2.3、查看集群状态。
docker info
2.4、将节点从集群中移除
(1)将节点从集群中移除 (只能移除worker节点)。
docker swarm leave
(2)将节点从集群中强制移除(包括manager节点)。
docker swarm leave -f
2.5、更新集群
更新集群的部分参数
docker swarm update --autolock=false
2.6、锁定/解锁集群
- 重启一个旧的管理节点或者进行备份恢复可能对集群造成影响,一个旧的管理节点重新接入Swarm会自动解密并获得Raft数据库中长时间序列的访问权,这会带来安全隐患。进行备份恢复可能会抹掉最新的Swarm配置。
- 为了规避上述问题,Docker提供自动锁机制来锁定Swarm,这会强制要求重启的管理节点在提供一个集群解锁码之后才有权重新接入集群(也可以防止原来的主节点宕机后重新接入集群,和当前主节点一起成为双主,双主也是一种脑裂问题)。
(1)设置为自动锁定集群。
# 设置为自动锁定集群
docker swarm update --autolock=true
(2)当集群设置为 --autolock后,可以通过该命令查询解锁集群的秘钥。
# 当集群设置为 --autolock后,可以通过该命令查询解锁集群的秘钥
# 该节点必须为集群有效的管理节点
docker swarm unlock-key
(3)重启管理节点,集群将被自动锁定。
# 重启管理节点,集群将被自动锁定
service docker restart
(4)重启后的管理节点必须提供解锁码后才能重新接入集群。
# 重启后的管理节点必须提供解锁码后才能重新接入集群
docker swarm unlock
三、节点管理
# 查看参数帮助
docker node -h
# 命令说明:
# 降级节点
demote Demote one or more nodes from manager in the swarm
# 查看节点详情
inspect Display detailed information on one or more nodes
# 查看所有节点
ls List nodes in the swarm
# 升级节点
promote Promote one or more nodes to manager in the swarm
# 查看节点上运行的任务,默认当前节点
ps List tasks running on one or more nodes, defaults to current node
# 删除节点
rm Remove one or more nodes from the swarm
# 更新节点
update Update a node
- demote:降级节点。
- inspect:查看节点详情。
- ls:查看所有节点。
- promote:升级节点。
- ps:查看节点上运行的任务,默认当前节点。
- rm:删除节点。
- update:更新节点。
(1) 查看集群节点列表。
docker node ls
fly@fly:~/wokspace$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
re12imh3gr7d1dudrw1gkm9f7 * fly Ready Active Leader 20.10.12
(2)升级或降级节点。
# 降级一个或多个节点
docker node demote <NODE>
# 通过修改单个节点的role属性,来降级节点
docker node update --role worker <NODE>
# 升级一个或多个节点
docker node promote <NODE>
# 通过修改单个节点的role属性,来升级节点
docker node update --role manager <NODE>
(3)更改节点状态。
# 更改节点状态
docker node update --availability active|pause|drain <NODE>
# active: 正常
# pause:挂起
# drain:排除
- 正常节点,可正常部署应用。
- 挂起节点,已经部署的应用不会发生变化,新应用将不会部署到该节点。
- 排除节点,已经部署在该节点的应用会被调度到其他节点。
(4)删除节点。
# 只能删除已关闭服务的工作节点
docker node rm <node>
# 只能强制删除工作节点
docker node rm -f <node>
注意:管理节点的删除只能先将管理节点降级为工作节点,再执行删除动作。
# 停止docker server
sudo service docker stop
四、服务部署
4.1、准备
(1)拉取代码,获取tag。
# 拉取代码
git clone https://gitee.com/long-xu/helloworld.git
# 进入代码目录
cd helloworld
# fetch
git fetch origin
(2)镜像制作。
# 切换到1.0.0 tag
git checkout 1.0.0
# 构建1.0.0镜像
docker build -f Dockerfile -t hello:1.0.0 .
# 切换到1.0.1 tag
git checkout 1.0.1
# 构建1.0.1镜像
docker build -f Dockerfile -t hello:1.0.1 .
(3)将镜像推送到仓库(这里使用公共仓库作为演示)。
# 登录注册中心
docker login
(4)为镜像重新打tag(格式:用户名/仓库名:tag)。
docker tag hello:1.0.0 long-xu/hello:1.0.0
docker push long-xu/hello:1.0.0
docker tag hello:1.0.1 long-xu/hello:1.0.1
docker push long-xu/hello:1.0.1
(5) 登录https://hub.docker.com/ 查看镜像情况。
4.2、服务管理
docker service -h
4.2.1、常用命令
# 创建一个服务
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
4.2.2、在集群上部署应用
(1)部署一个副本数量。
docker service create --name myhello --publish published=81,target=80 --replicas 3 long-xu/hello:1.0.0
# 若是采用私有注册中心请加上 --with-registry-auth 选项
(2)查看服务下的任务(容器)。
docker service ps myhello
(3) 查看节点下的任务(容器)。
docker node ps <NODE>
(4)访问集群中任意节点(包括没有运行任务的节点)对应的端口号均能访问到应用程序,swarm为集群实现了负载均衡。
curl http://localhost:81/ping
(5)查看service详细信息。
docker service inspect myhello
(6)查看service日志。
docker service logs myhello
(7)伸缩服务。
docker service scale myhello=5
(8) 修改节点状态,查看任务部署情况。
docker node update --availability active|pause|drain <NODE>
4.2.3、在集群上部署一个带更新策略和回滚策略的应用
(1)部署应用。
docker service create \\
--name myhello1 \\
--publish published=82,target=80 \\
--replicas 20 \\
--update-delay 5s \\
--update-parallelism 2 \\
--update-failure-action continue \\
--rollback-parallelism 2 \\
--rollback-monitor 10s \\
--rollback-max-failure-ratio 0.2 \\
long-xu/hello:1.0.0
# 若是采用私有注册中心请加上 --with-registry-auth 选项
#--update-delay 5s :每个容器依次更新,间隔5s
# --update-parallelism 2 : 每次允许两个服务一起更新
#--update-failure-action continue : 更新失败后的动作是继续
# --rollback-parallelism 2 : 回滚时允许两个一起
# --rollback-monitor 10s :回滚监控时间10s
# --rollback-max-failure-ratio 0.2 : 回滚失败率20%
(2) 检查部署后的应用设置项是否都有被成功设置。
# 查看并打印友好的详细信息
docker service inspect --pretty myhello1
注意:查看详细信息时,详细信息中时间单位为ns(纳秒)。友好格式下,时间单位为(s)。
(3)更新未设置成功的项。
docker service update --update-delay 5s --rollback-monitor 10s myhello1
(4)访问服务。
curl http://localhost:82/ping
curl http://localhost:82/ping/v1.0.1
4.2.4、更新服务
(1)启动更新。
docker service update --image long-xu/hello:1.0.1 myhello1
# 若是采用私有注册中心请加上 --with-registry-auth 选项
(2)访问服务。
curl http://localhost:82/ping
curl http://localhost:82/ping/v1.0.1
4.2.5、回滚服务
(1)启动回滚(策略是失败后回滚,目前没有失败的情况,我们手动回滚)。
docker service update --rollback myhello1
五、结合docker-compose.yml部署
5.1、部署应用
(1)常用命令:
# 部署或更新 stack
deploy Deploy a new stack or update an existing stack
# 查看 stack 列表
ls List stacks
# 查看 stack 的任务列表
ps List the tasks in the stack
# 删除 stack
rm Remove one or more stacks
# 查看stack 中的服务列表
services List the services in the stack
(2)docker-compose.yml 文件。
version: "3.7"
services:
myhello2:
image: long-xu/hello:1.0.0
ports:
- "83:80"
depends_on:
- redis
deploy:
mode: replicated
replicas: 20
endpoint_mode: vip
rollback_config:
parallelism: 2
delay: 10s
monitor: 10s
max_failure_ratio: 0.2
update_config:
parallelism: 2
delay: 5s
failure_action: continue
redis:
image: redis:alpine
deploy:
mode: replicated
replicas: 6
endpoint_mode: dnsrr
labels:
description: "This redis service label"
resources:
limits:
cpus: '0.50'
memory: 50M
reservations:
cpus: '0.25'
memory: 20M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
(3)部署stack。
docker stack deploy -c docker-compose.yml mystack
(4)查看服务详情。
# 查看并打印友好的详细信息
docker service inspect --pretty mystack_myhello2
docker service inspect --pretty mystack_redis
5.2、语法说明
注意:仅支持 V3.4 及更高版本。
(1)endpoint_mode:访问集群服务的方式。
endpoint_mode: vip
# Docker 集群服务一个对外的虚拟 ip。所有的请求都会通过这个虚拟 ip 到达集群服务内部的机器。
endpoint_mode: dnsrr
# DNS 轮询(DNSRR)。所有的请求会自动轮询获取到集群 ip 列表中的一个 ip 地址。
(2)labels:在服务上设置标签。可以用容器上的 labels(跟 deploy 同级的配置) 覆盖 deploy 下的labels。
(3)mode:指定服务提供的模式。
- replicated:复制服务,复制指定服务到集群的机器上。
- global:全局服务,服务将部署至集群的每个节点。
- replicas:mode 为 replicated 时,需要使用此参数配置具体运行的节点数量。
(4)resources:配置服务器资源使用的限制,例如上例子,配置 redis 集群运行需要的 cpu 的百分比 和 内存的占用。避免占用资源过高出现异常。
(5)restart_policy:配置如何在退出容器时重新启动容器。
- condition:可选 none,on-failure 或者 any(默认值:any)。
- delay:设置多久之后重启(默认值:0)。
- max_attempts:尝试重新启动容器的次数,超出次数,则不再尝试(默认值:一直重试)。
- window:设置容器重启超时时间(默认值:0)。
(6)rollback_config:配置在更新失败的情况下应如何回滚服务。
- parallelism:一次要回滚的容器数。如果设置为0,则所有容器将同时回滚。
- delay:每个容器组回滚之间等待的时间(默认为0s)。
- failure_action:如果回滚失败,该怎么办。其中一个 continue 或者 pause(默认pause)。
- monitor:每个容器更新后,持续观察是否失败了的时间 (ns|us|ms|s|m|h)(默认为0s)。
- max_failure_ratio:在回滚期间可以容忍的故障率(默认为0)。
- order:回滚期间的操作顺序。其中一个 stop-first(串行回滚),或者 start-first(并行回滚),默认 stop-first 。
(7)update_config:配置应如何更新服务,对于配置滚动更新很有用。
- parallelism:一次更新的容器数。
- delay:在更新一组容器之间等待的时间。
- failure_action:如果更新失败,该怎么办。其中一个 continue,rollback 或者pause (默认:pause)。
- monitor:每个容器更新后,持续观察是否失败了的时间 (ns|us|ms|s|m|h)(默认为0s)。
- max_failure_ratio:在更新过程中可以容忍的故障率。
- order:回滚期间的操作顺序。其中一个 stop-first(串行回滚),或者 start-first(并行回滚),默认stop-first。
云原生时代必须具备的核心技能之Docker高级篇(Swarm)
解决集群问题 k8s
官网地址:https://docs.docker.com/engine/swarm/
1.Swarm介绍
Swarm是Docker官方提供的一款集群管理工具,其主要作用是把若干台Docker主机抽象为一个整体,并且通过一个入口统一管理这些Docker主机上的各种Docker资源。Swarm和Kubernetes比较类似,但是更加轻,具有的功能也较kubernetes更少一些
管理节点
管理节点处理集群管理任务:
- 维护集群状态
- 调度服务
- 服务群模式HTTP API 端点
使用Raft
实现,管理器维护整个 swarm 及其上运行的所有服务的一致内部状态。出于测试目的,可以使用单个管理器运行 swarm。如果单管理器群中的管理器出现故障,您的服务会继续运行,但您需要创建一个新集群来恢复。
为了利用 swarm 模式的容错特性,Docker 建议您根据组织的高可用性要求实现奇数个节点。当您有多个管理器时,您可以在不停机的情况下从管理器节点的故障中恢复。
- 三个管理器的群体最多可以容忍一个管理器的损失。
- 一个五管理器群可以容忍最大同时丢失两个管理器节点。
- 一个
N
管理器集群最多可以容忍管理器的丢失(N-1)/2
。 - Docker 建议一个群最多有七个管理器节点。
工作节点
工作节点也是 Docker 引擎的实例,其唯一目的是执行容器。Worker 节点不参与 Raft 分布式状态,不做出调度决策,也不为 swarm 模式 HTTP API 提供服务。
您可以创建一个由一个管理器节点组成的群,但是如果没有至少一个管理器节点,您就不能拥有一个工作节点。默认情况下,所有经理也是工人。在单个管理器节点集群中,您可以运行类似命令docker service create
,调度程序将所有任务放在本地引擎上。
为防止调度程序将任务放置在多节点群中的管理器节点上,请将管理器节点的可用性设置为Drain
。调度器在Drain
mode 中优雅地停止节点上的任务并调度Active
节点上的任务 。调度程序不会将新任务分配给具有Drain
可用性的节点。
2.Swarm集群搭建
环境准备
准备3个节点,通过vagrant新增加两个节点
需要单独指定hostname
config.vm.hostname="work01-node"
还有就是每个节点需要具备Docker环境
集群环境搭建
1> 创建manager节点
进入manager节点,manager node也可以作为worker node提供服务
docker swarm init -advertise 192.168.56.10
注意观察日志,拿到worker node加入manager node的信息
docker swarm join --token SWMTKN-1-0a5ph4nehwdm9wzcmlbj2ckqqso38pkd238rprzwcoawabxtdq-arcpra6yzltedpafk3qyvv0y3 192.168.56.10:2377
2>进入两个Worker
docker swarm join --token SWMTKN-1-0a5ph4nehwdm9wzcmlbj2ckqqso38pkd238rprzwcoawabxtdq-arcpra6yzltedpafk3qyvv0y3 192.168.56.10:2377
3>进入manager node 查看集群情况
docker node ls
4>node类型转换
可以将worker提升成manager,从而保证manager的高可用
docker node promote worker01-node
docker node promote worker02-node
#降级可以用demote
docker node demote worker01-node
在线Swarm演示:http://labs.play-with-docker.com 通过Dock Hub 的账号密码登录即可,有效会话4个小时
3.Raft一致性协议
Raft一致性协议:保证manager节点半数存活集群环境可用
一主两从
还是参考上面的案例直接操作
我们停掉manager节点,那么整个集群环境是不可用的
我们将一个work节点提升等级
二主一从
除了上面的promote
提升到 主的案例意外,我们还可用从新来搭集群处理
我们可以在init后直接在 manager节点执行如下命令
docker swarm join-token manager
三主0从
停止其中一个整个集群还是可用
但是停止掉两个后就不可用使用了
4.Service
(1)创建一个tomcat的service
docker service create --name my-tomcat tomcat
(2)查看当前swarm的service
docker service ls
(3)查看service的启动日志
docker service logs my-tomcat
(4)查看service的详情
docker service inspect my-tomcat
(5)查看my-tomcat运行在哪个node上
docker service ps my-tomcat
日志
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
u6o4mz4tj396 my-tomcat.1 tomcat:latest worker01-node Running Running 3 minutes ago
(6)水平扩展service
docker service scale my-tomcat=3
docker service ls
docker service ps my-tomcat
日志
:可以发现,其他node上都运行了一个my-tomcat的service
[root@manager-node ~]# docker service ps my-tomcat
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
u6o4mz4tj396 my-tomcat.1 tomcat:latest worker01-node Running Running 8 minutes ago
v505wdu3fxqo my-tomcat.2 tomcat:latest manager-node Running Running 46 seconds ago
wpbsilp62sc0 my-tomcat.3 tomcat:latest worker02-node Running Running 49 seconds ago
此时到worker01-node上:docker ps,可以发现container的name和service名称不一样,这点要知道
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bc4b9bb097b8 tomcat:latest "catalina.sh run" 10 minutes ago Up 10 minutes 8080/tcp my-tomcat.1.u6o4mz4tj3969a1p3mquagxok
(7)如果某个node上的my-tomcat挂掉了,这时候会自动扩展
[worker01-node]
docker rm -f containerid
[manager-node]
docker service ls
docker service ps my-tomcat
(8)删除service
docker service rm my-tomcat
5.overlay
Overlay 在网络技术领域,指的是一种网络架构上叠加的虚拟化技术模式,其大体框架是对基础网络不进行大规模修改的条件下,实现应用在网络上的承载,并能与其它网络业务分离,并且以基于IP的基础网络技术为主
VXLAN(Virtual eXtensible LAN)技术是当前最为主流的Overlay标准
6.WordPress实战
1> 创建MySQL service
docker service create --name mysql --mount type=volume,source=v1,destination=/var/lib/mysql --env MYSQL_ROOT_PASSWORD=examplepass --env MYSQL_DATABASE=db_wordpress --network my-overlay-net mysql:5.6
2>创建WordPress的Service
docker service create --name wordpress --env WORDPRESS_DB_USER=root --env WORDPRESS_DB_PASSWORD=examplepass --env WORDPRESS_DB_HOST=mysql:3306 --env WORDPRESS_DB_NAME=db_wordpress -p 8080:80 --network my-overlay-net wordpress
3>访问测试
4>查看my-overlay-net
搞定~
以上是关于云原生Swarm解决docker server的集群化管理和部署的主要内容,如果未能解决你的问题,请参考以下文章
云原生第十篇--Docker主机集群化方案 Docker Swarm
[云原生专题-17]:容器 - docker自带的集群管理工具swarm - 简介原理架构