文章目录

  • 基于 Swarm 的 Docker 集群管理
  • 一、Swarm简介
    • 1、Swarm 模式简介
    • 2、Swarm 特性
    • 3、Swarm 主要概念
      • (1)开始使用Swarm模式
      • (2)安装环境要求
      • (3)管理节点的IP地址
      • (4)端口开放
  • 二、创建一个 Swarm 集群
  • 三、将节点加入到 Swarm 集群
    • 1、找回指令
    • 2、加入节点到集群
    • 3、部署服务
    • 4、查看服务详情
    • 5、查看服务运行在哪个节点
    • 6、在swarm集群中动态伸缩服务实例数
    • 7、从swarm集群中删除服务
    • 8、更新、回滚服务
      • (1)更新服务资源配置
      • (2)滚动更新服务
      • (3)回滚更新服务
    • 9、从swarm集群中下线一个节点
    • 10、swarm 集群中的路由网络
      • (1)创建服务时暴露端口
      • (2)对已存在服务暴露端口
      • (3)仅暴露一个tcp/udp端口
      • (4)绕过路由网络
      • (5)配置外部负载均衡

基于 Swarm 的 Docker 集群管理

一、Swarm简介

​ Swarm是Docker的一个编排工具,参考官网:https://docs.docker.com/engine/swarm/

1、Swarm 模式简介

​ 要在Swarm模式下运行docker,需要先安装docker,参考安装教程

​ 当前版本的docker包含了swarm模式,用于管理docker集群。可以使用命令行来创建swarm集群,部署应用,管理swarm的行为。

​ 如果你使用低于1.12.0版本的docker,可以使用独立模式的是swarm,但是建议使用最新版本

2、Swarm 特性

  • 与docker集成的集群管理工具
  • 去中心化设计,只使用docker引擎即可创建各类节点
  • 声明式服务模型。可以声明的方式来定义应用。
  • 动态伸缩。管理节点自动调整服务数量。
  • 高可用,对于服务期望状态做到动态调整,swarm的管理节点会持续监控集群状态,集群中有没有达到期望状态的服务,管理节点会自动调度来达到期望状态。
  • 自定义网络。可以为你的服务指定一个网络,容器创建的时候分配一个IP
  • 服务发现。管理节点给集群中每个服务一个特定的DNS名字,并给运行的容器提供负载均衡。
  • 负载均衡。你可以暴露服务端口给外部的负载均衡。内部swarm提供可配置的容器分配到节点的策略。
  • 默认的安全机制。swarm集群中各个节点强制TLS协议验证。连接加密,你可以自定义根证书。
  • 滚动更新。增量跟新,可以自定义更新下个节点的时间间隔,如果有问题,可以会滚到上个版本。

3、Swarm 主要概念

(1)开始使用Swarm模式

后续文档按如下流程进行:

  • 在swarm模式下初始化一个基于docker引擎的swarm集群
  • 在swarm集群中添加节点
  • 部署应用服务到swarm集群中
  • 管理swarm集群
  • 本教程使用docker命令行的方式交互

(2)安装环境要求

  • 准备3台主机,3台可以网络通信的linux主机,可以是物理机,虚拟机,云主机,甚至是docker machine创建的主机,并且3台主机都要安装docker(docker版本要大于1.12.0,安装步骤参考:在linux上安装docker),本例3台主机名称分别为:cnkanon-1、cnkanon-2、cnkanon-3
  • 安装1.12.0以上的docker,本例中 docker 版本为:v18.09.6, build 481bc77156
  • 管理节点的IP地址
  • 主机之间开放端口

(3)管理节点的IP地址

​ 所有swarm集群中的节点都能连接到管理节点的IP地址。

(4)端口开放

  • 以下端口需要开放

2377/tcp 为集群管理通信

7946/tcp、7946/udp 为节点间通信

4789/udp 为网络间流量

  • 如果你想使用加密网络(–opt encrypted)也需要确保ip protocol 50 (ESP)是可用的

二、创建一个 Swarm 集群

完成上面的开始过程后,可以开始创建一个swarm集群,确保docker的后台应用已经在主机上运行了。

  • 登陆到 cnkanon-1 上,如果使用 docker-machine 创建的主机,要求可以 docker-machine ssh cnkanon-1
  • 运行以下命令来创建一个新的swarm集群:
docker swarm init --advertise-addr <MANAGER1-IP>
  • 使用如下命令在 cnkanon-1 上创建swarm集群:
