Docker Swarm Mode 入门实践

本文来源

翻译并总结官方文档,添加自定义示例,参考自Docker 19.03版本官方文档

未来可能归档为:https://docs.docker.com/v19.03/

2020.01.03为https://docs.docker.com/engine/swarm/

本文目标

本文主要演示创建一个小规模的Swarm集群,包含一个管理节点与两个工作节点,概念可以参考https://www.cnblogs.com/hellxz/p/12134386.html

  • 创建Docker Swarm集群
  • 添加节点
  • 部署应用服务
  • 管理Swarm集群

环境说明

  • 三台安装Docker的Linux虚拟机:本文用Docker Machine创建虚拟机
  • Docker版本:18.09.7,理论上1.12版本以后均可
  • 三台虚拟机网络互通

Docker Machine安装参考我的上一篇文章,安装Docker Machine

虚拟机准备

实体机安装Linux或Mac,跳过此节

本文通过一台Linux虚拟机中创建三个虚拟机节点来操作的,虚拟机内存可以开大些,另外需要配置开启Intel VT-x/EPT或AMD-RVI(V)

另外,由于我们要做的实验是在虚拟机下的再创建虚拟机,外部虚拟机与虚拟机内构成内网,在没有设置代理的情况下,我们无法直接通过浏览器直接访问

创建 Swarm 集群(Create a swarm)

创建一个管理节点的虚拟机

$ docker-machine create -d virtualbox manager

连接创建的管理节点虚拟机

$ docker-machine ssh manager1

出现上图已经进入虚拟机了

初始化Swarm集群

$ docker swarm init --advertise-addr 192.168.99.100

初始化完成,在多网卡的情况下,必须使用--advertise-addr指定IP,其它主机必须可以访问此ip,输出中包含新节点加入此节点的命令,我们只需要复制此命令到其它节点上执行

执行docker swarm init的节点自动成为管理节点,节点的ip是ssh到节点后ifconfig查到的

添加节点命令要先复制出来,一会添加节点会用,如果没复制也不要紧

在manager节点输入docker swarm join-token 角色 就能提示token了,上边复制的默认是worker角色的命令

1578032218348

输入docker info查看当前节点的Docker Swarm Mode已经处于激活状态了

执行docker node ls查看当前Swarm集群中节点的情况

*指示当前登录的节点

输出exit退出当前登录的主机

向Swarm添加节点(Add nodes to the swarm)

创建第一个工作节点并ssh连接到这个节点上

$ docker-machine create -d virtualbox worker1
$ docker-machine ssh worker1

执行刚才复制的docker swarm join-token命令,忘了就先去manager节点下执行docker swarm join-token worker来查看命令

$ docker swarm join --token SWMTKN-1-0kr7tkx9ku4rcrl1lny1o8chg9xl24h4nexmz1ctfwz43425uq-egecegeyfaet0volcvo15zia8 192.168.99.100:2377

This node joined a swarm as a worker.

接着创建个worker2,操作不再复述了

查看集群节点情况

连接manager节点,执行命令查看集群状态

$ docker node ls

docker node ls命令仅可以在管理节点使用

部署服务到Swarm集群(Deployed a service)

部署服务只需要使用docker service create加正常的docker命令,还可以指定创建几个备份实例,这里部署2个Nginx

$ docker service create --replicas 2 --name nginx -p 80:80 nginx:mainline-alpine

docker service create命令主要参数:

  • --name - 用来指定服务名,部署服务的容器名使用这个名称作为前缀
  • --replicas - 设置负载实例数

其余参数请自行参考 docker service create --help文档

此命名仅能在manager节点执行

Docker Swarm Mode简介与核心概念 一文中,我们有谈过:服务可以运行在Manager节点上,也可以运行在Worker节点上

部署服务的输出并没有提示具体将服务部署到哪个节点上,接下来我们看看节点情况

查看服务

使用docker service ls查看服务列表,查看具体服务部署在哪个节点使用docker service ps 服务名

如图,我们的服务一个部署到了manger节点上,一个部署在worker1节点上

检查部署在Swarm集群中的服务(Inspect the service)

通过docker service inspect命令检查服务的详细信息,使用--pretty使输出更易读

$ docker service inspect --pretty nginx

除了这种简单的方法外就是普通的办法——去部署的节点上docker ps 🐻

服务伸缩(Scale the service)

使用docker service scale命令来对服务进行扩大或缩小实例数

当业务压力攀升时,我们需要对服务进行横向扩容,添加更多的实例,就可以像下边这么做

$ docker service scale nginx=5

