Docker Swarm(一)

即便有了Docker Compose,项目的部署仍然存在问题,由于Docker Compose只能把项目全部的容器部署在同一台机器上,这在生产环境下是不现实的。html

Docker Compose通常只适用于开发环境,而对于生产环境下的项目部署,咱们须要用到Docker Swarm。node

Docker Swarm介绍

Docker Swarm是Docker官方提供的一套容器编排系统,它将一组Docker主机虚拟成一个单独的虚拟Docker主机。mysql

架构以下:linux

在这里插入图片描述

  • swarm节点:

swarm是一系列节点的集合,而节点能够是一台裸机或者一台虚拟机。一个节点能扮演一个或者两个角色,manager或者worker。sql

manager
    Docker Swarm集群须要至少一个manager节点,节点之间使用Raft consensus protocol进行协同工做。
    一般,第一个启用docker swarm的节点将成为leader,后来加入的都是follower。当前的leader若是挂掉,
    剩余的节点将从新选举出一个新的leader。每个manager都有一个完整的当前集群状态的副本,能够保证manager的高可用。

worker
    worker节点是运行实际应用服务的容器所在的地方。理论上,一个manager节点也能同时成为worker节点,但在生产环境中,
    咱们不建议这样作。worker节点之间,经过control plane进行通讯,这种通讯使用gossip协议,而且是异步的。

  • task、service、stack:

多个tasks组成一个service,多个services组成一个stack。docker

task
    在Docker Swarm中,task是一个部署的最小单元,task与容器是一对一的关系。

service
    swarm service是一个抽象的概念,它只是一个对运行在swarm集群上的应用服务,所指望状态的描述。
    它就像一个描述了下面物品的清单列表同样:
        服务名称
        使用哪一个镜像来建立容器
        要运行多少个副本
        服务的容器要链接到哪一个网络上
        须要映射哪些端口

stack
    stack是描述一系列相关services的集合,能够经过在一个YAML文件中来定义一个stack,相似于docker-compose。

  • 多主机网络:

对于单主机网络,全部的容器都运行在一个docker主机上,他们之间的通讯通常使用本地的bridge network便可。centos

而对于swarm集群,针对的是一组docker主机,须要使用docker的overlay network。浏览器


经常使用命令

  • docker swarm命令:
ca          显示根CA证书

init        初始化一个集群

join        加入集群

join-token worker   查看工做节点的token

join-token manager  查看管理节点的token

leave       离开集群

unlock      解锁集群

unlock-key  管理解锁密钥

update      更新集群

  • docker node命令:
demote      节点降级,由管理节点降级为工做节点

inspect	    查看一个或多个节点的详情

ls	        查看全部的节点

promote     节点升级,由工做节点升级为管理节点

ps	        查看一个或多个节点中的task,默认为当前节点

rm	        删除一个或多个节点

update      更新一个节点

  • docker service命令:
create      建立一个新的service

inspect     查看一个或多个service的详情

logs        获取service或task的日志

ls          列出全部的service

ps          列出一个或多个service的task

rm          删除一个或多个service

rollback    将更改还原为service的配置

scale       建立一个或多个service的副本

update      更新一个service

  • docker stack命令:
deploy      部署新的stack或更新现有stack

ls          列出现有stack

ps          列出stack中的tasks

rm          删除一个或多个stack

services    列出stack中的services

注意:以上命令大多只能在manager节点上执行。网络


Swarm集群建立

根据集群的高可用性要求实现奇数个节点。当有两个以上manager节点时,集群能够manager节点的故障中恢复,而无需停机。架构

N个manager节点的集群将最多容忍(N-1) / 2个manager节点的丢失。

下面建立一个三节点的swarm集群。

  • 角色划分:
role ip hostname
manager 192.168.30.128 test1
worker1 192.168.30.129 test2
worker2 192.168.30.130 test3
  • 环境准备:
# systemctl stop firewalld && systemctl disable firewalld# sed -i 's/=enforcing/=disabled/g' /etc/selinux/config && setenforce 0

  • 安装docker:
# curl http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker.repo# yum makecache fast# yum install -y docker-ce# systemctl start docker && systemctl enable docker

  • 建立集群:

注意:swarm集群必须先在manager节点进行集群初始化,而后在worker节点上加入集群。

192.168.30.128

# docker swarm init --advertise-addr=192.168.30.128Swarm initialized: current node (q1n9ztahdj489pltf3gl5pomj) is now a manager.

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

    docker swarm join --token SWMTKN-1-38ci507e4fyp92oauqvov5axo3qhti5wlm58odjz5lo2rdatyo-e2y52gxq7y40mah2nzq1b5fg9 192.168.30.128:2377

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

将添加worker节点的命令复制到其它非manager节点的机器执行