[root@cnkanon-1 ~]# docker swarm init --advertise-addr 192.168.56.3
Swarm initialized: current node (82a19cjqf5gvorp2p5jxwhnn6) is now a manager.To add a worker to this swarm, run the following command:docker swarm join --token SWMTKN-1-2if9pe4h2bvnv2izdaqckxsbhxferygh9h9enh7uqpalyi284o-3hp093o5gyb9oimfn4v64zqz1 192.168.56.3:2377To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
  • –advertise-addr 选项表示管理节点公布它的IP是多少。其它节点必须能通过这个IP找到管理节点。
  • 命令输出了加入swarm 集群的命令。通过 --token 选项来判断是加入为管理节点还是工作节点

3、运行 docker info 来查看当前 swarm 集群的状态:

[root@cnkanon-1 ~]# docker info
Containers: 8Running: 1Paused: 0Stopped: 7
Images: 5
Server Version: 18.09.6
Storage Driver: overlay2Backing Filesystem: xfsSupports d_type: trueNative Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:Volume: localNetwork: bridge host macvlan null overlayLog: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: activeNodeID: 82a19cjqf5gvorp2p5jxwhnn6Is Manager: trueClusterID: 7jmo6jykf14u1lpd90lwinxsoManagers: 1Nodes: 1Default Address Pool: 10.0.0.0/8  SubnetSize: 24Orchestration:Task History Retention Limit: 5Raft:Snapshot Interval: 10000Number of Old Snapshots to Retain: 0Heartbeat Tick: 1Election Tick: 10Dispatcher:Heartbeat Period: 5 secondsCA Configuration:Expiry Duration: 3 monthsForce Rotate: 0Autolock Managers: falseRoot Rotation In Progress: falseNode Address: 192.168.56.3Manager Addresses:192.168.56.3:2377
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: bb71b10fd8f58240ca47fbb579b9d1028eea7c84
runc version: 2b18fe1d885ee5083ef9f0838fee39b62d653e30
init version: fec3683
Security Options:seccompProfile: default
Kernel Version: 3.10.0-957.21.2.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 991.2MiB
Name: cnkanon-1
ID: RZDA:2RQT:Q5M5:HHTW:VTTD:E4GW:ZNHK:E7GI:D6HV:PHFD:NGDZ:TOUE
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:127.0.0.0/8
Registry Mirrors:https://registry.docker-cn.com/http://hub-mirror.c.163.com/https://docker.mirrors.ustc.edu.cn/http://ef017c13.m.daocloud.io/
Live Restore Enabled: false
Product License: Community EngineWARNING: API is accessible on http://0.0.0.0:2375 without encryption.Access to the remote API is equivalent to root access on the host. Referto the 'Docker daemon attack surface' section in the documentation formore information: https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface

4、运行 docker node ls 来查看节点信息:

[root@cnkanon-1 ~]# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
82a19cjqf5gvorp2p5jxwhnn6 *   cnkanon-1           Ready               Active              Leader              18.09.6
  • nodeId 旁边的 * 号表示你当前连接到的节点
  • docker 引擎的swarm模式自动使用宿主机的主机名作为节点名

三、将节点加入到 Swarm 集群

1、找回指令

如果你找不到加入命令了,可以在管理节点运行下列命令找回加入命令:

[root@cnkanon-1 ~]# docker swarm join-token worker
To add a worker to this swarm, run the following command:docker swarm join --token SWMTKN-1-2if9pe4h2bvnv2izdaqckxsbhxferygh9h9enh7uqpalyi284o-3hp093o5gyb9oimfn4v64zqz1 192.168.56.3:2377

2、加入节点到集群

一旦前面的创建swarm集群完成,你就可以加入工作节点了。

登录到服务器 cnkanon-2、cnkanon-3,将这两个服务器加入到集群 cnkanon-1

运行如下指令加入到集群中:

# 服务器 cnkanon-2
[root@cnkanon-2 ~]# docker swarm join --token SWMTKN-1-2if9pe4h2bvnv2izdaqckxsbhxferygh9h9enh7uqpalyi284o-3hp093o5gyb9oimfn4v64zqz1 192.168.56.3:2377
This node joined a swarm as a worker.# 服务器 cnkanon-3
[root@cnkanon-3 ~]# docker swarm join --token SWMTKN-1-2if9pe4h2bvnv2izdaqckxsbhxferygh9h9enh7uqpalyi284o-3hp093o5gyb9oimfn4v64zqz1 192.168.56.3:2377
This node joined a swarm as a worker.

返回服务器 cnkanon-1 管理节点查看集群中节点列表:

[root@cnkanon-1 ~]# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
82a19cjqf5gvorp2p5jxwhnn6 *   cnkanon-1           Ready               Active              Leader              18.09.6
a9durycfoospewwyf7gvyoo35     cnkanon-2           Ready               Active                                  18.09.6
s879hzzvfqc9l2ixmj130ved4     cnkanon-3           Ready               Active                                  18.09.6

3、部署服务

