Docker Swarm集群搭建

Swarm是Docker公司自研发的容器集群管理系统,Swarm在早期是作为一个独立服务存在,在Docker Engine v1.12中集成了Swarm的集群管理
和编排功能。可以通过初始化Swarm或加入现有Swarm来启用Docker引擎的Swarm模式。
Docker Engine CLI和API包括了管理Swarm节点命令,比如添加、删除节点,以及在Swarm中部署和编排服务。
也增加了服务栈(Stack)、服务(Service)、任务(Task)概念

Docker Swarm集群搭建_第1张图片
20180816211329808.png

功能特点:

a.与Docker Engine集成的集群管理:

使用Docker Engine CLI创建一组Docker引擎,您可以在其中部署应用程序服务。您不需要其他编排软件来创建或管理群集。

b.节点分散式设计:

Docker Engine不是在部署时处理节点角色之间的差异,而是在运行时处理角色变化。您可以使用Docker Engine部署两种类型的节点,管理节点和工作节点。这意味着您可以从单个服务器构建整个群集。

c.声明性服务模型:

Docker Engine使用声明性方法来定义应用程序堆栈中各种服务的所需状态。例如,您可以描述由具有消息队列服务和数据库后端的Web前端服务组成的应用程序。

d.可扩容与缩放容器:

对于每个服务,您可以声明要运行的任务数。当您向上或向下缩放时,swarm管理器通过添加或删除任务来自动适应,以保持所需的任务数量来保证集群的可靠状态。

e.容器容错状态协调:

群集管理器节点不断监视群集状态,并协调您表示的期望状态的实际状态之间的任何差异。例如,如果设置一个服务以运行容器的10个副本,并且托管其中两个副本的工作程序计算机崩溃,则管理器将创建两个新副本以替换崩溃的副本。 swarm管理器将新副本分配给正在运行和可用的worker节点上。

f.多主机网络:

您可以为服务指定覆盖网络。当swarm管理器初始化或更新应用程序时,它会自动为覆盖网络上的容器分配地址。

g.服务发现:

Swarm管理器节点为swarm中的每个服务分配唯一的DNS名称,并负载平衡运行的容器。您可以通过嵌入在swarm中的DNS服务器查询在群中运行的每个容器。

h.负载平衡:

您可以将服务的端口公开给外部负载平衡器。在内部,swarm允许您指定如何在节点之间分发服务容器。

m.缺省安全:

群中的每个节点强制执行TLS相互验证和加密,以保护其自身与所有其他节点之间的通信。您可以选择使用自签名根证书或来自自定义根CA的证书。

n.滚动更新:

在已经运行期间,您可以增量地应用服务更新到节点。 swarm管理器允许您控制将服务部署到不同节点集之间的延迟。如果出现任何问题,您可以将任务回滚到服务的先前版本。

我的三台测试机

IP 角色
172.16.10.85 manager
172.16.10.86 worker
172.16.10.87 worker

创建集群

在创建集群前,如果开启了防火墙,请确认三台主机的防火墙能让swarm需求的端口开放,需要打开主机之间的端口,以下端口必须可用。在某些系统上,这些端口默认为打开。

  • 2377:TCP端口2377用于集群管理通信
  • 7946:TCP和UDP端口7946用于节点之间的通信
  • 4789:TCP和UDP端口4789用于覆盖网络流量

可以直接禁用系统防火墙来让这些端口通信不受限制,一般测试环境我们都会禁用防火墙

systemctl stop firewalld(立即生效)
systemctl disable firewalld(重启生效)

docker环境自行安装

常用命令
在Docker Swarm中经常使用的主要有docker swarm、docker node、docker service、docker stack。
docker swarm
管理swarm,添加节点

Commands:
  init        Initialize a swarm   
  join        Join a swarm as a node and/or manager
  join-token  Manage join tokens
  leave       Leave the swarm
  unlock      Unlock swarm
  unlock-key  Manage the unlock key
  update      Update the swarm

docker node
用于管理节点

Commands:
  demote      Demote one or more nodes from manager in the swarm
  inspect     Display detailed information on one or more nodes
  ls          List nodes in the swarm
  promote     Promote one or more nodes to manager in the swarm
  ps          List tasks running on one or more nodes, defaults to current node
  rm          Remove one or more nodes from the swarm
  update      Update a node

docker service
管理service

Commands:
  create      Create a new service
  inspect     Display detailed information on one or more services
  logs        Fetch the logs of a service or task
  ls          List services
  ps          List the tasks of one or more services
  rm          Remove one or more services
  scale       Scale one or multiple replicated services
  update      Update a service

