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進行負載均衡
相關文章
相關標籤/搜索