1. 程式人生 > >Docker 1.12 Swarm Mode叢集實戰(第二章)

Docker 1.12 Swarm Mode叢集實戰(第二章)

第二章 建立Swarm叢集

繼續上一章 Docker 1.12 Swarm Mode叢集實戰(第一章) 的內容, 為了產生更多的docker幣,我們需要搭建一個swarm叢集來scale out我們的docker幣應用,解決單節點的效能瓶頸。

2.1 Swarm Mode簡介

Docker Engine 1.12及後續版本集成了SwarmKit編排服務,即Swarm Mode。它將服務物件引入到docker中,提供swarm叢集管理的原生支援並實現scaling、rolling update、service discovery、load balance、routing mesh等特性。

基本概念

  • 節點(Node)Swarm叢集中的一個Docker Engine例項。其中管理節點(Manager Node)負責swarm叢集管理並向工作節點分配任務;工作節點(Work Node)接受並執行來自管理節點的Task。簡單可理解為一個Node就是一臺Docker宿主機,管理節點為領導,工作節點為小兵。

需要注意的是領導也會幹小兵的活兒,真是個好領導啊…而且小兵也可以根據需求隨時提拔成領導,真是個好團隊啊…

  • 服務(Service)是對在worker nodes所執行一組任務的定義,它是整個swarm的核心,一個Service由多個任務組成。
  • 任務(Task)包含Docker容器和容器中執行的命令或應用,它是swarm中被排程的最小單元。簡單可理解為一個Task就是一個容器。

Swarm Mode下主要使用三組新的命令列工具建立和管理一個Swarm叢集:

  • docker swarm:開啟swarm模式; 加入Swarm叢集; 配置叢集引數
  • docker node: 查詢叢集節點資訊; 提升/移除一個管理節點; 管理swarm節點主機
  • docker service: 建立管理service

2.2 建立Swarm叢集

在node01上初始化swarm叢集:

# docker swarm init --advertise-addr 192.168.33.101Swarm initialized: current node (7e2vvnlakrrv2p0omxgl2lflz)is
now a manager.To add a worker to this swarm, run the following command: docker swarm join \ --token SWMTKN-1-4d8z30svnj6wi8y64ttzirpildro5vego1qrrldepj8auwxa6l-4l4b6o7q1wnjyiwsubkpffkkn \ 192.168.33.101:2377To add a manager to this swarm, run the following command: docker swarm join \ --token SWMTKN-1-4d8z30svnj6wi8y64ttzirpildro5vego1qrrldepj8auwxa6l-3e8p1ojarz8rdq1rx0ves1a9o \ 192.168.33.101:2377

NOTE

  • 你只需要在一個node上初始化swarm叢集, 其他node加入這個叢集就行了, 所以以上命令只需要在node01上執行。
  • –advertise-addr引數, 後面跟你swarm叢集的通訊地址, 這裡是node01的IP地址。
  • 命令輸出的提示很人性化吧,在需要的管理/工作節點複製貼上執行即可加入到swarm叢集中

將node01以manager角色加入swarm叢集

docker swarm join \

--token SWMTKN-1-4d8z30svnj6wi8y64ttzirpildro5vego1qrrldepj8auwxa6l-3e8p1ojarz8rdq1rx0ves1a9o \

192.168.33.101:2377

檢查node01 docker swarm mode資訊:

# docker info...Swarm: active

NodeID:7e2vvnlakrrv2p0omxgl2lflzIsManager:trueClusterID:0hhbs9vhvnpovil91d6z87txoManagers:1Nodes:1Orchestration:TaskHistoryRetentionLimit:5Raft:Snapshot interval:10000Heartbeat tick:1Election tick:3Dispatcher:Heartbeat period:5 seconds

CA configuration:Expiry duration:3 months

NodeAddress:192.168.33.101...

檢視swarm叢集node列表

# docker node ls

ID                      HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS

7e2vvnlakrrv2p0omxgl2lflz*  node01    ReadyActiveLeader

可以看到,我們的Swarm叢集中只有一個管理節點。

現在我們把其他節點也加入我們的叢集中
在node01通過ssh, 在node02-node05上執行上面的加入叢集命令:

# for N in $(seq 2 5); \do ssh node0$N \

docker swarm join \

--token SWMTKN-1-4d8z30svnj6wi8y64ttzirpildro5vego1qrrldepj8auwxa6l-4l4b6o7q1wnjyiwsubkpffkkn \

192.168.33.101:2377 \

;done

友情提示,如果你不記得初始化後提示加入swarm叢集的命令和金鑰也沒關係,可以使用如下方式檢視worker節點和manager節點的加入命令

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

再次檢查叢集節點列表, 我們可以看到所有的伺服器都已經加入swarm叢集了。

# docker node ls

ID            HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS

0frlcbt1xp0kggs64k5ktqrwj    node02    ReadyActive6o60ktooinsrej8dcwncq8ibc    node04    ReadyActive7e2vvnlakrrv2p0omxgl2lflz*  node01    ReadyActiveLeader