docker stack
与docker-compose结合的命令,可以方便地在集群中部署应用。

Commands:
  deploy      Deploy a new stack or update an existing stack
  ls          List stacks
  ps          List the tasks in the stack
  rm          Remove one or more stacks
  services    List the services in the stack

初始化swarm:

docker swarm init --advertise-addr 172.16.10.85(本机IP)

在其它两台worker主机上执行加入swarm:

[root@swarm-m ~]# docker swarm init --advertise-addr 172.16.10.85
Swarm initialized: current node (mclobj2doj65sek345mjkklfo) is now a manager.

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

    docker swarm join --token SWMTKN-1-42w2dmkv2u18k9d6vi65rhqggjcqcc31iijnecd4bbi43bmom2-b3o89g28thkcken0v3qxtczuj 172.16.10.85:2377

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

如果后续我们有新的主机被当做manager、worker节点想要加入到集群中来,但要不记得当时创建集群时的token,在manager主机上执行以下命令:

  docker swarm join-token manager
  docker swarm join-token worker

查看swarm的节点

[root@swarm-m ~]# docker node ls
ID                            HOSTNAME                     STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
mclobj2doj65sek345mjkklfo *   swarm-m.nahong.com.cn        Ready               Active              Leader              18.06.1-ce
oyrkdwj3da9r275jxsj0lyqxe     swarm-node01.nahong.cm.cn    Ready               Active                                  18.06.1-ce
f295ymtj2t3vjojdbuwclykva     swarm-node02.nahong.com.cn   Ready               Active                                  18.06.1-ce

AVAILABILITY列的说明:

  • Active 意味着调度程序可以将任务分配给节点。
  • Pause 意味着调度程序不会将新任务分配给节点,但现有任务仍在运行。
  • Drain 意味着调度程序不会向节点分配新任务。调度程序关闭所有现有任务并在可用节点上调度它们。

MANAGER STATUS列的说明

显示节点是属于manager或者worker

  • 没有值 表示不参与群管理的工作节点。
  • Leader 意味着该节点是使得群的所有群管理和编排决策的主要管理器节点。
  • Reachable 意味着节点是管理者节点正在参与Raft共识。如果领导节点不可用,则该节点有资格被选为新领导者。
  • Unavailable 意味着节点是不能与其他管理器通信的管理器。如果管理器节点不可用,您应该将新的管理器节点加入群集,或者将工作器节点升级为管理器。

升级或降级节点
您可以将工作程序节点提升为manager角色。这在管理器节点不可用或者您希望使管理器脱机以进行维护时很有用。 类似地,您可以将管理器节点降级为worker角色。
无论您升级或降级节点,您应该始终在群中维护奇数个管理器节点。
要升级一个节点或一组节点,请从管理器节点运行docker node promote:

[root@swarm-m ~]# docker node promote swarm-node01.nahong.cm.cn
Node swarm-node01.nahong.cm.cn promoted to a manager in the swarm.
[root@swarm-m ~]# docker node ls
ID                            HOSTNAME                     STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
mclobj2doj65sek345mjkklfo *   swarm-m.nahong.com.cn        Ready               Active              Leader              18.06.1-ce
oyrkdwj3da9r275jxsj0lyqxe     swarm-node01.nahong.cm.cn    Ready               Active              Reachable           18.06.1-ce
f295ymtj2t3vjojdbuwclykva     swarm-node02.nahong.com.cn   Ready               Active                                  18.06.1-ce

要降级一个节点或一组节点,请从管理器节点运行docker node demote:

[root@swarm-m ~]# docker node demote swarm-node01.nahong.cm.cn 
Manager swarm-node01.nahong.cm.cn demoted in the swarm.
[root@swarm-m ~]# docker node ls
ID                            HOSTNAME                     STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
mclobj2doj65sek345mjkklfo *   swarm-m.nahong.com.cn        Ready               Active              Leader              18.06.1-ce
oyrkdwj3da9r275jxsj0lyqxe     swarm-node01.nahong.cm.cn    Ready               Active                                  18.06.1-ce
f295ymtj2t3vjojdbuwclykva     swarm-node02.nahong.com.cn   Ready               Active                                  18.06.1-ce

创建自定义的overlay网络:

docker network create --driver overlay --subnet 10.10.10.0/16 my-overlay-network

查询swarm网络 docker network ls

[root@docker01 ~]# docker network ls
NETWORK ID          NAME                 DRIVER              SCOPE
24de50a56f99        bridge               bridge              local
a4e5dcbfd6b8        docker_gwbridge      bridge              local
a261cf27e5bb        host                 host                local
l5abdspoesd9        ingress              overlay             swarm
lp2f4kze0osc        my-overlay-network   overlay             swarm
d625b46d604a        none                 null                local