192.168.30.129

# docker swarm join --token SWMTKN-1-38ci507e4fyp92oauqvov5axo3qhti5wlm58odjz5lo2rdatyo-e2y52gxq7y40mah2nzq1b5fg9 192.168.30.128:2377This node joined a swarm as a worker.

192.168.30.130

# docker swarm join --token SWMTKN-1-38ci507e4fyp92oauqvov5axo3qhti5wlm58odjz5lo2rdatyo-e2y52gxq7y40mah2nzq1b5fg9 192.168.30.128:2377This node joined a swarm as a worker.

  • 查看集群节点:

192.168.30.128

# docker node lsID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
q1n9ztahdj489pltf3gl5pomj *   test1               Ready               Active              Leader              19.03.3
0qyp2ut4m3pggag1yq7f3jn31     test2               Ready               Active                                  19.03.4
cbi8detm7t9v8w5ntyzid0cvj     test3               Ready               Active                                  19.03.4

能够看到,一个三节点的swarm集群建立完毕,test1(192.168.30.128)为manager节点。


Docker Service

在Docker Swarm集群中,咱们能够经过docker service命令建立一些service,每一个service都包含多个tasks,每一个task对应一个容器。

  • 建立service:

192.168.30.128

# docker service create --name busybox busybox:latest sh -c "while true; do sleep 3600; done"y8o6jogs0iyp4qewb5okgzb37
overall progress: 1 out of 1 tasks 
1/1: running
verify: Service converged# docker service lsID                  NAME                MODE                REPLICAS            IMAGE               PORTS
y8o6jogs0iyp        busybox             replicated          1/1                 busybox:latest# docker service ps busybox ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE                ERROR               PORTS
mavy3blpmzvz        busybox.1           busybox:latest      test2               Running             Running about a minute ago

能够看到,该service的task运行在test2(192.168.30.129)上

192.168.30.129

# docker psCONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
3dd48d9541ca        busybox:latest      "sh -c 'while true; …"   2 minutes ago       Up 2 minutes                            busybox.1.mavy3blpmzvzka1ks1ebuz3s4

  • 水平扩展:

当前busybox这个service的task只有1个,扩展为5个。

192.168.30.128

# docker service scale busybox=5busybox scaled to 5
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# docker service lsID                  NAME                MODE                REPLICAS            IMAGE               PORTS
y8o6jogs0iyp        busybox             replicated          5/5                 busybox:latest# docker service ps busybox ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS
mavy3blpmzvz        busybox.1           busybox:latest      test2               Running             Running 4 minutes ago                        
gxg5gt2j5a1v        busybox.2           busybox:latest      test1               Running             Running 20 seconds ago                       
okge105yuzb8        busybox.3           busybox:latest      test2               Running             Running 25 seconds ago                       
b86rr94bbotj        busybox.4           busybox:latest      test3               Running             Running 22 seconds ago                       
8zogu5kacnpw        busybox.5           busybox:latest      test1               Running             Running 20 seconds ago

能够看到,该service的task分别运行在集群的3个节点上。

  • 故障恢复:

当某个task对应的容器挂掉时,会自动在任一节点启动该task对应的容器。

192.168.30.128

# docker rm -f 7d013a7eb6857d013a7eb685# docker service ps busybox ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE            ERROR                         PORTS
mavy3blpmzvz        busybox.1           busybox:latest      test2               Running             Running 11 minutes ago                                 
jewllc9gywpa        busybox.2           busybox:latest      test3               Ready               Ready 3 seconds ago                                    
gxg5gt2j5a1v         \_ busybox.2       busybox:latest      test1               Shutdown            Failed 3 seconds ago     "task: non-zero exit (137)"   okge105yuzb8        busybox.3           busybox:latest      test2               Running             Running 7 minutes ago                                  
b86rr94bbotj        busybox.4           busybox:latest      test3               Running             Running 7 minutes ago                                  
8zogu5kacnpw        busybox.5           busybox:latest      test1               Running             Running 7 minutes ago                                  

# docker service lsID                  NAME                MODE                REPLICAS            IMAGE               PORTS
y8o6jogs0iyp        busybox             replicated          5/5                 busybox:latest

能够看到,test1(192.168.30.128)上强制删除的容器在test3(192.168.30.130)上从新启动。

192.168.30.130

# docker psCONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
05efd68e06c5        busybox:latest      "sh -c 'while true; …"   2 minutes ago       Up About a minute                       busybox.2.jewllc9gywpaude65rmc87wka
629fe2d2b396        busybox:latest      "sh -c 'while true; …"   9 minutes ago       Up 9 minutes                            busybox.4.b86rr94bbotj1fhyk7owwt2tl

故障恢复能够保证咱们的service是稳定有效的。

  • 删除service:

192.168.30.128

# docker service lsID                  NAME                MODE                REPLICAS            IMAGE               PORTS
y8o6jogs0iyp        busybox             replicated          5/5                 busybox:latest      

# docker service rm busybox busybox# docker service lsID                  NAME                MODE                REPLICAS            IMAGE               PORTS# docker ps -aCONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

192.168.30.129

# docker ps -aCONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

192.168.30.130

# docker ps -aCONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

当删除service后,该service对应的task容器也会中止运行并删除。


Docker Service 示例

若是在swarm集群中部署项目,首先须要建立的是overlay network,由于项目中关联的services须要经过overlay network通讯。

在swarm集群中建立overlay network,再也不须要外部的分布式存储(如etcd),swarm集群会自动完成overlay network的同步工做。

下面使用Docker Service部署wordpress项目,该项目包含两个service:wordpress和mysql。

  • 建立overlay network:

192.168.30.128

# docker network lsNETWORK ID          NAME                DRIVER              SCOPE
5ee1b278fd34        bridge              bridge              local
faf258f504b0        docker_gwbridge     bridge              local
535808221d2e        host                host                local
5yetwtzg2b1x        ingress             overlay             swarm
2addad8d8857        none                null                local# docker network create -d overlay testexyl7ksbeavt00c5ot0k66s2w# docker network lsNETWORK ID          NAME                DRIVER              SCOPE
5ee1b278fd34        bridge              bridge              local
faf258f504b0        docker_gwbridge     bridge              local
535808221d2e        host                host                local
5yetwtzg2b1x        ingress             overlay             swarm
2addad8d8857        none                null                local
exyl7ksbeavt        test                overlay             swarm

  • 建立mysql service:

192.168.30.128

# docker service create --name mysql --network test -e MYSQL_ROOT_PASSWORD=123456789 -e MYSQL_DATABASE=wordpress --mount type=volume,source=mysql_data,destination=/var/lib/mysql mysql:5.73bjl5kse0letilvkx0kltnfm9
overall progress: 1 out of 1 tasks 
1/1: running   [==================================================>] verify: Service converged

# docker service lsID                  NAME                MODE                REPLICAS            IMAGE               PORTS
3bjl5kse0let        mysql               replicated          1/1                 mysql:5.7           

# docker service ps mysql ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE                ERROR               PORTS
d8ofaptycyzs        mysql.1             mysql:5.7           test3               Running             Running about a minute ago

  • 建立wordpress service:

192.168.30.128

# docker service create --name wordpress --network test -p 80:80 -e WORDPRESS_DB_PASSWORD=123456789 -e WORDPRESS_DB_HOST=mysql wordpressx96xdiazi4iupgvwl5oza4sx3
overall progress: 1 out of 1 tasks 
1/1: running   [==================================================>] verify: Service converged

# docker service lsID                  NAME                MODE                REPLICAS            IMAGE               PORTS
3bjl5kse0let        mysql               replicated          1/1                 mysql:5.7           
x96xdiazi4iu        wordpress           replicated          1/1                 wordpress:latest    *:80->80/tcp# docker service ps wordpress ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS
8b9g1upsll15        wordpress.1         wordpress:latest    test1               Running             Running 36 seconds ago

能够看到,mysql这个service的task容器运行在test3(192.168.30.130)上,而wordpress这个服务的task容器运行在test1(192.168.30.128)上。

  • 查看容器:

192.168.30.128

# docker psCONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
e189db13cbe3        wordpress:latest    "docker-entrypoint.s…"   About a minute ago   Up About a minute   80/tcp              wordpress.1.8b9g1upsll15m8crlhkebgc64

192.168.30.130

# docker psCONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                 NAMES
6be947ccfe36        mysql:5.7           "docker-entrypoint.s…"   3 minutes ago       Up 3 minutes        3306/tcp, 33060/tcp   mysql.1.d8ofaptycyzs01ckt6k2zhxd7

  • 浏览器访问:

打开浏览器访问192.168.30.128

在这里插入图片描述

填写信息后直接登陆,能够看看wordpress站点

在这里插入图片描述

在这里插入图片描述

经过overlay network,在swarm集群中使用docker service部署wordpress项目成功。


Routing Mesh

  • 浏览器访问:

继续使用浏览器,分别访问192.168.30.129192.168.30.130

在这里插入图片描述

在这里插入图片描述

这是为何呢?这就是Routing Mesh的做用。若是service有绑定端口,则该service可经过任意swarm节点的相应端口访问。

  • 示例:

建立whoami service

