Docker 之 swarm 集群模式

好风 发表于 2016-12-12T13:03:56.775508Z
引用地址:https://plus.ooclab.com/note/article/1319

要使用 docker swarm 集群模式,必须使用 v1.12.0 及以上版本的 docker 程序。

参考:

创建 swarm

初始化 manager 节点(192.168.1.152):

[root@dev152 ~]# docker swarm init --advertise-addr 192.168.1.152
Swarm initialized: current node (8nntqfva3gqhye8m6giexd6wc) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join \
    --token SWMTKN-1-3ya9qjmklxmgy4oerf100vwtl8th40ttl2uf5a4n28akzywfoa-9a2ykpsheir2iixxbovkj9p9q \
    192.168.1.152:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

在其他节点 (192.168.1.155, 192.168.1.156) 执行上面 docker swarm join ... 命令,可以向 swarm 集群增加 worker 。

注意 : 任何时候可以运行 docker swarm join-token worker 重新查看增加 worker 的命令。

查看 manager 节点信息:

docker info

查看节点列表:

# docker node ls
ID                           HOSTNAME      STATUS  AVAILABILITY  MANAGER STATUS
1turw4i8o4khdse3h8phkof1x    gwind-dev-1   Ready   Active        
8nntqfva3gqhye8m6giexd6wc *  dev152.gwind  Ready   Active        Leader
f4z02ckpq94ufx1gqchmeudd8    gwind-dev-2   Ready   Active

部署 service

部署一个 service :

docker service create --replicas 1 --name helloworld alpine ping docker.com

查看 service 列表:

# docker service ls
ID            NAME        REPLICAS  IMAGE   COMMAND
722gb69qccp5  helloworld  1/1       alpine  ping docker.com

查看 service 详细信息

# docker service inspect --pretty 72
ID:             722gb69qccp5jimhueebk5t6y
Name:           helloworld
Mode:           Replicated
 Replicas:      1
Placement:
UpdateConfig:
 Parallelism:   1
 On failure:    pause
ContainerSpec:
 Image:         alpine
 Args:          ping docker.com
Resources:

查看 service 运行于哪一台 node :

# docker service ps helloworld
ID                         NAME              IMAGE   NODE          DESIRED STATE  CURRENT STATE           ERROR
4iixx56vgnn6s3vyu1d0u9lcm  helloworld.1      alpine  gwind-dev-2   Running        Running 12 minutes ago  
bnw6isn2sdb352rmsns9vvdun   \_ helloworld.1  alpine  dev152.gwind  Shutdown       Failed 13 minutes ago   "task: non-zero exit (1)"

scale service

$ docker service scale <SERVICE-ID>=<NUMBER-OF-TASKS>

示例:

# docker service scale 72=3
72 scaled to 3
# docker service ls
ID            NAME        REPLICAS  IMAGE   COMMAND
722gb69qccp5  helloworld  3/3       alpine  ping docker.com
# docker service ps 72
ID                         NAME              IMAGE   NODE          DESIRED STATE  CURRENT STATE           ERROR
4iixx56vgnn6s3vyu1d0u9lcm  helloworld.1      alpine  gwind-dev-2   Running        Running 18 minutes ago  
bnw6isn2sdb352rmsns9vvdun   \_ helloworld.1  alpine  dev152.gwind  Shutdown       Failed 19 minutes ago   "task: non-zero exit (1)"
2imj2441u661ilzcjkyrks57w  helloworld.2      alpine  dev152.gwind  Running        Running 3 minutes ago   
9js625mg8lfwc0emzji30y7ju  helloworld.3      alpine  gwind-dev-1   Running        Running 3 minutes ago

删除 service

# docker service rm 72

rolling update

创建一个 service :

# docker service create \
>   --replicas 3 \
>   --name redis \
>   --update-delay 10s \
>   redis:3.0.6

查看 service 详情:

# docker service inspect --pretty redis
ID:             2o1io0t7axh7cshvsczk4w27v
Name:           redis
Mode:           Replicated
 Replicas:      3
Placement:
UpdateConfig:
 Parallelism:   1
 Delay:         10s
 On failure:    pause
ContainerSpec:
 Image:         redis:3.0.6
Resources:

更新 service :

# docker service update --image redis:3.0.7 redis

drain node

docker node update --availability drain <NODE-ID>

示例:

清理旧的 redis 服务,并重新创建之:

# docker service rm redis
# docker service create --replicas 3 --name redis --update-delay 10s redis:3.0.6
# docker service ps redis

等redis服务正常运行后。drain 节点 gwind-dev-1

# docker node update --availability drain gwind-dev-1
# docker node inspect --pretty gwind-dev-1
ID:                     1turw4i8o4khdse3h8phkof1x
Hostname:               gwind-dev-1
Joined at:              2016-12-12 08:18:47.68126962 +0000 utc
Status:
 State:                 Ready
 Availability:          Drain
Platform:
 Operating System:      linux
 Architecture:          x86_64
Resources:
 CPUs:                  1
 Memory:                993.1 MiB
Plugins:
  Network:              bridge, host, null, overlay
  Volume:               local
Engine Version:         1.12.3
# docker service ps redis

重新 active node :

# docker node update --availability active gwind-dev-1

ingress network

swarm mode 很容易对外发布 service 的端口。

ingress routing mesh 可以外部程序从 swarm 中的任意node访问任意service的任意开放端口。

为了使用 ingress network , 你必须确保所有 node 开放以下端口:

  • 7946 UDP/TCP : 容器网络发现
  • 4789 UDP : 容器 ingress network

开放 service 端口

语法:

$ docker service create \
  --name <SERVICE-NAME> \
  --publish <PUBLISHED-PORT>:<TARGET-PORT> \
  <IMAGE>

示例:

$ docker service create \
  --name my-web \
  --publish 8080:80 \
  --replicas 2 \
  nginx

现在你访问任一 node 的 8080 端口,都可以访问 my-web 服务了 (swarm load balancer 路由你的请求到一个运行的容器)。

在运行中的 service 上增加开放端口

语法:

$ docker service update \
  --publish-add <PUBLISHED-PORT>:<TARGET-PORT> \
  <SERVICE>

查看 service publish port:

# docker service inspect --format="{{json .Endpoint.Spec.Ports}}" my-web
[{"Protocol":"tcp","TargetPort":80,"PublishedPort":8080}]

发布 tcp only 或 udp only 端口

TCP only

$ docker service create --name dns-cache -p 53:53 dns-cache
# 或
$ docker service create --name dns-cache -p 53:53/tcp dns-cache

TCP and UDP

$ docker service create --name dns-cache -p 53:53/tcp -p 53:53/udp dns-cache

UDP only

$ docker service create --name dns-cache -p 53:53/udp dns-cache

外部 load balancer 配置

/etc/haproxy/haproxy.cfg:

global
        log /dev/log    local0
        log /dev/log    local1 notice
...snip...

# Configure HAProxy to listen on port 80
frontend http_front
   bind *:80
   stats uri /haproxy?stats
   default_backend http_back

# Configure HAProxy to route requests to swarm nodes on port 8080
backend http_back
   balance roundrobin
   server node1 192.168.99.100:8080 check
   server node2 192.168.99.101:8080 check
   server node3 192.168.99.102:8080 check