Swarm有两个核心组件:
- 企业级的Docker安全集群
- Swarm 将一个或多个Docker节点组织起来,使用户能够以集群方式管理他们,节点分为管理节点(
Manager
)和工作节点(Worker
); - 多个Docker节点中,管理节点可以有多个,用于HA,只有一个节点为
Leader
,剩下的为Reachable
,工作节点的status展示为空; - Swarm 的配置和状态信息,保存在管理节点的etcd数据库中,如果有多个管理节点,那么etcd就是分布式的,即使一个节点挂了,新的管理节点仍然能获取到etcd中的数据。
- 微服务应用编排引擎
- 将应用定义在声明式配置文件中,就能使用原生的Docker命令完成部署,滚动升级,回滚,扩缩容;
- Swarm还可以部署管理 Kubernetes;
Swarm集群搭建
要求:
- 每个节点都需要安装Docker
- 能够和Swarm 的其它节点通信
- 开放端口
2377/tcp
:用于客户端和 Swarm 进行安全通信7946/tcp
与7946/udp
:用于控制面gossip分发4789/udp
:用于基于VXLAN的覆盖网络
流程:
- 初始化第一个管理节点
- 加入额外的管理节点
- 加入工作节点
- 初始化Swarm
不包含在任何Swarm中的Docker节点,称为运行于单引擎模式
,一旦加入Swarm集群,则切换为Swarm模式
[root@localhost ~]# docker swarm init --advertise-addr 192.168.124.17:2377 --listen-addr 192.168.124.17:2377
Swarm initialized: current node (z9zmm6qez6xzh31f027v0ntt3) is now a manager.
<...>
[root@localhost ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
z9zmm6qez6xzh31f027v0ntt3 * localhost.localdomain Ready Active Leader 19.03.5
docker swarm init
:通知Docker初始化一个新的Swarm,并将自身设置为第一个管理节点。--advertise-addr
:指定其它节点用来连接到当前节点的IP和端口,该属性可选(但建议加上),如果节点上有多个IP,可以用来指定使用哪个,也可以指定一个节点上没有的IP,比如负载均衡的IP。--listen-addr
:用于承载Swarm 流量的IP和端口,通常设置为和-advertise-addr匹配
- 查看如何加入Swarm
加入Manger
或Worker
的唯一区别就在于Token的不同,因此要妥善保管Token
[root@localhost ~]# docker swarm join-token worker
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-1p4qmhdf9gmn28nrj0gqfggjr217d7r7ztbywn4ia8rgieinby-686w21vz5a9un2deq0cnrte6j 192.168.124.17:2377
[root@localhost ~]# docker swarm join-token manager
To add a manager to this swarm, run the following command:
docker swarm join --token SWMTKN-1-1p4qmhdf9gmn28nrj0gqfggjr217d7r7ztbywn4ia8rgieinby-0hqcq9lhffn7xr6ekpwt4oam4 192.168.124.17:2377
[root@localhost ~]#
- 加入一个工作节点至Swarm
切换到工作节点的Docker主机,执行以下命令
[root@localhost ~]# docker swarm join --token SWMTKN-1-1p4qmhdf9gmn28nrj0gqfggjr217d7r7ztbywn4ia8rgieinby-686w21vz5a9un2deq0cnrte6j 192.168.124.17:2377 --advertise-addr 192.168.124.16:2377 --listen-addr 192.168.124.16:2377
This node joined a swarm as a worker.
[root@localhost ~]#
[root@localhost ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
p0ub2rkeyx3xg1du1q4jfst98 localhost.localdomain Ready Active 19.03.5
z9zmm6qez6xzh31f027v0ntt3 * localhost.localdomain Ready Active Leader 19.03.5
[root@localhost ~]#
- Swarm的HA
- 部署奇数个管理节点(偶数节点会造成脑裂)
- 不要部署太多管理节点(不要超过7个,一般用3个或5个)
- 不管有几个
Manager
,永远只有一个是活动状态(主节点
),只有主节点可以变更配置,发送任务到工作节点,如果其它Manager
收到了Swarm命令,也会转发到主节点
去 - 生产环境的Swarm 不要部署到多个不同的公有云(AWS,阿里云,华为云等),主要是为了确保节点间有高速可靠的网络连接
- Swarm锁定
锁定之后的Swarm节点,重启以后,必须输入一个集群解锁码才能重新接入集群
- 在创建节点时,传入
--autolock=true
可以直接启用锁 - 已存在的节点,通过
docker swarm update --autolock=true
来启用锁
解锁码必须妥善保管在安全的地方
Swarm 服务
- 创建服务
[root@huanzi-001 ~]# docker service create --name my-nginx -p 8080:80 --replicas 3 nginx:latest
kj3ad5kxq4jm66hrj5i0vn78e
overall progress: 3 out of 3 tasks
1/3: running [==================================================>]
2/3: running [==================================================>]
3/3: running [==================================================>]
verify: Service converged
[root@huanzi-001 ~]#
- 服务状态查看
[root@huanzi-001 ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx <none> 5ad3bd0e67a9 11 days ago 127MB
[root@huanzi-001 ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
kj3ad5kxq4jm my-nginx replicated 3/3 nginx:latest *:8080->80/tcp
[root@huanzi-001 ~]# docker service ps my-nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
l15nmdtxv88w my-nginx.1 nginx:latest huanzi-001 Running Running 2 minutes ago
23es6uzc4pbu my-nginx.2 nginx:latest huanzi-002 Running Running 2 minutes ago
q4urcrionw9j my-nginx.3 nginx:latest huanzi-002 Running Running 2 minutes ago
[root@huanzi-001 ~]
[root@huanzi-002 ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx <none> 5ad3bd0e67a9 11 days ago 127MB
[root@huanzi-002 ~]#
可以看到,创建服务做了以下几件事:
- 在
Manager
和Worker
都拉取了一个镜像至本地(Docker默认用的国外的镜像源,如果拉取不了,可以在/etc/docker/daemon.json中配置一个国内的镜像源) - 启动了一个
my-nginx
的服务,并且将节点的8080端口映射到了服务内部的80端口 - 启动了3个副本,
Manager
和Worker
中都有运行的副本
如果想要查看服务更详细的信息,可以使用docker service inspect --pretty my-nginx
查看
-
启动状态验证
可以看到,不管是访问Manager
还是Worker
的8080端口,最终都会访问到nginx -
副本模式和全局模式
这里的模式指的是服务的复制模式;
副本模式:为默认
的模式,会尽可能的将各个副本均匀的分布
在整个集群中;
全局模式:每个节点上仅运行一个
副本,使用docker service create
传入--mode globle
部署全局服务 -
服务的扩缩容
使用docker service scale
进行扩缩容,直接指定副本数量扩缩容
[root@huanzi-001 ~]# docker service scale my-nginx=5
my-nginx scaled to 5
overall progress: 5 out of 5 tasks
1/5: running [==================================================>]
2/5: starting [==============================================> ]
3/5: starting [==============================================> ]
4/5: running [==================================================>]
5/5: running [==================================================>]
verify: Service converged
[root@huanzi-001 ~]# docker service ps my-nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
l15nmdtxv88w my-nginx.1 nginx:latest huanzi-001 Running Running 18 minutes ago
23es6uzc4pbu my-nginx.2 nginx:latest huanzi-002 Running Running 18 minutes ago
q4urcrionw9j my-nginx.3 nginx:latest huanzi-002 Running Running 18 minutes ago
pl42mguvt33k my-nginx.4 nginx:latest huanzi-001 Running Running 8 seconds ago
dcd9uis4vnc3 my-nginx.5 nginx:latest huanzi-001 Running Running 8 seconds ago
[root@huanzi-001 ~]#
-
删除服务
使用docker service rm <service_name>
删除,删除所有副本时不会进行确认,请谨慎操作 -
服务滚动升级
[root@huanzi-001 ~]# docker service update --image nginx:latest --update-parallelism 2 --update-delay 10s my-nginx
my-nginx
overall progress: 5 out of 5 tasks
1/5: running [==================================================>]
2/5: running [==================================================>]
3/5: running [==================================================>]
4/5: running [==================================================>]
5/5: running [==================================================>]
verify: Service converged
[root@huanzi-001 ~]#
--image nginx:latest
:指定用什么镜像更新--update-parallelism
:一次更新2个副本--update-delay 10s
:更新之间有10s的延迟
等待一段时间后,服务会全部更新完毕。
故障排查
日志查看docker service logs <service name>
,可以查看json-file
和journald
两种日志
如果是第三方日志驱动,需要在/etc/docker/daemon.json
进行配置
例如syslog作为日志驱动
{
"log-driver": "syslog"
}
也可以通过在执行docker service create
时传入--logdriver
和--log-opts
来强制指定一种日志驱动类型,会覆盖daemon.json中的配置。
来源:CSDN
作者:欢子不唱歌
链接:https://blog.csdn.net/weixin_41092791/article/details/104125446