1. 程式人生 > >Docker swarm部署

Docker swarm部署

docker swarm 部署

本教程將介紹 Docker Engine Swarm 模式。先介紹 swarm 模式幾個關鍵的概念,然後通過動手實踐帶你體驗一下 swarm 模式。

幾個關鍵概念

Swarm

Docker Engline 中集成的集群管理和編排功能都是基於 SwarmKit 實現。參與到集群中的 Docker Engine 會進入 swarm 模式。比如初始化一個 swarm 或加入已有的 swarm。

一個 swarm 就是個一個 Docker Engine 集群,你可以在上面部署服務。Docker Engine CLI 提供了用於 swarm 管理的命令,比如添加或移除一個節點。同樣還提供了用於部署服務到 swarm 和管理服務編排的命令。

當 Docker Engine 運行在 swarm 模式時,你管理容器。當 Docker Engine 運行在 swarm 模式時,你編排服務。

節點

每個參與到 swarm 中的 Docker Engine 都稱之為一個節點。

將服務的定義提交到管理節點即可將應用部署到 swarm。然後管理節點將叫作任務的工作單元分發到工作節點。

為了維持 swarm 的目標狀態,管理節點還將承當編排和集群管理的功能。一般有多個管理節點,它們之間會選出一個領導來進行編排任務。

工作節點接收並執行來自管理節點分發的任務。默認情況下,管理節點也是工作節點,你可以把它配置成只當管理節點。代理通知管理節點已分配任務的當前狀態,以便管理節點維護所需的狀態。

服務和任務

服務定義了需要在工作節點上執行的任務。它是 swarm 系統的中心結構,也是用戶和 swarm 交互的主要根源。

服務包括要使用的容器鏡像,以及在容器中執行的指令。

對於復制服務,管理節點根據服務的規模和目標狀態將一定數量的任務副本分發到各節點上。

對於全局服務,每個節點上都將分發一個任務副本。

任務包含一個容器和需要在容器中執行的指令。它是 swarm 原子調度單位。管理節點根據服務規模中定義的副本數量將任務分配給工作節點。一旦某個任務被分配到某個節點,就不能再移動到其他節點。它只能在分配的節點上運行或者失敗。

負載均衡

swarm 管理節點使用 入口負載均衡 的方式暴露你想要讓外部訪問的服務。Swarm 管理節點可以自動將一個服務分配到某個 發布端口

,或者你可以為服務指定一個發布端口。你可以指定任意未使用的端口。如果你沒指定端口,swarm 管理節點將為服務指定一個 30000-32757 之間的端口。

外部組件,比如雲負載均衡器,可以通過集群中的任意節點訪問發布端口上的服務,不管當前節點上是否有服務對應的任務在運行,swarm 中的所有節點都會將進入連接路由到正在運行任務的實例上。

Swarm 模式有一個內置的 DNS 組件,它會自動給 swarm 中的每個服務分配一個 DNS 條目。Swarm 管理器使用internal load balancing 基於服務對應的 DNS 名稱在服務之間分發請求。

開始實踐

本教程將指導你完成以下任務:

  • 在 Docker Engline swarm 模式下初始化一個集群

  • 添加節點到 swarm

  • 部署服務到 swarm

  • 在一切就緒後管理 swarm

準備工作

在開始本教程之前,你需要準備一下幾樣東西:

  • 三臺通過網絡連接的主機

  • 每臺主機安裝 Docker Engine 1.12 或更新版本

  • 充當管理節點的主機 IP

  • 主機之間開放下面提到的端口

主機之間端口開放

主機之間的以下端口必須是開放。某些環境下,這些端口默認是允許的:

  • TCP 端口 2377 用於集群管理通信(管理節點)

  • TCP 和 UDP 端口 7946 用於節點間通信(所有節點)

  • TCP 和 UDP 端口 4789 用於 overlay 網絡流量(所有節點)

如果你的這些端口沒有打開,可以用iptables命令打開它們:

iptables -A INPUT -p tcp --dport 2377 -j ACCEPT
iptables -A INPUT -p tcp --dport 7946 -j ACCEPT
iptables -A INPUT -p udp --dport 7946 -j ACCEPT
iptables -A INPUT -p tcp --dport 4789 -j ACCEPT
iptables -A INPUT -p udp --dport 4789 -j ACCEPT





192.168.33.160 swarm_manager

192.168.33.161 node1

192.168.33.162 node2

創建 swarm

創建一個 swarm

隨意選擇一個主機作為管理節點,在上面初始化一個 swarm:

[root@swarm_manager ~]# docker swarm init --advertise-addr 192.168.33.160
Swarm initialized: current node (7ik7wqhe5wcag8k5tp816c7ck) is now a manager.

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

    docker swarm join \    --token SWMTKN-1-0p0p5f96e1w4xblhw2eeookrv46spwf4yx7qmve2srxe9wec5g-ellbnyt4cwwvvdkssaj0cbtus     192.168.33.160:2377


--advertise-addr 標誌配置了管理節點的 IP 地址。如果你的機器只有一個 IP 地址,可以省略--adbertise-addr選項,docker 會自動選擇正確的 IP。上輸出信息說明了怎樣加入新的工作節點。也說明了執行docker swarm join-token manager 可以查詢怎樣加入新的管理節點。


執行docker info命令查看swarm的當前狀態

[root@swarm_manager ~]# docker info
...
Swarm: active
 NodeID: 7ik7wqhe5wcag8k5tp816c7ck
 Is Manager: true
 ClusterID: 2scd04fv8c9mua1jiaq6n0370
 Managers: 1
 Nodes: 1
 ...
 
 執行 docker node ls 命令查看節點信息
 
[root@swarm_manager ~]# docker node ls
ID                           HOSTNAME       STATUS  AVAILABILITY  MANAGER STATUS     
9e21bk67ey1abzje69lmpvbe1 *  swarm_manager  Ready   Active        Leader

節點 id 後面的*表示你當前連接到了該節點。

添加節點到 swarm

添加兩個工作節點到swarm

在第二臺主機上,執行前面創建 swarmdocker swarm init 輸出信息中命令創建工作節點並加入到 swarm

[root@node1 ~]# docker swarm join \     
       --token SWMTKN-1-0p0p5f96e1w4xblhw2eeookrv46spwf4yx7qmve2srxe9wec5g-ellbnyt4cwwvvdkssaj0cbtus      192.168.33.160:2377
     This node joined a swarm as a worker.

輸出信息表示當前節點已是 swarm 中的一個工作節點了。如果你忘記了該命令,可以在管理節點上執行 docker swarm join-token worker 查詢怎麽加入。

[root@swarm_manager ~]# docker swarm join-token worker 
To add a worker to this swarm, run the following command:

    docker swarm join \    --token SWMTKN-1-3wi7tszkolocsbc7vopv1tfx2r2h1owtqegwevdqqdk3fj195u-ejpeq0afjvfmujlvzboux9zjs     192.168.33.160:2377

到第三臺主機上,繼續講第三臺主機加入到 swarm

[root@node1 ~]# docker swarm join \     
       --token SWMTKN-1-0p0p5f96e1w4xblhw2eeookrv46spwf4yx7qmve2srxe9wec5g-ellbnyt4cwwvvdkssaj0cbtus      192.168.59.128:2377
     This node joined a swarm as a worker.

查看所有節點的狀態

在管理節點上