创建一个nginx service
先摘取docker镜像

docker pull linuxserver/nginx

执行命令创建service:

docker service create --name webapp-nginx --replicas 3 --network my-overlay-network --publish 8089:80 linuxserver/nginx

docker service create中的参数:

  • --name 服务名
  • --replicas 是创建的副本的数量
  • --network 是使用的网络
  • --publish 是服务公开的端口 :

查看webapp-nginx服务任务分配到的节点 docker service ps webapp-nginx

[root@swarm-m ~]# docker service ps webapp-nginx 
ID                  NAME                IMAGE                      NODE                         DESIRED STATE       CURRENT STATE                ERROR               PORTS
sv6y9jedbetw        webapp-nginx.1      linuxserver/nginx:latest   swarm-node02.nahong.com.cn   Running             Running about a minute ago                       
k26fewhj9lzq        webapp-nginx.2      linuxserver/nginx:latest   swarm-m.nahong.com.cn        Running             Running about a minute ago                       
jnr2t0msnumy        webapp-nginx.3      linuxserver/nginx:latest   swarm-node01.nahong.cm.cn    Running             Running 52 seconds ago           

外部访问公开端口8089

  • http://172.16.10.85:8089
  • http://172.16.10.86:8089
  • http://172.16.10.87:8089
    都会访问成功,这里就出一个85的截图
    Docker Swarm集群搭建_第2张图片
    o01.png

查看manager主机上的docker容器

[root@swarm-m ~]# docker ps
CONTAINER ID        IMAGE                      COMMAND             CREATED             STATUS              PORTS               NAMES
d412b3ce543e        linuxserver/nginx:latest   "/init"             4 minutes ago       Up 4 minutes        80/tcp, 443/tcp     webapp-nginx.2.k26fewhj9lzqpva03zv6mgtpm

查看manager节点容器网络

[root@swarm-m ~]# docker exec d412b3ce543e ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:0A:FF:00:08  
          inet addr:10.255.0.8  Bcast:10.255.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1450  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

eth1      Link encap:Ethernet  HWaddr 02:42:0A:0A:0A:08  
          inet addr:10.10.10.8  Bcast:10.10.10.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1450  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