=左边是服务名,右边是负载数

业务压力下降时只需调小负载数的值

删除服务(Delete the service)

使用docker service rm命名来删除服务,包含服务包含的所有Task都会被删除

$ docker service rm nginx

滚动升级服务(Apply rolling updates)

一般升级服务的方式是停服再启动新的服务这种方式,有些人习惯将原服务删除,再部署新的,当新的服务有问题,想回退上一版本时就傻眼了

在Docker部署服务的情况下,我们可以自己手动docker stop容器再创建新的部署新的容器,这样虽然看起来没问题,但是手动操作一方面是很大重复劳动,另一方面人工也容易误操作

在这种情况下,Docker Swarm为我们准备了docker service update命令来更新服务,一方面简单更新操作,另一方面提供回滚的命令,这个稍后会提及

关于服务更新的配置有两种:

  • 一种是在初次部署服务时就指定的配置,比如在docker service create时添加参数--update-delay+时延来设置每个服务的Task间的延迟,--update-parallelism设置更新时最大并行部署数值,--update-failure-action标记更新失败要做的动作 等
  • 另一种就是docker service update时指定参数,上边举例的三个参数此命令也可以使用

以上提到的参数在例子中就不写了

刚才已经把nginx的服务干掉了,我们再创建部署一个nginx服务

$ docker service create --replicas 2 --name nginx -p 80:80 nginx:mainline-alpine

查看下当前服务镜像,一会我们通过命令修改镜像版本

我们更新下nginx服务的镜像版本,格式为docker service update --image 镜像 服务名

$ docker service update --image nginx:alpine nginx

再查看下nginx服务

我们发现镜像的版本已经改变了

使用docker service ps nginx查看服务情况

我们发现之前版本的Task还有保留,只是状态为Shutdown

保留的Task可以用于后续如果服务不正常,回滚版本

docker service update更多操作请参考--help文档

服务回退

使用docker service rollback命令对服务进行一键回退

$ docker service rollback nginx

回退成功,如上图我还执行的查看服务命令,发现之前升级与回退的版本都还在,层次也比较清晰

排除节点(Drain a node on the swarm)

当我们部署服务的时候,Manager节点会将Task分发到所有状态为ACTIVE 的节点上,执行Task

当需要维护一个节点的时候,你一定不会希望还有Task被分配到此节点上,Swarm的设计者也考虑到这点,除了ACTIVE状态外,还有一个DRAIN 状态用来标识当前节点(Node)不再提供服务,你也别给我这发Task了

使用docker node update --availability drain 节点名来完成此功能

$ docker node update --availability drain worker1

上图先是查看了当前nginx服务部署在worker1与manager节点上,接着下线了worker1

我们发现Manger将原来部署在worker1的节点下线,重新在worker2节点上部署了nginx的task

可能上图中对node的状态描述不直观,执行docker node ls或许更清楚些😄

上线与之相反,设置drainactive即可,docker node update --availability active 节点名

使用swarm模式路由网格(Use swarm mode routing mesh)

简单来说是使用Swarm模式的网络路由,将服务指定端口暴露出去提供服务

有点类似于-p 8080:80这种写法,按官网的说法是:分隔的写法是旧版本的写法😙 ,因为新版本更灵活易读

看了下文档,把我认为最关键的先抛出来

暴露端口(Publish a port for a service)

Swarm中暴露接口有两种情况,一种是创建服务时暴露,另一种是服务已经存在,需要暴露

创建服务时暴露端口

$ docker service create \
  --name <SERVICE-NAME> \
  --publish published=<PUBLISHED-PORT>,target=<CONTAINER-PORT> \
  <IMAGE>

更新服务时暴露接口

$ docker service update \
  --publish-add published=<PUBLISHED-PORT>,target=<CONTAINER-PORT> \
  <IMAGE>

分流路由(Bypass the routing mesh)

官方文档这块没看明白,大意是使用节点的host模式网络绕过路由网格

$ docker service create --name dns-cache \
  --publish published=53,target=53,protocol=udp,mode=host \
  --mode global \
  dns-cache

TODO: 待完善,如您有清晰的概念,还请留言解惑,在此先行感谢

配置外部负载均衡器(Configure an external load balancer)

相信我贴一张图就明白了,就是配置个负载均衡配置到Node节点的特定端口上,此端口相对于容器暴露的端口作映射

本文是官网翻译文档,如有错误与不准确处,希望读者可以留言与本人探讨

posted @ 2020-01-03 18:48  东北小狐狸  阅读(1193)  评论(0编辑  收藏  举报