[root@swarm_manager ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
622ih8ji5t428lazjx233pvks node2 Ready Active
9e21bk67ey1abzje69lmpvbe1 * swarm_manager Ready Active Leader
f3wzagmtgsn8qyqzidxtw98d3 node1 Ready Active

輸出信息第二行 id 後面的*表示當前連接到了該節點。HOSTNAME 欄輸出節點的 hostname。MANAGER 用於指示 swarm中的管理節點,該欄值為 Leader 表示為管理節點,空值表示為工作節點。


部署一個服務到 swarm

創建服務

在管理節點上創建一個服務,每隔三秒輸出一個 “hello world”:

[root@swarm_manager ~]# docker service create --replicas 1 --name helloworld busybox:1.25.1-musl /bin/sh -c "while true; do echo hello world; sleep 3; done"
04a3iqg8zlhba84kpi2tatssf


  • docker service create 命令創建服務。

  • --name 標誌將服務命名為helloworld

  • --replicas 標誌指定了期望狀態為 1 個運行示例。

  • 參數 busybox:1.25.1-musl /bin/sh -c "while true; do echo hello world; sleep 3; done 將服務定義為使用鏡像busybox:1.25.1-musl 創建容器,並在裏面執行 /bin/sh -c "while true; do echo hello world; sleep 3; done

查看服務列表

還是在管理節點上

[root@swarm_manager ~]# docker service ls
ID            NAME        REPLICAS  IMAGE                COMMAND
c3hvgwhyim4n  helloworld  1/1       busybox:1.25.1-musl  /bin/sh -c while true; do echo hello world; sleep 3; done

查看服務的詳細信息

查看服務的詳細信息

在管理節點上。

[root@swarm_manager ~]# docker service inspect --pretty helloworld
ID:        c3hvgwhyim4nllg1qqix7kli6
Name:        helloworld
Mode:        Replicated
 Replicas:    1
Placement:
UpdateConfig:
 Parallelism:    1
 On failure:    pause
ContainerSpec:
 Image:        busybox:1.25.1-musl
 Args:        /bin/sh -c while true; do echo hello world; sleep 3; done
Resources:

參數--pretty表示以可讀性良好的格式輸出。如果想輸出詳細的 json 格式信息,去掉--pretty參數即可。



查看哪個節點在運行該服務

還是在管理節點上:

[root@swarm_manager ~]# docker service ps helloworld
ID                         NAME          IMAGE                NODE   DESIRED STATE  CURRENT STATE          ERROR
556c2lpvr4489yrclo52cjlo5  helloworld.1  busybox:1.25.1-musl  node2  Running        Running 3 minutes ago

輸出信息表明,helloworld 服務的一個實例在 node2 節點上執行。這是因為,默認情況下管理節點是工作節點。

DESIRED STATECURRENT STATE表示服務的期望狀態和當前狀態,你可以對比它們,判斷服務是否想期望的那樣運行。這裏的RunningRunning 3 minutes ago說明服務運行正常。

在執行任務的節點上使用docker ps命令查看相關容器的詳細信息

[root@node2 ~]# docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS               NAMES
964ddb3220b6        busybox:1.25.1-musl   "/bin/sh -c ‘while tr"   5 minutes ago       Up 5 minutes                            helloworld.1.556c2lpvr4489yrclo52cjlo5

伸縮服務

伸縮服務的任務數量

在管理節點上

[root@node2 ~]# docker service scale helloworld=5
helloworld scaled to 5
我們將服務的數量伸縮到5。

查看服務列表

在管理節點上:

[root@swarm_manager ~]# docker service ps helloworld 
ID                         NAME          IMAGE                NODE           DESIRED STATE  CURRENT STATE           ERROR
556c2lpvr4489yrclo52cjlo5  helloworld.1  busybox:1.25.1-musl  node2          Running        Running 10 minutes ago  
e2tw7i9bkjb32jrr3sdztskwe  helloworld.2  busybox:1.25.1-musl  swarm_manager  Running        Running 24 seconds ago  
d5plppbjvtr1rany4tzb88czc  helloworld.3  busybox:1.25.1-musl  node2          Running        Running 28 seconds ago  
a0hs8ik837jl7mlgeaowws1i3  helloworld.4  busybox:1.25.1-musl  node1          Running        Running 18 seconds ago  
bo27jnf7n59hqzl9m9jnpwbks  helloworld.5  busybox:1.25.1-musl  swarm_manager  Running        Running 24 seconds ago

在各節點上查看服務

首先是管理節點:

[root@swarm_manager ~]# docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED              STATUS              PORTS               NAMES
46aa83031ad7        busybox:1.25.1-musl   "/bin/sh -c ‘while tr"   About a minute ago   Up About a minute                       helloworld.2.e2tw7i9bkjb32jrr3sdztskwe
e1cb3bd1bfb0        busybox:1.25.1-musl   "/bin/sh -c ‘while tr"   About a minute ago   Up About a minute                       helloworld.5.bo27jnf7n59hqzl9m9jnpwbks

再是工作節點1

[root@node1 ~]# docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED              STATUS                  PORTS               NAMES
1c200722ace5        busybox:1.25.1-musl   "/bin/sh -c ‘while tr"   About a minute ago   Up About a minute                           helloworld.4.a0hs8ik837jl7mlgeaowws1i3

再是工作節點2

[root@node2 ~]# docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED              STATUS              PORTS               NAMES
2dba702ccd68        busybox:1.25.1-musl   "/bin/sh -c ‘while tr"   About a minute ago   Up About a minute                       helloworld.3.d5plppbjvtr1rany4tzb88czc
964ddb3220b6        busybox:1.25.1-musl   "/bin/sh -c ‘while tr"   11 minutes ago       Up 11 minutes                           helloworld.1.556c2lpvr4489yrclo52cjlo5

可以看到:管理節點上運行了兩個任務,工作節點1運行了兩個任務,工作節點2運行了1個任務。

刪除 swarm 上運行的服務

刪除

在管理節點上

[root@swarm_manager ~]# docker service rm helloworld
helloworld

確認

在管理節點上

[root@swarm_manager ~]# docker service ls
ID NAME REPLICAS IMAGE COMMAND
[root@swarm_manager ~]#

看不到任何服務了。


滾動更新

在這部分,我們將部署一個基於 Rddis 3.07 鏡像的服務。然後使用滾動更新將服務更新到使用 Redis 3.2.5 鏡像。

swarm中部署 Redis 3.0.7,並配置 10 秒更新延遲

[root@swarm_manager ~]# docker service create --replicas 3 --name redis --update-delay 10s redis:3.0.7-alpine
6vw26iief1y2nxmi6a01tzco6

我們在部署服務指定滾動更新策略。--update-delay 表示更新服務對應的任務或一組任務之間的時間間隔。時間間隔用數字和時間單位表示,m 表示分,h 表示時,所以 10m30s 表示 10 分 30 秒的延時。

默認情況下,調度器一次更新一個任務。你可以使用 --update-parallelism 標誌配置調度器每次同時更新的最大任務數量。

默認情況下,如果更新某個任務返回了RUNNING狀態,調度器會轉去更新另一個任務,直到所有任務都更新完成。如果在更新某個任務的任意時刻返回了FAILED,調度器暫停更新。我們可以在執行 docker service create 命令和 docker service update 命令時使用 --update-failure-action 標誌來覆蓋這種默認行為。

查看redis服務

[root@swarm_manager ~]# docker service inspect --pretty redis
ID:        6vw26iief1y2nxmi6a01tzco6
Name:        redis
Mode:        Replicated
 Replicas:    3
Placement:
UpdateConfig:
 Parallelism:    1
 Delay:        10s
 On failure:    pause
ContainerSpec:
 Image:        redis:3.0.7-alpine
Resources:

更新redis服務使用的容器鏡像

swarm管理節點會根據UpdateConfig策略來更新節點

[root@swarm_manager ~]# docker service update --image redis:3.2.5-alpine redis 
redis

調度器根據下面默認的策略來應用滾動更新:

  • 停止第一個任務。

  • 為停止的任務應用更新。

  • 為更新的任務啟動容器。

  • 如果更新任務時返回RUNNING,等待一個指定的延時後停止下一個任務。

  • 如果,在更新的任意時刻,某個任務返回FAILED,暫停更新。

查看新鏡像的狀態

[root@swarm_manager ~]# docker service update --image redis:3.2.5-alpine redis 
redis
[root@swarm_manager ~]# docker service inspect --pretty redis
ID:        6vw26iief1y2nxmi6a01tzco6
Name:        redis
Mode:        Replicated
 Replicas:    3
Update status:
 State:        updating
 Started:    46 seconds ago
 Message:    update in progress
Placement:
UpdateConfig:
 Parallelism:    1
 Delay:        10s
 On failure:    pause
ContainerSpec:
 Image:        redis:3.2.5-alpine
Resources:

可以看到 redis 服務的鏡像已經變成了redis:3.2.5-alpine。不過狀態還在更新中。過一會再查看:

[root@swarm_manager ~]# docker service inspect --pretty redis
ID:        6vw26iief1y2nxmi6a01tzco6
Name:        redis
Mode:        Replicated
 Replicas:    3
Update status:
 State:        completed
 Started:    2 minutes ago
 Completed:    about a minute ago
 Message:    update completed
Placement:
UpdateConfig:
 Parallelism:    1
 Delay:        10s
 On failure:    pause
ContainerSpec:
 Image:        redis:3.2.5-alpine
Resources:

可以看到更新完成。

查看滾動更新後服務的狀態

[root@swarm_manager ~]# docker service ps  redis
ID                         NAME         IMAGE               NODE           DESIRED STATE  CURRENT STATE               ERROR
e69zhhxz66jmlm0h15gj89s2x  redis.1      redis:3.2.5-alpine  swarm_manager  Running        Running 2 minutes ago       
63h5wy36474k01vmr5jppbbxs   \_ redis.1  redis:3.0.7-alpine  node1          Shutdown       Shutdown 2 minutes ago      
1h9e8m9v3rx3hgx5x2bn71kim  redis.2      redis:3.2.5-alpine  node2          Running        Running 3 minutes ago       
39jitd0mzztl0mpy6k6rppkx5   \_ redis.2  redis:3.0.7-alpine  swarm_manager  Shutdown       Shutdown 3 minutes ago      
8pwrkq6558fwp8oiiu0uq484h  redis.3      redis:3.2.5-alpine  node1          Running        Running about a minute ago  
6usd4p2mj7p597ilgs490ou7a   \_ redis.3  redis:3.0.7-alpine  node2          Shutdown       Shutdown 2 minutes ago

可以看到有三個鏡像為redis:3.0.7-alpine的任務狀態為Shutdown,三個鏡像為redis:3.2.5-alpine的任務狀態為Running。說明滾動更新已完成。

再看看容器信息

[root@swarm_manager ~]# docker ps -a
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS                     PORTS               NAMES
f7c5ebb8678b        redis:3.2.5-alpine   "docker-entrypoint.sh"   4 minutes ago       Up 4 minutes               6379/tcp            redis.1.e69zhhxz66jmlm0h15gj89s2x
524aadad84b8        redis:3.0.7-alpine   "docker-entrypoint.sh"   7 minutes ago       Exited (0) 5 minutes ago                       redis.2.39jitd0mzztl0mpy6k6rppkx5

可以看出更新後,swarm並沒有刪除舊的容器。

下線某個節點

在前面的步驟中,所有的節點都處於運行狀態且可用性為ACTIVE。swarm 管理器可以將任務分配給任何可用性為 ACTIVE 的節點,所以到目前為止,所有節點都可以接收任務。

有時候,比如到了計劃的維護時間,你需要將節點的可用性設為DRAIN。可用性為DRAIN的節點不會從 swarm 接收任何新任務。同時,管理器將停止運行在該節點上的任務,並在另外可用性為 ACTIVE 的節點上啟動相應的任務副本。

確認所有節點都是活躍可用的

[root@swarm_manager ~]# docker node ls
ID                           HOSTNAME       STATUS  AVAILABILITY  MANAGER STATUS
622ih8ji5t428lazjx233pvks    node2          Ready   Active        
9e21bk67ey1abzje69lmpvbe1 *  swarm_manager  Ready   Active        Leader
f3wzagmtgsn8qyqzidxtw98d3    node1          Ready   Active

下線一個被分配了任務的節點

將分配了任務的工作節點node2 下線:

[root@swarm_manager ~]# docker node update --availability drain node2
node2

查看被下線節點的詳細信息

[root@swarm_manager ~]# docker node ls
ID                           HOSTNAME       STATUS  AVAILABILITY  MANAGER STATUS
622ih8ji5t428lazjx233pvks    node2          Ready   Drain         
9e21bk67ey1abzje69lmpvbe1 *  swarm_manager  Ready   Active        Leader
f3wzagmtgsn8qyqzidxtw98d3    node1          Ready   Active        
[root@swarm_manager ~]# docker node inspect --pretty node2
ID:            622ih8ji5t428lazjx233pvks
Hostname:        node2
Joined at:        2017-10-25 06:45:04.369968305 +0000 utc
Status:
 State:            Ready
 Availability:        Drain
Platform:
 Operating System:    linux
 Architecture:        x86_64
Resources:
 CPUs:            1
 Memory:        985.6 MiB
Plugins:
  Network:        bridge, host, null, overlay
  Volume:        local
Engine Version:        1.12.6

可以看到該節點的狀態為Ready,但可用性為Drain

再次查看任務的分配情況

[root@swarm_manager ~]#  docker service ps redis
ID                         NAME         IMAGE               NODE           DESIRED STATE  CURRENT STATE                ERROR
e69zhhxz66jmlm0h15gj89s2x  redis.1      redis:3.2.5-alpine  swarm_manager  Running        Running 8 minutes ago        
63h5wy36474k01vmr5jppbbxs   \_ redis.1  redis:3.0.7-alpine  node1          Shutdown       Shutdown 9 minutes ago       
6q046y1camb43b146kj2jaxe4  redis.2      redis:3.2.5-alpine  node1          Running        Running about a minute ago   
1h9e8m9v3rx3hgx5x2bn71kim   \_ redis.2  redis:3.2.5-alpine  node2          Shutdown       Shutdown about a minute ago  
39jitd0mzztl0mpy6k6rppkx5   \_ redis.2  redis:3.0.7-alpine  swarm_manager  Shutdown       Shutdown 9 minutes ago       
8pwrkq6558fwp8oiiu0uq484h  redis.3      redis:3.2.5-alpine  node1          Running        Running 8 minutes ago        
6usd4p2mj7p597ilgs490ou7a   \_ redis.3  redis:3.0.7-alpine  node2          Shutdown       Shutdown 8 minutes ago

再次將被下線的節點重置為活動狀態

[root@swarm_manager ~]# docker node update --availability active node2
node2

確認該節點的新狀態

[root@swarm_manager ~]# docker node ls
ID                           HOSTNAME       STATUS  AVAILABILITY  MANAGER STATUS
622ih8ji5t428lazjx233pvks    node2          Ready   Active        
9e21bk67ey1abzje69lmpvbe1 *  swarm_manager  Ready   Active        Leader
f3wzagmtgsn8qyqzidxtw98d3    node1          Ready   Active

說明現在該節點又可以重新接收任務了。

再看看 node2 節點上是否被分配了任務:

[root@swarm_manager ~]# docker service ps -f desired-state=running redis 
ID                         NAME     IMAGE               NODE           DESIRED STATE  CURRENT STATE           ERROR
e69zhhxz66jmlm0h15gj89s2x  redis.1  redis:3.2.5-alpine  swarm_manager  Running        Running 10 minutes ago  
6q046y1camb43b146kj2jaxe4  redis.2  redis:3.2.5-alpine  node1          Running        Running 2 minutes ago   
8pwrkq6558fwp8oiiu0uq484h  redis.3  redis:3.2.5-alpine  node1          Running        Running 9 minutes ago

desired-state 表示只列出處於活動狀態的任務。說明 node2雖然可用,但沒被分配任務。

一個可用性為Active的節點在以下情況下可以接收到新任務:

  • 當一個服務在伸縮規模時

  • 滾動更新時

  • 當你把其他某個節點的可用性設為 Drain

  • 當某個任務在另外某個 Active 節點上啟動失敗時




Docker swarm部署