# docker service create --name whoami --network test -p 8000:8000 jwilder/whoamickgqv2okq5wdscgv0pihk2hwr
overall progress: 1 out of 1 tasks 
1/1: running   [==================================================>] verify: Service converged# docker service scale whoami=3whoami scaled to 3
overall progress: 3 out of 3 tasks 
1/3: running   [==================================================>] 2/3: running   [==================================================>] 3/3: running   [==================================================>] verify: Service converged

# docker service lsID                  NAME                MODE                REPLICAS            IMAGE                   PORTS
3bjl5kse0let        mysql               replicated          1/1                 mysql:5.7               
ckgqv2okq5wd        whoami              replicated          3/3                 jwilder/whoami:latest   *:8000->8000/tcp
x96xdiazi4iu        wordpress           replicated          1/1                 wordpress:latest        *:80->80/tcp# docker service ps whoami ID                  NAME                IMAGE                   NODE                DESIRED STATE       CURRENT STATE                ERROR               PORTS
ugndxn4ojkw4        whoami.1            jwilder/whoami:latest   test2               Running             Running 2 minutes ago                            
iv3cu975hpr4        whoami.2            jwilder/whoami:latest   test1               Running             Running about a minute ago                       
qc5kp773iof7        whoami.3            jwilder/whoami:latest   test3               Running             Running about a minute ago

建立busybox service

# docker service create --name busybox --network test busybox sh -c "while true; do sleep 3600; done"bxy6hzvrfoxy28yyagzvkfqmf
overall progress: 1 out of 1 tasks 
1/1: running   [==================================================>] verify: Service converged# docker service ps busybox ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS
rewjvfn34qq9        busybox.1           busybox:latest      test2               Running             Running 23 seconds ago

192.168.30.129

# docker psCONTAINER ID        IMAGE                   COMMAND                  CREATED              STATUS              PORTS               NAMES
933d4e916cbd        busybox:latest          "sh -c 'while true; …"   About a minute ago   Up About a minute                       busybox.1.rewjvfn34qq9tbrn2dty4e6vf
7b28da1c9491        jwilder/whoami:latest   "/app/http"              5 minutes ago        Up 5 minutes        8000/tcp            whoami.1.ugndxn4ojkw42u6y22rfdjlii# docker exec -it busybox.1.rewjvfn34qq9tbrn2dty4e6vf sh/ # ping whoamiPING whoami (10.0.0.17): 56 data bytes
64 bytes from 10.0.0.17: seq=0 ttl=64 time=0.192 ms
64 bytes from 10.0.0.17: seq=1 ttl=64 time=0.353 ms
64 bytes from 10.0.0.17: seq=2 ttl=64 time=0.144 ms
64 bytes from 10.0.0.17: seq=3 ttl=64 time=0.144 ms
^C
--- whoami ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.144/0.208/0.353 ms

前面启动了3个whoami的task容器,为何在busybox中ping whoami时,始终只返回一个ip呢?

/ # nslookup whoamiServer:		127.0.0.11
Address:	127.0.0.11:53

Non-authoritative answer:

*** Can't find whoami: No answer

/ # nslookup tasks.whoami 127.0.0.11
Server:		127.0.0.11
Address:	127.0.0.11:53

Non-authoritative answer:
Name:	tasks.whoami
Address: 10.0.0.18
Name:	tasks.whoami
Address: 10.0.0.21
Name:	tasks.whoami
Address: 10.0.0.20

*** Can't find tasks.whoami: No answer

这回看到3个ip:10.0.0.1810.0.0.2110.0.0.20,分别在进入各个whoami的容器内查看ip可知,这3个ip就是whoami容器的真实ip,而咱们ping whoami获得的ip10.0.0.17是一个虚拟ip(vip)。

对于一个service来讲,它的vip通常是不变的,在水平扩展时发生变化的是vip后面的task容器ip。

任选一个节点,

# curl 127.0.0.1:8000I'm ae9da507e9f7

# curl 127.0.0.1:8000
I'm 5e4782fd9dee# curl 127.0.0.1:8000I'm 7b28da1c9491

# curl 127.0.0.1:8000
I'm ae9da507e9f7# curl 127.0.0.1:8000I'm 5e4782fd9dee

# curl 127.0.0.1:8000
I'm 7b28da1c9491

经过连续curl返回的内容能够看到,每次返回的结果是不一样的hostname,而且是轮询返回,这就造成了负载均衡。

其实routing mesh内部根据LVS(Linux Virtual Server)来实现的,经过vip达到负载均衡的目的。

  • routing mesh的两种体现:
Internal
    容器和容器之间的访问经过overlay网络(经过VIP)
    
Ingress
    若是service有绑定端口,则此service可经过任意swarm节点的相应端口访问

  • routing mesh的做用:
外部访问的负载均衡

服务端口被暴露到各个swarm节点

内部经过LVS进行负载均衡
相关文章
相关标签/搜索