bsak0gszy07gh88tmo7lh5033    node05    ReadyActive

cmn6f714no0hn7c4xi9l0xs6h    node03    ReadyActive

不過現在我們的叢集只有一個manager節點,即node01。為了swarm叢集的高可用,避免單點故障. 我們希望建立多個manager節點叢集.
只需要通過如下命令, 提升node02和node03節點為manager節點:

# docker node promote node02 node03Node node02 promoted to a manager in the swarm.Node node03 promoted to a manager in the swarm.

# 檢視swarm叢集node列表

# docker node ls

ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS

0frlcbt1xp0kggs64k5ktqrwj    node02    ReadyActiveReachable6o60ktooinsrej8dcwncq8ibc    node04    ReadyActive7e2vvnlakrrv2p0omxgl2lflz*  node01    ReadyActiveLeader

bsak0gszy07gh88tmo7lh5033    node05    ReadyActive

cmn6f714no0hn7c4xi9l0xs6h    node03    ReadyActiveReachable

我們可以看到, 已經有3個manager節點了, 一個Leader節點, 兩個Reachable節點.

現在你也可以在node02和node03上面管理整個swarm叢集.

# ssh node02 docker node ls

ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS

0frlcbt1xp0kggs64k5ktqrwj*  node02    ReadyActiveReachable6o60ktooinsrej8dcwncq8ibc    node04    ReadyActive7e2vvnlakrrv2p0omxgl2lflz    node01    ReadyActiveLeader

bsak0gszy07gh88tmo7lh5033    node05    ReadyActive

cmn6f714no0hn7c4xi9l0xs6h    node03    ReadyActiveReachable# ssh node03 docker node ls

ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS

0frlcbt1xp0kggs64k5ktqrwj    node02    ReadyActiveReachable6o60ktooinsrej8dcwncq8ibc    node04    ReadyActive7e2vvnlakrrv2p0omxgl2lflz    node01    ReadyActiveLeader

bsak0gszy07gh88tmo7lh5033    node05    ReadyActive

cmn6f714no0hn7c4xi9l0xs6h *  node03    ReadyActiveReachable

好了,到此我們的swarm叢集就搭建完畢了。超級簡單吧~~

2.3 Swarm叢集執行Service

有了Docker Swarm叢集,我們如何把我們的應用跑在Swarm叢集上呢?

很簡單, 將我們原來我們使用的docker run命令替換成docker service create就行了,命令後面的格式和選項全都一樣。

使用docker service命令去建立容器服務.

例如在swarm叢集上, 啟動一個alpine映象來執行ping 8.8.8.8命令

# docker service create --name ping-google alpine ping 8.8.8.89cyy6xrk2n0welrql49hm3ass

查詢 swarm service列表, 我們可以看到剛剛建立的service:

# docker service ls

ID            NAME         REPLICAS  IMAGE   COMMAND

9cyy6xrk2n0w  ping-google  1/1       alpine  ping 8.8.8.8docker service ps <Service ID orName>命令可以檢視服務到底跑在哪個節點伺服器上:# docker service ps ping-google

ID                         NAME               IMAGE   NODE    DESIRED STATE  CURRENT STATE           ERROR

alxkyacovh4ltiklpccjhf2u5  ping-google.1      alpine  node03  RunningRunning5 minutes ago

15e8v9q83wu3skrz63ieacbkr   \_ ping-google.1  alpine  node01  ShutdownRejected5 minutes ago  "No such image: alpine:latest"

上面的輸出我們可以看到service當前跑在node03上, 下面有一條node01上的報錯是怎麼回事呢?

hehe, 因為docker hub連線不穩的問題, 有時候你還可能沒法pull到image.
swarm叢集會不斷幫你重試啟動容器,直到成功為止,報錯即為啟動失敗的日誌。

2.3.1 擴充套件(Scale)服務
現在我們的ping-google服務只有一個容器, 注意下面的REPLICAS欄位.

# docker service ls

ID            NAME         REPLICAS  IMAGE   COMMAND

9cyy6xrk2n0w  ping-google  1/1       alpine  ping 8.8.8.8

如果我們想Scale服務到10個副本容器, 可以使用

docker service scale <Service ID orName>=<replicas No.># docker service scale ping-google=10

ping-google scaled to 10# docker service ls

ID            NAME         REPLICAS  IMAGE   COMMAND

9cyy6xrk2n0w  ping-google  1/10      alpine  ping 8.8.8.8

注意REPLICAS現在顯示1/10表示這個service一共有10個副本,現在成功運行了1個. 叢集正在啟動其他的副本.

這時候檢視service程序:

# docker service ps ping-google

ID                         NAME                IMAGE   NODE    DESIRED STATE  CURRENT STATE               ERROR

alxkyacovh4ltiklpccjhf2u5  ping-google.1       alpine  node03  RunningRunning about an hour ago

15e8v9q83wu3skrz63ieacbkr   \_ ping-google.1   alpine  node01  ShutdownRejected about an hour ago  "No such image: alpine:latest"2x0abay1gtfdj2kposza0cwbc  ping-google.2       alpine  node03  RunningRunning13 seconds ago