创建好 swarm 集群后,就可以部署服务了(也可以不加入工作节点,直接在管理节点单节点上部署服务),回到管理节点 cnkanon-1,基于 portainer/portainer 镜像创建服务:

[root@cnkanon-1 ~]# docker service create --replicas=1 --name=dev-portainer --publish=9000:9000 portainer/portainer
3k2ptlq025amaevlb2zmebsj4
overall progress: 1 out of 1 tasks
1/1: running   [==================================================>]
verify: Service converged

–replicas:表示期望1个服务实例

–name:表示创建服务的名称

–publish:表示映射的端口

如果指定的镜像未下载,则系统会自动下载,本例中的 portainer/portainer 镜像是提前下载好的

在管理节点 cnkanon-1 上查看运行的服务:

[root@cnkanon-1 ~]# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                        PORTS
3k2ptlq025am        dev-portainer       replicated          1/1                 portainer/portainer:latest   *:9000->9000/tcp

4、查看服务详情

在管理节点 cnkanon-1 上运行如下命令查看服务详情

[root@cnkanon-1 ~]# docker service inspect dev-portainer --pretty
ID:             3k2ptlq025amaevlb2zmebsj4
Name:           dev-portainer
Service Mode:   ReplicatedReplicas:      1
Placement:
UpdateConfig:Parallelism:   1On failure:    pauseMonitoring Period: 5sMax failure ratio: 0Update order:      stop-first
RollbackConfig:Parallelism:   1On failure:    pauseMonitoring Period: 5sMax failure ratio: 0Rollback order:    stop-first
ContainerSpec:Image:         portainer/portainer:latest@sha256:cc226d8a06b6d5e24b44a4f10d0d1fd701741e84a852adc6d40bef9424a000ecInit:          false
Resources:
Endpoint Mode:  vip
Ports:PublishedPort = 9000Protocol = tcpTargetPort = 9000PublishMode = ingress

–pretty:表示以 yaml 格式显示,不加此参数将以 json 格式显示

5、查看服务运行在哪个节点

在管理节点 cnkanon-1 上运行指令查看 dev-portainer 服务运行在 swarm 集群中的哪个节点:

[root@cnkanon-1 ~]# docker service ps dev-portainer
ID           NAME                 IMAGE                       NODE       DESIRED STATE  CURRENT STATE           ERROR                       PORTS
ei18defdqie6 dev-portainer.1      portainer/portainer:latest  cnkanon-1  Running        Running 4 minutes ago
in1rwx6g63kd  \_ dev-portainer.1  portainer/portainer:latest  cnkanon-1  Shutdown       Failed 4 minutes ago    "task: non-zero exit (1)"

服务可能运行在管理或工作节点上,默认的管理节点可以像工作节点一样运行任务

该命令也显示服务期望的状态 DESIRED STATE,和实际的状态 CURRENT STATE

6、在swarm集群中动态伸缩服务实例数

一旦你在swarm集群中创建一个服务后,你就可以使用命令来改变服务的实例个数。在服务中运行的容器称为“任务”。

在管理节点 cnkanon-1 中执行如下指令将 dev-portainer 的实例个数变为3个:

[root@cnkanon-1 ~]# docker service scale dev-portainer=3
dev-portainer scaled to 3
overall progress: 3 out of 3 tasks
1/3: running   [==================================================>]
2/3: running   [==================================================>]
3/3: running   [==================================================>]
verify: Service converged

scale SERVICENAME/{SERVICE_NAME}/SERVICEN​AME/{SERVICE_ID} = n:伸缩服务的实例为指定个数

在管理节点 cnkanon-1 上查看服务 dev-portainer 的运行情况及实例个数:

# 查看服务运行情况
[root@cnkanon-1 ~]# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                        PORTS
3k2ptlq025am        dev-portainer       replicated          3/3                 portainer/portainer:latest   *:9000->9000/tcp# 查看服务运行的实例个数
[root@cnkanon-1 ~]# docker service ps dev-portainer
ID            NAME             IMAGE                       NODE       DESIRED STATE  CURRENT STATE                ERROR         PORTS
rugy9x8je284  dev-portainer.1  portainer/portainer:latest  cnkanon-1  Running        Running about a minute ago
1a5hyn0g23c8  dev-portainer.2  portainer/portainer:latest  cnkanon-3  Running        Running 4 minutes ago
tjgi9ptunfg8  dev-portainer.3  portainer/portainer:latest  cnkanon-2  Running        Running 4 minutes ago

可以看出,dev-portainer 服务运行情况中,REPLICAS=3 表示服务运行实例已扩展为3个

dev-portainer 服务的运行节点 NODE 有 cnkanon-1、cnkanon-2、cnkanon-3,共3个节点

现在分别登录工作节点 cnkanon-2、cnkanon-3 查看服务 dev-portainer 的运行情况:

# 工作节点 cnkanon-2
[root@cnkanon-2 ~]# docker ps
CONTAINER ID        IMAGE                        COMMAND             CREATED             STATUS              PORTS               NAMES
a91f1c529425        portainer/portainer:latest   "/portainer"        3 minutes ago       Up 3 minutes        9000/tcp            dev-portainer.3.va0p1mllzqnte3cghnbp19mk6# 工作节点 cnkanon-3
[root@cnkanon-3 ~]# docker ps
CONTAINER ID        IMAGE                        COMMAND             CREATED             STATUS              PORTS               NAMES
e69063554d71        portainer/portainer:latest   "/portainer"        3 minutes ago       Up 3 minutes        9000/tcp            dev-portainer.2.ene51pt4kpqtq7czpduqrmn9w

可以看到,dev-portainer.3 运行在工作节点 cnkanon-2 上,dev-portainer.2 运行在工作节点 cnkanon-3 上。

在管理节点 cnkanon-1 中尝试将 dev-portainer 的实例个数变为2个,会发现并不会动态删除第3个节点上的容器,只是停止第3个容器:

# 在管理节点 cnkanon-1 上将 dev-portainer 的运行实例缩放到2个节点
[root@cnkanon-1 ~]# docker service scale dev-portainer=2
dev-portainer scaled to 2
overall progress: 2 out of 2 tasks
1/2: running   [==================================================>]
2/2: running   [==================================================>]
verify: Service converged # 在管理节点 cnkanon-1 上查看 dev-portainer 运行情况
[root@cnkanon-1 ~]# docker service ps dev-portainer
ID            NAME             IMAGE                       NODE       DESIRED STATE  CURRENT STATE              ERROR         PORTS
rugy9x8je284  dev-portainer.1  portainer/portainer:latest  cnkanon-1  Running        Running about a minute ago
1a5hyn0g23c8  dev-portainer.2  portainer/portainer:latest  cnkanon-3  Running        Running 4 minutes ago
tjgi9ptunfg8  dev-portainer.3  portainer/portainer:latest  cnkanon-2  Shutdown       Failed 3 minutes ago       "task: non-zero exit (1)"# 登录工作节点 cnkanon-2 查看 dev-portainer 已不在运行
[root@cnkanon-2 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAME

7、从swarm集群中删除服务

在管理节点 cnkanon-1 中删除 dev-portainer:

[root@cnkanon-1 ~]# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                        PORTS
3k2ptlq025am        dev-portainer       replicated          2/2                 portainer/portainer:latest   *:9000->9000/tcp
[root@cnkanon-1 ~]# docker service rm dev-portainer
dev-portainer
[root@cnkanon-1 ~]# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
[root@cnkanon-1 ~]# docker service ps dev-portainer
no such service: dev-portainer
[root@cnkanon-1 ~]# docker service inspect dev-portainer
[]
Status: Error: no such service: dev-portainer, Code: 1

尽管服务不存在了,任务容器还需要几秒钟来清理,你可以在工作节点 cnkanon-2、cnkanon-3 上 docker ps 查看任务什么时候被移除。

8、更新、回滚服务

swarm 集群有一项非常重要的功能:对服务进行滚动更新、滚动回滚以及对服务资源配置进行更新。

(1)更新服务资源配置

(2)滚动更新服务

在swarm集群中可以对服务的版本进行升级,此例中以 nginx:1.16.0 版本为例,先基于 nginx:1.16.0 创建服务,设置 replicas=3,创建3个实例运行来运行,再将服务升级到 nginx:1.17 版本:

# 先下载 nginx:1.16.0 镜像
[root@cnkanon-1 ~]# docker pull nginx:1.16.0
# 创建服务,并指定实例数为3
[root@cnkanon-1 ~]# docker service create --replicas=3 --name=dev-nginx --publish=80:80 nginx:1.16.0# 查看服务版本为 nginx:1.16.0
[root@cnkanon-1 ~]# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                          PORTS
uyqnphtca0lx        dev-nginx           replicated          3/3                 nginx:1.16.0                   *:80->80/tcp

现在将 nginx:1.16.0 版本升级到 nginx:1.17.0 版本:

# 更新版本到 nginx:1.17.0
[root@cnkanon-1 ~]# docker service update --image nginx:1.17 dev-nginx
dev-nginx
overall progress: 3 out of 3 tasks
1/3: running   [==================================================>]
2/3: running   [==================================================>]
3/3: running   [==================================================>]
verify: Service converged# 查看服务版本为 nginx:1.17.0
[root@cnkanon-1 ~]# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                        PORTS
uyqnphtca0lx        dev-nginx           replicated          3/3                 nginx:1.17                   *:80->80/tcp# 查看服务运行情况,版本为 nginx:1.17.0
[root@cnkanon-1 ~]# docker service ps dev-nginx
ID             NAME            IMAGE         NODE         DESIRED STATE       CURRENT STATE                 ERROR               PORTS
3zstw4g8a3vg   dev-nginx.1     nginx:1.17    cnkanon-2    Running             Running about a minute ago
hug1u1seuzwg   \_ dev-nginx.1  nginx:1.16.0  cnkanon-2    Shutdown            Shutdown 2 minutes ago
9av4gh54tk3o   dev-nginx.2     nginx:1.17    cnkanon-3    Running             Running 54 seconds ago
63ajbftz8dp3   \_ dev-nginx.2  nginx:1.16.0  cnkanon-3    Shutdown            Shutdown about a minute ago
spzalsgvt7w8   dev-nginx.3     nginx:1.17    cnkanon-1    Running             Running about a minute ago
y3wyuqq06ldy   \_ dev-nginx.3  nginx:1.16.0  cnkanon-1    Shutdown            Shutdown about a minute ago

调度器 scheduler 依照以下步骤来滚动更新:

  • 停止第一个任务
  • 对停止的任务进行更新
  • 对更新的任务进行启动
  • 如果更新的任务返回RUNNING,等待特定间隔后启动下一个任务
  • 如果在任何更新的时间,任务返回了FAILED,则停止更新。

可以看出执行更新指令后,并未将 nginx:1.16.0 版本删除,而是停止了并且新创建了 nginx:1.17 版本的服务

同时可以指定相应参数来制定滚动更新策略:

  • –update-delay:配置更新服务的时间间隔,可以指定时间T为秒是Ts,分是Tm,或时是Th,所以10m30s就是10分30秒的延迟
  • 默认的调度器 scheduler 一次更新一个任务,使用参数 --update-parallelism 来配置调度器同时更新的最大任务数量
  • 默认的当一个更新任务返回RUNNING状态后,调度器才调度另一个更新任务,直到所有任务都更新了。如果更新过程中任何任务返回了FAILED,调度器就会停止更新。可以给命令docker service create or docker service update配置配置 --update-failure-action,来设置这个行为。

(3)回滚更新服务

将上述更新到 nginx:1.17.0 版本的服务回滚到 nginx:1.16.0 版本,其滚动回滚的原理和滚动更新类似,并不会删除 nginx:1.17.0 服务,只是停止,也不会重启之前的 nginx:1.16.0 版本的服务,而是直接再创建一个 nginx:1.16.0 版本的服务:

# 执行回滚
[root@cnkanon-1 ~]# docker service update --rollback dev-nginx
dev-nginx
rollback: manually requested rollback
overall progress: rolling back update: 3 out of 3 tasks
1/3: running   [>                                                  ]
2/3: running   [>                                                  ]
3/3: running   [>                                                  ]
verify: Service converged # 查看服务运行情况,running状态的版本为 nginx:1.16.0,停止状态的版本为 nginx:1.16.0、nginx:1.17.0
[root@cnkanon-1 ~]# docker service ps dev-nginx
ID            NAME                IMAGE          NODE        DESIRED STATE       CURRENT STATE                 ERROR               PORTS
0jlkh0ci9r42  dev-nginx.1         nginx:1.16.0   cnkanon-2   Running             Running about a minute ago
3zstw4g8a3vg  \_ dev-nginx.1      nginx:1.17     cnkanon-2   Shutdown            Shutdown about a minute ago
hug1u1seuzwg  \_ dev-nginx.1      nginx:1.16.0   cnkanon-2   Shutdown            Shutdown 13 minutes ago
54sciwitz0he  dev-nginx.2         nginx:1.16.0   cnkanon-3   Running             Running about a minute ago
9av4gh54tk3o  \_ dev-nginx.2      nginx:1.17     cnkanon-3   Shutdown            Shutdown about a minute ago
63ajbftz8dp3  \_ dev-nginx.2      nginx:1.16.0   cnkanon-3   Shutdown            Shutdown 12 minutes ago
spzalsgvt7w8  dev-nginx.3         nginx:1.17     cnkanon-1   Shutdown            Shutdown about a minute ago
y3wyuqq06ldy  \_ dev-nginx.3      nginx:1.16.0   cnkanon-1   Shutdown            Shutdown 13 minutes ago

9、从swarm集群中下线一个节点

  • 前面的教程中管理节点会把任务分配给 ACTIVE 的节点,所有 ACTIVE 的节点都能接到任务
  • 有时候,例如特定的维护时间,我们就需要从集群中下线一个节点。下线节点使节点不会接受新任务,管理节点会停止该节点上的任务,分配到别的 ACTIVE 的节点上。

注意:下线一个节点不移除节点中的独立容器,如docker run,docker-compose up、docker api启动的容器都不会删除。节点的状态仅影响集群服务的负载是否分到该节点。

# swarm 集群中3个节点都牌 ACTIVE 状态
[root@cnkanon-1 ~]# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
82a19cjqf5gvorp2p5jxwhnn6 *   cnkanon-1           Ready               Active              Leader              18.09.6
a9durycfoospewwyf7gvyoo35     cnkanon-2           Ready               Active                                  18.09.6
s879hzzvfqc9l2ixmj130ved4     cnkanon-3           Ready               Active                                  18.09.6# swarm 集群中有一个服务 nginx:1.16.0 在2个节点运行
[root@cnkanon-1 ~]# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                        PORTS
uyqnphtca0lx        dev-nginx           replicated          2/2                 nginx:1.16.0                 *:80->80/tcp# nginx:1.16.0 服务分别运行在节点 cnkanon-2、cnkanon-3 上
[root@cnkanon-1 ~]# docker service ps dev-nginx
ID            NAME                IMAGE          NODE        DESIRED STATE       CURRENT STATE                 ERROR               PORTS
0jlkh0ci9r42  dev-nginx.1         nginx:1.16.0   cnkanon-2   Running             Running about a minute ago
3zstw4g8a3vg  \_ dev-nginx.1      nginx:1.17     cnkanon-2   Shutdown            Shutdown about a minute ago
hug1u1seuzwg  \_ dev-nginx.1      nginx:1.16.0   cnkanon-2   Shutdown            Shutdown 13 minutes ago
54sciwitz0he  dev-nginx.2         nginx:1.16.0   cnkanon-3   Running             Running about a minute ago
9av4gh54tk3o  \_ dev-nginx.2      nginx:1.17     cnkanon-3   Shutdown            Shutdown about a minute ago
63ajbftz8dp3  \_ dev-nginx.2      nginx:1.16.0   cnkanon-3   Shutdown            Shutdown 12 minutes ago
spzalsgvt7w8  dev-nginx.3         nginx:1.17     cnkanon-1   Shutdown            Shutdown about a minute ago
y3wyuqq06ldy  \_ dev-nginx.3      nginx:1.16.0   cnkanon-1   Shutdown            Shutdown 13 minutes ago

将节点 cnkanon-3 下线:

# 更新节点 cnkanon-3 的状态为 DRAIN
[root@cnkanon-1 ~]# docker node update --availability drain cnkanon-3
cnkanon-3# swarm 集群中节点 cnkanon-3 状态已变为 DRAIN
[root@cnkanon-1 ~]# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
82a19cjqf5gvorp2p5jxwhnn6 *   cnkanon-1           Ready               Active              Leader              18.09.6
a9durycfoospewwyf7gvyoo35     cnkanon-2           Ready               Active                                  18.09.6
s879hzzvfqc9l2ixmj130ved4     cnkanon-3           Ready               Drain                                   18.09.6# 服务 nginx:1.16.0 依旧在2个节点运行,但已经从 cnkanon-3 切换到了 cnkanon-1
[root@cnkanon-1 ~]# docker service ps dev-nginx
ID            NAME             IMAGE          NODE          DESIRED STATE       CURRENT STATE                 ERROR               PORTS
0jlkh0ci9r42  dev-nginx.1      nginx:1.16.0   cnkanon-2     Running             Running 6 hours ago
3zstw4g8a3vg  \_ dev-nginx.1   nginx:1.17     cnkanon-2     Shutdown            Shutdown 6 hours ago
hug1u1seuzwg  \_ dev-nginx.1   nginx:1.16.0   cnkanon-2     Shutdown            Shutdown 6 hours ago
9esjmlrua9hv  dev-nginx.2      nginx:1.16.0   cnkanon-1     Running             Running about a minute ago
54sciwitz0he  \_ dev-nginx.2   nginx:1.16.0   cnkanon-3     Shutdown            Shutdown about a minute ago
9av4gh54tk3o  \_ dev-nginx.2   nginx:1.17     cnkanon-3     Shutdown            Shutdown 6 hours ago
63ajbftz8dp3  \_ dev-nginx.2   nginx:1.16.0   cnkanon-3     Shutdown            Shutdown 6 hours ago
spzalsgvt7w8  dev-nginx.3      nginx:1.17     cnkanon-1     Shutdown            Shutdown 6 hours ago
y3wyuqq06ldy  \_ dev-nginx.3   nginx:1.16.0   cnkanon-1     Shutdown            Shutdown 6 hours ago
  • 当节点重新active的时候,在以下情况下它会重新接受任务:
  • 当一个服务缩容扩容时
  • 在滚动更新的时候
  • 当另一个节点Drain下线的时候
  • 当一个任务在另一个active节点上运行失败的时候

10、swarm 集群中的路由网络

  • docker的swarm模式使服务暴露给外部端口更加方便。所有的节点都在一个路由网络里。这个路由网络使得集群内的所有节点都能在开放的端口上接受请求。即使节点上没有任务运行,这个服务的端口也暴露的。路由网络路由所有的请求到暴露端口的节点上。
  • 前提是需要暴露以下端口来使节点间能通信
    • 7946/tcp、7946/udp 用于容器间网络发现
    • 4789/udp 用于容器进入网络
  • 你也必须开放节点之间的公开端口,和任何外部资源端口,例如一个外部的负载均衡
  • 你也可以使特定服务绕过路由网络

(1)创建服务时暴露端口

  • 使用--publish来在创建一个服务的时候暴露端口。target指明容器内暴露的端口。published 指明绑定到路由网络上的端口。如果不写published,就会为每个服务绑定一个随机的高数字端口。你需要检查任务才能确定端口
docker service create --name=dev-nginx --publish=published=8080,target=80 --replicas=1 nginx:1.16.0

注意旧版的语法是冒号分开的published:target,例如 -p 8080:80。新语法更易读且灵活。

当你在任何节点访问8080端口时,路由网络将把请求分发到一个active的容器中。在各个节点,8080端口可能并没有绑定,但是路由网络知道如何路由流量,并防止任何端口冲突。

路由网络监听各个节点的IP上的 published port 。从外面看,这些端口是各个节点暴露的。对于别的IP地址,只在该主机内可以访问。

(2)对已存在服务暴露端口

  • 也可以用以下命令给一个已经存在的服务暴露端口
docker service update --publish-add published=8080,target=80 dev-nginx# 查看暴露端口情况
docker service inspect --format="{{json .Endpoint.Spec.Ports}}" dev-nginx
[{"Protocol":"tcp","TargetPort":80,"PublishedPort":8080,"PublishMode":"ingress"}]

(3)仅暴露一个tcp/udp端口

  • 默认你暴露的端口都是tcp的。如果你使用长语法(Docker 1.13 and higher),设置protocol为tcp或udp即可暴露相应协议的端口
# 仅暴露 tcp 端口
# 长语法
docker service create --name=dev-nginx dns-cache --publish=published=8080,target=80 dns-cache
# 短语法
docker service create --name=dev-nginx dns-cache -p 53:53 dns-cache# 暴露 tcp和udp 端口
# 长语法
docker service create --name=dev-nginx dns-cache --publish=published=8080,target=80 --publish=published=6379,target=6379,protocol=udp dns-cache
# 短语法
docker service create --name=dev-nginx dns-cache -p 53:53 -p 53:53/udp dns-cache# 仅暴露 udp 端口
# 长语法
docker service create --name=dev-nginx dns-cache --publish=published=8080,target=80,protocol=udp dns-cache
#短语法
docker service create --name=dev-nginx dns-cache -p 53:53/udp dns-cache

(4)绕过路由网络

  • 你可以绕过路由网络,直接和一个节点上的端口通信,来访问服务。这叫做Host模式:

如果该节点上没有服务运行,服务也没有监听端口,则可能无法通信。

你不能在一个节点上运行多个服务实例他们绑定同一个静态target端口。或者你让docker分配随机高数字端口(通过空配置target),或者确保该节点上只运行一个服务实例(通过配置全局服务global service 而不是副本服务,或者使用配置限制)。

  • 为了绕过路由网络,必须使用长格式–publish,设置模式mode为host模式。如果你忽略了mode设置或者设置为内网ingress,则路由网络将启动。下面的命令创建了全局应用使用host模式绕过路由网络:
docker service create --name=dev-nginx dns-cache --publish=published=8080,target=80,protocol=udp,mode=host --mode global dns-cache

(5)配置外部负载均衡

可以为swarm集群配置外部的负载均衡,或者结合路由网络使用或者完全不使用

  • 使用路由网络

使用一个外部的HAProxy来负载均衡,服务是8080端口上的nginx服务

上图中负载均衡和集群节点之间的8080端口必须是开放的。swarm集群节点在一个外部不可访问的内网中,节点可以与HAProxy通信。

可以配置负载均衡分流请求到不同的集群节点,即使节点上没有服务运行

当请求HAProxy的80端口的时候,它会转发请求到后端节点。swarm的路由网络会路由到相应的服务节点。这样无论任何原因swarm的调度器调度服务到不同节点,都不需要重新配置负载均衡。

可以配置任何类型的负载均衡来分流请求。

  • 不使用路由网络

如果不使用路由网络,配置--endpoint-mode的值为dnsrr,而不是vip。在本例子中没有一个固定的虚拟IP。Docker为服务做了DNS注册,这样一个服务的DNS查询会返回一系列IP地址。客户端就可以直接连接其中一个节点。你负责提供这一系列的IP地址,开放端口给你的负载均衡器。参考Configure service discovery.

基于 Swarm 的 Docker 集群管理相关推荐

  1. 基于Kubernetes构建Docker集群管理详解

    from: 基于Kubernetes构建Docker集群管理详解 Kubernetes是Google开源的容器集群管理系统,基于Docker构建一个容器的调度服务,提供资源调度.均衡容灾.服务注册.动 ...

  2. Docker集群管理之Swarm介绍

    [摘要] Docker自诞生以来,其容器特性以及镜像特性给DevOps爱好者带来了诸多方便.然而在很长的一段时间内,Docker只能在单host上运行,其跨host的部署.运行与管理能力颇受外界诟病. ...

  3. Docker集群管理(DockerHub Harbor 打包-Jib 任务编排工具- docker-compose和Swarm)

    Docker 集群管理 Docker 集群管理 镜像仓库管理 DockerHUb仓库管理 什么是DockerHUb 账号注册和登陆 Docker客户端登录 管理镜像 推送镜像 仓库镜像测试 regis ...

  4. Kubernetes与docker集群管理常见问题解析

    很荣幸受邀参加开源中国社区的高手问答,我是时速云团队的后端工程师,负责主机管理功能开发.在互动过程中,发现大家在使用/调研kubernetes(简称k8s)过程中遇到了很多问题,这里我总结为几点: l ...

  5. docker集群管理工具_太多选择:如何选择正确的工具来管理Docker集群

    docker集群管理工具 There are all kinds of ways to play the Docker game and, obviously, no one of them is g ...

  6. docker集群管理

    docker集群管理 ps:docker machine     docker swarm       docker compose  在Docker Machine发布之前,你可能会遇到以下问题: ...

  7. Swarm搭建Docker集群

    Swarm介绍 Swarm是Docker公司在2014年12月初发布的一套较为简单的工具,用来管理Docker集群,它将一群Docker宿主机变成一个单一的,虚拟的主机.Swarm使用标准的Docke ...

  8. Docker学习笔记 — Swarm搭建Docker集群

    http://www.cnblogs.com/rio2607/p/4445968.html#undefined Swarm介绍 Swarm是Docker公司在2014年12月初发布的一套较为简单的工具 ...

  9. 基于Rancher实现kubernetes集群管理

    基于Rancher实现kubernetes集群管理 1.Rancher介绍 2.Rancher部署 添加kubernetes集群 3.Rancher简单操作 1.Rancher介绍 Rancher可以 ...

最新文章

  1. CCNA考试认证教材【 ip地址 子网划分 】视频教程【高清】
  2. asp.net跳转并接收参数
  3. mac版本查看日志命令
  4. 基于live555实现的RTSPServer对底层进行性能优化的方法
  5. 关于myeclipse打开jsp巨慢解决方案
  6. mysql数据库比较,各数据库不同之处
  7. 本周小结!(二叉树系列三)
  8. ENVI入门系列教程---一、数据预处理---1.1基本操作--5.x以后的界面(新界面)
  9. ueditor 文件服务器,ueditor-extend: 对百度UEditor编辑器做扩展,开放文件存储方法和获取远程文件列表方法,使其更灵活,更容易和独立的文件服务或者文件存储的云服务结合。...
  10. 这款优秀的检验工具SolidWorks Inspection你用过吗?
  11. linux下面的j2sdk的安装和配置过程!
  12. 内存操作函数:memcmp、memcpy、memmove、memset 的使用与模拟。
  13. 阿里云服务器ECS上部署简单的SSM项目
  14. 计算机不识别固态硬盘,win7系统电脑无法识别M.2固态硬盘如何解决
  15. 服务器返回常见状态码及意义
  16. 第二届中国PWA开发者日
  17. 告别光棍节——见习情圣(恋爱培训导师)
  18. 科罗拉多大学波尔得分校计算机科学,科罗拉多大学波尔得分校副教授Dan Zhang:基于线性规划的近似动态规划方面的一些最新成果...
  19. 比百度地图.api更方便的测量面积方法
  20. Nginx Rewrite研究笔记

热门文章

  1. 【物联网/智慧城市】2021年物联网与智慧城市国际学术会议 (IoTSC2021)
  2. 面试金典08(Python)—— 零矩阵(中等)
  3. Zstack云平台管理
  4. 趣谈12星座 这个貌似挺准的
  5. GG有这个提醒怎么办 合并外部 JavaScript 尽量减少 DNS 查询次数 由同一网址提供资源...
  6. 40+嘉宾阵容齐聚深圳!邀您参加第八届肠道微生态与健康研讨会!
  7. Vue百度地图轨迹回放
  8. 酒店数字化转型,就从这4步开始
  9. gitlab服务器安装及汉化配置
  10. react和vue中自定义标签的原理在这里