eth2      Link encap:Ethernet  HWaddr 02:42:AC:12:00:03  
          inet addr:172.18.0.3  Bcast:172.18.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:648 (648.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

eth0、eth1、eth2网卡分别:

  • eth0:10.255.0.8 属于docker的ingress网络
  • eth1:10.10.10.8 属于overlay的自定义网络my-overlay-network
  • eth2:172.18.0.3 属于docker_gwbridge网络

ingress网络会用于容器间的负载均衡,docker_gwbridge网络用于容器连接外网。

到另外两台查看网络:

[root@swarm-node01 ~]# docker ps
CONTAINER ID        IMAGE                      COMMAND             CREATED             STATUS              PORTS               NAMES
34dd665161bd        linuxserver/nginx:latest   "/init"             About an hour ago   Up About an hour    80/tcp, 443/tcp     webapp-nginx.3.jnr2t0msnumyd6znib3smcdj7
[root@swarm-node01 ~]# docker exec 34dd665161bd ifconfig | grep -A 1 eth1
eth1      Link encap:Ethernet  HWaddr 02:42:0A:0A:0A:06  
          inet addr:10.10.10.6  Bcast:10.10.10.255  Mask:255.255.255.0
[root@swarm-node02 ~]# docker ps
CONTAINER ID        IMAGE                      COMMAND             CREATED             STATUS              PORTS               NAMES
ba325bc18b97        linuxserver/nginx:latest   "/init"             About an hour ago   Up About an hour    80/tcp, 443/tcp     webapp-nginx.1.sv6y9jedbetw3lbxebtneqhf6
[root@swarm-node02 ~]# docker exec ba325bc18b97 ifconfig | grep -A 1 eth1
eth1      Link encap:Ethernet  HWaddr 02:42:0A:0A:0A:07  
          inet addr:10.10.10.7  Bcast:10.10.10.255  Mask:255.255.255.0

三个容器自定义IP分别是:

  • 10.10.10.8 manager主机的nginx容器
  • 10.10.10.6 worker主机的nginx容器
  • 10.10.10.7 worker主机的nginx容器

在容器10.10.10.6上ping 10.10.10.8

[root@swarm-node02 ~]# docker exec ba325bc18b97 ping 10.10.10.8
PING 10.10.10.8 (10.10.10.8): 56 data bytes
64 bytes from 10.10.10.8: seq=0 ttl=64 time=0.965 ms
64 bytes from 10.10.10.8: seq=1 ttl=64 time=0.600 ms
64 bytes from 10.10.10.8: seq=2 ttl=64 time=0.710 ms
64 bytes from 10.10.10.8: seq=3 ttl=64 time=0.587 ms
64 bytes from 10.10.10.8: seq=4 ttl=64 time=0.706 ms
64 bytes from 10.10.10.8: seq=5 ttl=64 time=0.555 ms

Swarm还内置了DNS服务。将service name作为service的DNS,就可以访问到这个service了
创建另一个服务:

[root@swarm-m ~]# docker service create --name webapp-test --replicas 1 --network my-overlay-network --publish 9089:80 linuxserver/nginx
a7557hfsyh60t2km2g839irvy
overall progress: 1 out of 1 tasks 
1/1: running   [==================================================>] 
verify: Service converged 
[root@swarm-m ~]# docker service ps webapp-test 
ID                  NAME                IMAGE                      NODE                    DESIRED STATE       CURRENT STATE            ERROR               PORTS
kdhw9ykrmxo3        webapp-test.1       linuxserver/nginx:latest   swarm-m.nahong.com.cn   Running             Running 26 seconds ago                       

查看现有的服务 docker service ls

[root@swarm-m ~]# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                      PORTS
n9bg26g83dd9        webapp-nginx        replicated          3/3                 linuxserver/nginx:latest   *:8089->80/tcp
a7557hfsyh60        webapp-test         replicated          1/1                 linuxserver/nginx:latest   *:9089->80/tcp

在webapp-test容器ping 服务名webapp-nginx

[root@swarm-m ~]# docker ps
CONTAINER ID        IMAGE                      COMMAND             CREATED             STATUS              PORTS               NAMES
30ef88e05ed4        linuxserver/nginx:latest   "/init"             3 minutes ago       Up 3 minutes        80/tcp, 443/tcp     webapp-test.1.kdhw9ykrmxo36i7ldu4a43uaz
d412b3ce543e        linuxserver/nginx:latest   "/init"             About an hour ago   Up About an hour    80/tcp, 443/tcp     webapp-nginx.2.k26fewhj9lzqpva03zv6mgtpm
[root@swarm-m ~]# docker exec 30ef88e05ed4 ifconfig | grep -A 1 eth1
eth1      Link encap:Ethernet  HWaddr 02:42:0A:0A:0A:0A  
          inet addr:10.10.10.10  Bcast:10.10.10.255  Mask:255.255.255.0
[root@swarm-m ~]# docker exec 30ef88e05ed4 ping webapp-nginx
PING webapp-nginx (10.10.10.5): 56 data bytes
64 bytes from 10.10.10.5: seq=0 ttl=64 time=0.259 ms
64 bytes from 10.10.10.5: seq=1 ttl=64 time=0.149 ms
64 bytes from 10.10.10.5: seq=2 ttl=64 time=0.153 ms
64 bytes from 10.10.10.5: seq=3 ttl=64 time=0.137 ms
64 bytes from 10.10.10.5: seq=4 ttl=64 time=0.135 ms

可以看到它们使用了同一个自定义网络 10.10.10.10,但是webapp-nginx解析的IP和之前的不一样,这应该是swarm内部负载均衡的机制

负载均衡
负载均衡分为两种:Swarm集群内的service之间的相互访问需要做负载均衡,称为内部负载均衡(Internal LB);从Swarm集群外部访问服务的公开端口,也需要做负载均衡,称外部部负载均衡(Exteral LB or Ingress LB)

Internal LB
内部负载均衡就是集群内部通过DNS访问service时,Swarm默认通过VIP(virtual IP)、iptables、IPVS转发到某个容器


Docker Swarm集群搭建_第3张图片
图片来源网络

Exteral LB(Ingress LB)
外部负载均衡和Ingress网络有关。Swarm网络要提供对外访问的服务就需要打开公开端口,并映射到宿主机。Ingress LB就是外部通过公开端口访问集群时做的负载均衡。

Docker Swarm集群搭建_第4张图片
图片来源网络

上图是三个节点的Swarm集群,app服务公开了8000端口,并且有两个副;虽然服务只有两个副本,分别在A、B两台主机上,但是访问C主机的8000端口,ingress网络会通过IPVS将请求转到A、B之一的容器中处理,依然可以对外提供服务这就是 routing mesh 的作用。

reference
docker swarm mode的服务发现和LB详解

你可能感兴趣的:(Docker Swarm集群搭建)