evt8fdlph66e1ih9cayrhz1zg  ping-google.3       alpine  node05  ReadyPreparing2 seconds ago

b9fciqvr90ruq1h0yoeudm54t   \_ ping-google.3   alpine  node05  ShutdownRejected2 seconds ago      "No such image: alpine:latest"10voxosxigfek1yd29u5o5igk   \_ ping-google.3   alpine  node05  ShutdownRejected14 seconds ago     "No such image: alpine:latest"57urifyyjzyqzjgbo8mpuuj3z  ping-google.4       alpine  node01  RunningRunning8 seconds ago

51ttvahuq54xrs64egx1gk4lx  ping-google.5       alpine  node01  RunningRunning11 seconds ago

288uy2wj5pw3gdu5texm1f9hl   \_ ping-google.5   alpine  node01  ShutdownRejected18 seconds ago     "No such image: alpine:latest"6fphqamttmmwztp43d3a2iz8q  ping-google.6       alpine  node02  RunningPreparing13 seconds ago

82jd8lipbsc4x1i3msd6kqe0x   \_ ping-google.6   alpine  node02  ShutdownRejected18 seconds ago     "No such image: alpine:latest"3l5kv6zwh5nx4piqd983i39nr  ping-google.7       alpine  node05  RunningPreparing9 seconds ago

bhvwas8un7xwplo4e0r3vv5z7   \_ ping-google.7   alpine  node05  ShutdownRejected14 seconds ago     "No such image: alpine:latest"64npet8ftxctdvbfjuqn3b7xs  ping-google.8       alpine  node02  RunningPreparing11 seconds ago

2ydgrctk17btn1dplrc5z53tl   \_ ping-google.8   alpine  node02  ShutdownRejected16 seconds ago     "No such image: alpine:latest"

alqhl7r3nmff0h1mrez9iw348  ping-google.9       alpine  node04  RunningPreparing13 seconds ago

7facu0tsaqpxiwqwclpz4ir0n   \_ ping-google.9   alpine  node04  ShutdownRejected18 seconds ago     "No such image: alpine:latest"1mt8ucgdjxsxdozqtwclyp11w  ping-google.10      alpine  node04  RunningPreparing11 seconds ago

e8om0kbqyn2r91v3oz72kx0tb   \_ ping-google.10  alpine  node04  ShutdownRejected16 seconds ago     "No such image: alpine:latest"

-_-!!! 不忍直視…還是因為docker hub連線不穩定原因,pull image失敗造成你會看到很多Error。忽略吧, swram叢集會自動重試的…

等所有的副本都啟動成功了, 你會看到swarm叢集會自動編排10個副本到5臺docker宿主機上,而且每個節點會啟動2個容器。

# docker ps

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS

b440806604e0        alpine:latest       "ping 8.8.8.8"10 seconds ago      Up8 seconds

6b217e23fee6        alpine:latest       "ping 8.8.8.8"10 seconds ago      Up8 seconds

2.3.2 開放一個服務埠

跟我們在單機使用docker一樣, 你可以將你容器的埠暴露到主機網路中,從而使得跑在容器中的應用能夠被外部訪問。

swarm叢集的service埠暴露還有如下特性:

  • 公共的埠會暴露在每一個swarm叢集中的節點伺服器上.
  • 請求進如公共埠後會負載均衡到所有的sevice例項上.

釋出埠的引數跟單機環境一樣是-p, 就是把docker run -p替換成docker service create -p就行。

下面我們建立一個elasticsearch服務, 釋出9200埠:

# docker service create --name search --publish 9200:9200 --replicas 7 elasticsearch

使用以下命令監控 service 建立過程:

# watch docker service ps search

注意DESIRED STATE列, 一個service副本的建立過程,會經歷以下幾個狀態:

  • accepted 任務已經被分配到某一個節點執行
  • preparing 準備資源, 現在來說一般是從網路拉取image
  • running 副本執行成功
  • shutdown 呃, 報錯,被停止了…

當一個任務被終止stoped or killed.., 任務不能被重啟, 但是一個替代的任務會被建立.

測試服務埠:

# curl localhost:9200{"name":"Rachel Grey","cluster_name":"elasticsearch","version":{"number":"2.3.4","build_hash":"e455fd0c13dceca8dbbdbb1665d068ae55dabe3f","build_timestamp":"2016-06-30T11:24:31Z","build_snapshot":false,"lucene_version":"5.5.0"},"tagline":"You Know, for Search"}

反覆執行這個命令, 你會看到name會改變, 請求會被分發到不同的service副本.

2.3.3 刪除服務

下一章我們要將docker幣應用, 跑在swarm叢集上,開始之前, 清理我們的service.

你可以使用docker service rm <Service ID or Name> 命令刪除服務。

刪除所有servcie可以使用如下命令;

# docker service ls -q | xargs docker service rm4iwtgcfnovd2uzcyp5w57qd0e

bnfutusm7qide08ihurxmucis