Docker Swarm 学习笔记

若如初见. 提交于 2020-02-02 21:47:37
Swarm有两个核心组件:
  • 企业级的Docker安全集群
  1. Swarm 将一个或多个Docker节点组织起来,使用户能够以集群方式管理他们,节点分为管理节点(Manager)和工作节点(Worker);
  2. 多个Docker节点中,管理节点可以有多个,用于HA,只有一个节点为Leader,剩下的为Reachable,工作节点的status展示为空;
  3. Swarm 的配置和状态信息,保存在管理节点的etcd数据库中,如果有多个管理节点,那么etcd就是分布式的,即使一个节点挂了,新的管理节点仍然能获取到etcd中的数据。
  • 微服务应用编排引擎
  1. 将应用定义在声明式配置文件中,就能使用原生的Docker命令完成部署,滚动升级,回滚,扩缩容;
  2. Swarm还可以部署管理 Kubernetes;
Swarm集群搭建

要求:

  1. 每个节点都需要安装Docker
  2. 能够和Swarm 的其它节点通信
  3. 开放端口
    2377/tcp:用于客户端和 Swarm 进行安全通信
    7946/tcp7946/udp:用于控制面gossip分发
    4789/udp:用于基于VXLAN的覆盖网络

流程:

  1. 初始化第一个管理节点
  2. 加入额外的管理节点
  3. 加入工作节点
  • 初始化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
    加入MangerWorker的唯一区别就在于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
  1. 部署奇数个管理节点(偶数节点会造成脑裂)
  2. 不要部署太多管理节点(不要超过7个,一般用3个或5个)
  3. 不管有几个Manager,永远只有一个是活动状态(主节点),只有主节点可以变更配置,发送任务到工作节点,如果其它Manager收到了Swarm命令,也会转发到主节点
  4. 生产环境的Swarm 不要部署到多个不同的公有云(AWS,阿里云,华为云等),主要是为了确保节点间有高速可靠的网络连接
  • Swarm锁定
    锁定之后的Swarm节点,重启以后,必须输入一个集群解锁码才能重新接入集群
  1. 在创建节点时,传入--autolock=true可以直接启用锁
  2. 已存在的节点,通过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 ~]# 

可以看到,创建服务做了以下几件事:

  1. ManagerWorker都拉取了一个镜像至本地(Docker默认用的国外的镜像源,如果拉取不了,可以在/etc/docker/daemon.json中配置一个国内的镜像源)
  2. 启动了一个my-nginx的服务,并且将节点的8080端口映射到了服务内部的80端口
  3. 启动了3个副本,ManagerWorker中都有运行的副本

如果想要查看服务更详细的信息,可以使用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-filejournald两种日志
如果是第三方日志驱动,需要在/etc/docker/daemon.json进行配置
例如syslog作为日志驱动

{
	"log-driver": "syslog"
}

也可以通过在执行docker service create时传入--logdriver--log-opts来强制指定一种日志驱动类型,会覆盖daemon.json中的配置。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!