ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Docker Swarm(一)

2021-04-25 11:01:36  阅读:212  来源: 互联网

标签:docker service busybox Swarm Running Docker 节点 latest


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

Docker Compose一般只适用于开发环境,而对于生产环境下的项目部署,我们需要用到Docker Swarm。

Docker Swarm介绍

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

架构如下:

在这里插入图片描述

  • swarm节点:

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

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。

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

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

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

  • 多主机网络:

对于单主机网络,所有的容器都运行在一个docker主机上,他们之间的通信一般使用本地的bridge network即可。

而对于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集群。

  • 角色划分:
roleiphostname
manager192.168.30.128test1
worker1192.168.30.129test2
worker2192.168.30.130test3
  • 环境准备:
# 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进行负载均衡


标签:docker,service,busybox,Swarm,Running,Docker,节点,latest
来源: https://blog.51cto.com/u_10272167/2730577

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有