一、什麼是Docker Swarm
Swarm是Docker公司推出的用來管理docker叢集的平臺,幾乎全部用GO語言來完成的開發的,程式碼開源在 , 它是將一群Docker宿主機變成一個單一的虛擬主機,Swarm使用標準的Docker API介面作為其前端的訪問入口,換言之,各種形式的Docker
Client(compose,docker-py等)均可以直接與Swarm通訊,甚至Docker本身都可以很容易的與Swarm整合,這大大方便了使用者將原本基於單節點的系統移植到Swarm上,同時Swarm內建了對Docker網路外掛的支援,使用者也很容易的部署跨主機的容器叢集服務。
Docker Swarm 和 Docker Compose 一樣,都是 Docker 官方容器編排專案,但不同的是,Docker Compose 是一個在單個伺服器或主機上建立多個容器的工具,而 Docker Swarm 則可以在多個伺服器或主機上建立容器叢集服務,對於微服務的部署,顯然 Docker Swarm 會更加適合。
從 Docker 1.12.0 版本開始,Docker Swarm 已經包含在 Docker 引擎中(docker swarm),並且已經內建了服務發現工具,我們就不需要像之前一樣,再配置 Etcd 或者 Consul 來進行服務發現配置了。
Swarm deamon只是一個排程器(Scheduler)加路由器(router),Swarm自己不執行容器,它只是接受Docker客戶端發來的請求,排程適合的節點來執行容器,這就意味著,即使Swarm由於某些原因掛掉了,叢集中的節點也會照常執行,放Swarm重新恢復執行之後,他會收集重建叢集資訊。
二、Docker Swarm 基本結構圖
在結構圖可以看出 Docker Client使用Swarm對 叢集(Cluster)進行排程使用。
上圖可以看出,Swarm是典型的master-slave結構,透過發現服務來選舉manager。manager是中心管理節點,各個node上執行agent接受manager的統一管理,叢集會自動透過Raft協議分散式選舉出manager節點,無需額外的發現服務支援,避免了單點的瓶頸問題,同時也內建了DNS的負載均衡和對外部負載均衡機制的整合支援
三.Swarm的幾個關鍵概念
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 |
1.Swarm 叢集的管理和編排是使用嵌入docker引擎的SwarmKit,可以在docker初始化時啟動swarm模式或者加入已存在的swarm 2.Node 一個節點是docker引擎叢集的一個例項。您還可以將其視為Docker節點。您可以在單個物理計算機或雲伺服器上執行一個或多個節點,但生產群集部署通常包括分佈在多個物理和雲端計算機上的Docker節點。 要將應用程式部署到swarm,請將服務定義提交給 管理器節點。管理器節點將稱為任務的工作單元分派 給工作節點。 Manager節點還執行維護所需群集狀態所需的編排和叢集管理功能。Manager節點選擇單個領導者來執行編排任務。 工作節點接收並執行從管理器節點分派的任務。預設情況下,管理器節點還將服務作為工作節點執行,但您可以將它們配置為僅執行管理器任務並且是僅管理器節點。代理程式在每個工作程式節點上執行,並報告分配給它的任務。工作節點向管理器節點通知其分配的任務的當前狀態,以便管理器可以維持每個工作者的期望狀態。 3.Service 一個服務是任務的定義,管理機或工作節點上執行。它是群體系統的中心結構,是使用者與群體互動的主要根源。建立服務時,你需要指定要使用的容器映象。 4.Task 任務是在docekr容器中執行的命令,Manager節點根據指定數量的任務副本分配任務給worker節點 ------------------------------------------使用方法------------------------------------- docker swarm:叢集管理,子命令有init,
join
, leave, update。(docker swarm --help檢視幫助) docker service:服務建立,子命令有create, inspect, update, remove, tasks。(docker service--help檢視幫助) docker node:節點管理,子命令有accept, promote, demote, inspect, update, tasks,
ls
,
rm
。(docker node --help檢視幫助) node是加入到swarm叢集中的一個docker引擎實體,可以在一臺物理機上執行多個node,node分為: manager nodes,也就是管理節點 worker nodes,也就是工作節點 1)manager node管理節點:執行叢集的管理功能,維護叢集的狀態,選舉一個leader節點去執行排程任務。 2)worker node工作節點:接收和執行任務。參與容器叢集負載排程,僅用於承載task。 3)service服務:一個服務是工作節點上執行任務的定義。建立一個服務,指定了容器所使用的映象和容器執行的命令。
service是執行在worker nodes上的task的描述,service的描述包括使用哪個docker 映象,以及在使用該映象的容器中執行什麼命令。 4)task任務:一個任務包含了一個容器及其執行的命令。task是service的執行實體,task啟動docker容器並在容器中執行任務。 |
四、Swarm的工作模式
1. Node
2. Service
3. 任務與排程
4. 服務副本與全域性服務
五、Swarm的排程策略
1
2
3
4
5
6
7
8
9
10
11
12 |
Swarm在排程(scheduler)節點(leader節點)執行容器的時候,會根據指定的策略來計算最適合執行容器的節點,目前支援的策略有:spread, binpack, random. 1)Random 顧名思義,就是隨機選擇一個Node來執行容器,一般用作除錯用,spread和binpack策略會根據各個節點的可用的CPU, RAM以及正在運 行的容器的數量來計算應該執行容器的節點。 2)Spread 在同等條件下,Spread策略會選擇執行容器最少的那臺節點來執行新的容器,binpack策略會選擇執行容器最集中的那臺機器來執行新的節點。 使用Spread策略會使得容器會均衡的分佈在叢集中的各個節點上執行,一旦一個節點掛掉了只會損失少部分的容器。 3)Binpack Binpack策略最大化的避免容器碎片化,就是說binpack策略儘可能的把還未使用的節點留給需要更大空間的容器執行,儘可能的把容器執行在 一個節點上面。 |
六、Swarm Cluster模式特性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 |
1)批次建立服務 建立容器之前先建立一個overlay的網路,用來保證在不同主機上的容器網路互通的網路模式 2)強大的叢集的容錯性 當容器副本中的其中某一個或某幾個節點當機後,cluster會根據自己的服務註冊發現機制,以及之前設定的值--replicas n, 在叢集中剩餘的空閒節點上,重新拉起容器副本。整個副本遷移的過程無需人工干預,遷移後原本的叢集的load balance依舊好使! 不難看出,docker service其實不僅僅是批次啟動服務這麼簡單,而是在叢集中定義了一種狀態。Cluster會持續檢測服務的健康狀態 並維護叢集的高可用性。 3)服務節點的可擴充套件性 Swarm Cluster不光只是提供了優秀的高可用性,同時也提供了節點彈性擴充套件或縮減的功能。當容器組想動態擴充套件時,只需透過scale 引數即可複製出新的副本出來。 仔細觀察的話,可以發現所有擴充套件出來的容器副本都run在原先的節點下面,如果有需求想在每臺節點上都run一個相同的副本,方法 其實很簡單,只需要在命令中將
"--replicas n"
更換成
"--mode=global"
即可! 複製服務(--replicas n) 將一系列複製任務分發至各節點當中,具體取決於您所需要的設定狀態,例如“--replicas 3”。 全域性服務(--mode=global) 適用於叢集內全部可用節點上的服務任務,例如“--mode global”。如果大家在 Swarm 叢集中設有 7 臺 Docker 節點,則全部節點之上都將存在對應容器。 4. 排程機制 所謂的排程其主要功能是cluster的server端去選擇在哪個伺服器節點上建立並啟動一個容器例項的動作。它是由一個裝箱演算法和過濾器 組合而成。每次透過過濾器(constraint)啟動容器的時候,swarm cluster 都會呼叫排程機制篩選出匹配約束條件的伺服器,並在這上面執行容器。 ------------------Swarm cluster的建立過程包含以下三個步驟---------------------- 1)發現Docker叢集中的各個節點,收集節點狀態、角色資訊,並監視節點狀態的變化 2)初始化內部排程(scheduler)模組 3)建立並啟動API監聽服務模組 一旦建立好這個cluster,就可以用命令docker service批次對叢集內的容器進行操作,非常方便! 在啟動容器後,docker 會根據當前每個swarm節點的負載判斷,在負載最優的節點執行這個task任務,用
"docker service ls"
和
"docker service ps + taskID" 可以看到任務執行在哪個節點上。容器啟動後,有時需要等待一段時間才能完成容器建立。 |
七、Dcoker Swarm 叢集部署
溫馨提示:
機器環境(三臺機器,centos系統)
IP:192.168.31.43 主機名:manager43 擔任角色:swarm manager
IP:192.168.31.188 主機名:node188 擔任角色:swarm node
IP:192.168.31.139 主機名:node139 擔任角色:swarm node
1、準備工作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 |
1) 修改主機名 # 192.168.31.43 主機上執行 [root@manager43 ~]
# hostnamectl set-hostname manager43 # 192.168.31.188 主機上執行 [root@node188 ~]
# hostnamectl set-hostname node188 # 192.168.31.139 主機上執行 [root@node139 ~]
# hostnamectl set-hostname node139 2)配置hosts檔案(可配置可不配置) [root@manager43 ~]
# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.31.43 manager43 192.168.31.188 node188 192.168.31.139 node139 # 使用scp複製到node主機 [root@manager43 ~]
# scp /etc/hosts root@192.168.31.188:/etc/hosts [root@manager43 ~]
# scp /etc/hosts root@192.168.31.139:/etc/hosts 3) 設定防火牆 關閉三臺機器上的防火牆。如果開啟防火牆,則需要在所有節點的防火牆上依次放行2377
/tcp
(管理埠)、7946
/udp
(節點間通訊埠)、4789
/udp
(overlay 網路埠)埠。 [root@manager43 ~]
# systemctl disable firewalld.service [root@manager43 ~]
# systemctl stop firewalld.service 4) 安裝docker並配置加速器(在三臺主機都要安裝喲...) [root@manager43 ~]
# yum -y install docker [root@node188 ~]
# yum -y install docker [root@node139 ~]
# yum -y install docker |
也可以安裝最新版docker,可查考: docker安裝教程
加速器配置,可查考: docker加速器配置教程
2、建立Swarm並新增節點
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 |
1) 建立Swarm叢集 [root@manager43 ~]
# docker swarm init --advertise-addr 192.168.31.43 Swarm initialized: current node (z2n633mty5py7u9wyl423qnq0) is now a manager. To add a worker to this swarm, run the following
command
:
# 這就是新增節點的方式(要儲存初始化後token,因為在節點加入時要使用token作為通訊的金鑰)
docker swarm
join
--token SWMTKN-1-2lefzq18zohy9yr1vskutf1sfb2a590xz9d0mjj2m15zu9eprw-2938j5f50t35ycut0vbj2sx0s 192.168.31.43:2377 To add a manager to this swarm, run
'docker swarm join-token manager'
and follow the instructions. 上面命令執行後,該機器自動加入到swarm叢集。這個會建立一個叢集token,獲取全球唯一的 token,作為叢集唯一標識。後續將其他節點加入叢集都會用到這個token值。 其中,--advertise-addr參數列示其它swarm中的worker節點使用此ip地址與manager聯絡。命令的輸出包含了其它節點如何加入叢集的命令。 這裡無意中遇到了一個小小的問題: # 在次執行上面的命令,回報下面的錯誤 [root@manager43 ~]
# docker swarm init --advertise-addr 192.168.31.43 Error response from daemon: This node is already part of a swarm. Use
"docker swarm leave"
to leave this swarm and
join
another one. # 解決方法 [root@manager43 ~]
# docker swarm leave -f 這裡的leave就是在叢集中刪除節點,-f引數強制刪除,執行完在重新執行OK 2) 檢視叢集的相關資訊 [root@manager43 ~]
# docker info 上面的命令執行後 找到Swarm的關鍵字,就可以看到相關資訊了 [root@manager43 ~]
# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 3jcmnzjh0e99ipgshk1ykuovd * manager43 Ready Active Leader 18.06.0-ce 上面的命令是檢視叢集中的機器(注意上面node ID旁邊那個*號表示現在連線到這個節點上) 3) 新增節點主機到Swarm叢集 上面我們在建立Swarm叢集的時候就已經給出了新增節點的方法 # 192.168.31.188 主機上執行 [root@node188 ~]
# docker swarm join --token SWMTKN-1-2lefzq18zohy9yr1vskutf1sfb2a590xz9d0mjj2m15zu9eprw-2938j5f50t35ycut0vbj2sx0s 192.168.31.43:2377 This node joined a swarm as a worker. # 192.168.31.139 主機上執行 [root@node139 ~]
# docker swarm join --token SWMTKN-1-2lefzq18zohy9yr1vskutf1sfb2a590xz9d0mjj2m15zu9eprw-2938j5f50t35ycut0vbj2sx0s 192.168.31.43:2377 This node joined a swarm as a worker. 如果想要將其他更多的節點新增到這個swarm叢集中,新增方法如上一致 在manager43主機上我們可以看一下叢集中的機器及狀態 [root@manager43 ~]
# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 3jcmnzjh0e99ipgshk1ykuovd * manager43 Ready Active Leader 18.06.0-ce vww7ue2xprzg46bjx7afo4h04 node139 Ready Active 18.06.1-ce c5klw5ns4adcvumzgiv66xpyj node188 Ready Active 18.06.1-ce -------------------------------------------------------------------------------------------------------------------- 溫馨提示:更改節點的availablity狀態 swarm叢集中node的availability狀態可以為 active或者drain,其中: active狀態下,node可以接受來自manager節點的任務分派; drain狀態下,node節點會結束task,且不再接受來自manager節點的任務分派(也就是下線節點) [root@manager43 ~]
# docker node update --availability drain node139 # 將node139節點下線。如果要刪除node139節點,命令是"docker node rm --force node139" node139 [root@manager43 ~]
# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 3jcmnzjh0e99ipgshk1ykuovd * manager43 Ready Active Leader 18.06.0-ce vww7ue2xprzg46bjx7afo4h04 node139 Ready Drain 18.06.1-ce c5klw5ns4adcvumzgiv66xpyj node188 Ready Active 18.06.1-ce 如上,當node1的狀態改為drain後,那麼該節點就不會接受task任務分發,就算之前已經接受的任務也會轉移到別的節點上。 再次修改為active狀態(及將下線的節點再次上線) [root@manager43 ~]
# docker node update --availability active node139 node139 [root@manager43 ~]
# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 3jcmnzjh0e99ipgshk1ykuovd * manager43 Ready Active Leader 18.06.0-ce vww7ue2xprzg46bjx7afo4h04 node139 Ready Active 18.06.1-ce c5klw5ns4adcvumzgiv66xpyj node188 Ready Active 18.06.1-ce |
3、在Swarm中部署服務(nginx為例)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218 |
Docker 1.12版本提供服務的Scaling、health check、滾動升級等功能,並提供了內建的dns、vip機制,實現service的服務發現和負載均衡能力 1) 建立網路在部署服務 # 建立網路 [root@manager43 ~]
# docker network create -d overlay nginx_net a52jy33asc5o0ts0rq823bf0m [root@manager43 ~]
# docker network ls | grep nginx_net a52jy33asc5o nginx_net overlay swarm # 部署服務 [root@manager43 ~]
# docker service create --replicas 1 --network nginx_net --name my_nginx -p 80:80 nginx # 就建立了一個具有一個副本(--replicas 1 )的nginx服務,使用映象nginx olexfmtdf94sxyeetkchwhehg overall progress: 1 out of 1 tasks 1
/1
: running [==================================================>] verify: Service converged 在manager-node節點上使用上面這個覆蓋網路建立nginx服務: 其中,--replicas 引數指定服務由幾個例項組成。 注意:不需要提前在節點上下載nginx映象,這個命令執行後會自動下載這個容器映象(比如此處建立tomcat容器,就將下面命令中的映象改為tomcat映象)。 # 使用 docker service ls 檢視正在執行服務的列表 [root@manager43 ~]
# docker service ls ID NAME MODE REPLICAS IMAGE PORTS olexfmtdf94s my_nginx replicated 1
/1
nginx:latest *:80->80
/tcp 2) 查詢Swarm中服務的資訊 -pretty 使命令輸出格式化為可讀的格式,不加 --pretty 可以輸出更詳細的資訊: [root@manager43 ~]
# docker service inspect --pretty my_nginx ID: zs7fw4ereo5w7ohd4n9ii06nt Name: my_nginx Service Mode: Replicated
Replicas: 1 Placement: UpdateConfig:
Parallelism: 1
On failure: pause
Monitoring Period: 5s
Max failure ratio: 0
Update order: stop-first RollbackConfig:
Parallelism: 1
On failure: pause
Monitoring Period: 5s
Max failure ratio: 0
Rollback order: stop-first ContainerSpec:
Image: nginx:latest@sha256:b73f527d86e3461fd652f62cf47e7b375196063bbbd503e853af5be16597cb2e
Init:
false Resources: Networks: nginx_net Endpoint Mode: vip Ports:
PublishedPort = 80
Protocol = tcp
TargetPort = 80
PublishMode = ingress # 查詢到哪個節點正在執行該服務。如下該容器被排程到manager-node節點上啟動了,然後訪問http://192.168.31.43即可訪問這個容器應用(如果排程到其他節點,訪問也是如此) [root@manager43 ~]
# docker service ps my_nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS yzonph0zu7km my_nginx.1 nginx:latest manager43 Running Running about an hour ago 溫馨提示:如果上面命令執行後,上面的 STATE 欄位中剛開始的服務狀態為 Preparing,需要等一會才能變為 Running 狀態,其中最費時間的應該是下載映象的過程 有上面命令可知,該服務在manager-node節點上執行。登陸該節點,可以檢視到nginx容器在執行中 [root@manager43 ~]
# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0dc7103f8030 nginx:latest
"nginx -g 'daemon of…"
About an hour ago Up About an hour 80
/tcp
my_nginx.1.yzonph0zu7km0211uj0ro5brj 3) 在Swarm中動態擴充套件服務(scale) 當然,如果只是透過service啟動容器,swarm也算不上什麼新鮮東西了。Service還提供了複製(類似kubernetes裡的副本)功能。可以透過 docker service scale 命令來設定服務中容器的副本數 比如將上面的my_nginx容器動態擴充套件到4個 [root@manager43 ~]
# docker service scale my_nginx=4 my_nginx scaled to 4 overall progress: 4 out of 4 tasks 1
/4
: running [==================================================>] 2
/4
: running [==================================================>] 3
/4
: running [==================================================>] 4
/4
: running [==================================================>] verify: Service converged 和建立服務一樣,增加scale數之後,將會建立新的容器,這些新啟動的容器也會經歷從準備到執行的過程,過一分鐘左右,服務應該就會啟動完成,這時候可以再來看一下 nginx 服務中的容器 [root@manager43 ~]
# docker service ps my_nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS yzonph0zu7km my_nginx.1 nginx:latest manager43 Running Running about an hour ago mlprstt9ds5x my_nginx.2 nginx:latest node139 Running Running 52 seconds ago y09lk90tdzdp my_nginx.3 nginx:latest node139 Running Running 52 seconds ago clolfl3zlvj0 my_nginx.4 nginx:latest node188 Running Running 2 minutes ago 可以看到,之前my_nginx容器只在manager-node節點上有一個例項,而現在又增加了3個例項。 這4個副本的my_nginx容器分別執行在這三個節點上,登陸這三個節點,就會發現已經存在執行著的my_nginx容器 4) 模擬當機node節點 特別需要清楚的一點: 如果一個節點當機了(即該節點就會從swarm叢集中被踢出),則Docker應該會將在該節點執行的容器,排程到其他節點,以滿足指定數量的副本保持執行狀態。 比如: 將node139當機後或將node139的docker服務關閉,那麼它上面的task例項就會轉移到別的節點上。當node139節點恢復後,它轉移出去的task例項不會主動轉移回來, 只能等別的節點出現故障後轉移task例項到它的上面。使用命令
"docker node ls"
,發現node139節點已不在swarm叢集中了(狀態為:Down)。 [root@node139 ~]
# systemctl stop docker [root@manager43 ~]
# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION ppk7q0bjond8a58xja7in1qid * manager43 Ready Active Leader 18.06.0-ce mums8azgbrffnecp3q8fz70pl node139 Down Active 18.06.1-ce z3n36maf03yjg7odghikuv574 node188 Ready Active 18.06.1-ce 然後過一會查詢服務的狀態列表 [root@manager43 ~]
# docker service ps my_nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS yzonph0zu7km my_nginx.1 nginx:latest manager43 Running Running about an hour ago wb1cpk9k22rl my_nginx.2 nginx:latest node188 Running Running about a minute ago mlprstt9ds5x \_ my_nginx.2 nginx:latest node139 Shutdown Running 4 minutes ago rhbj4bcr4t2c my_nginx.3 nginx:latest manager43 Running Running about a minute ago y09lk90tdzdp \_ my_nginx.3 nginx:latest node139 Shutdown Running 4 minutes ago clolfl3zlvj0 my_nginx.4 nginx:latest node188 Running Running 6 minutes ago 上面我們可以發現node139故障後,它上面之前的兩個task任務已經轉移到node188和manager43節點上了 登陸到node188和manager43節點上,可以看到這兩個執行的task任務。當訪問192.168.31.188和192.168.31.43節點的80埠,swarm的負載均衡會把請求路由到一個任意節點的可用的容器上 [root@manager43 ~]
# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ae4c5c2e6f3f nginx:latest
"nginx -g 'daemon of…"
4 minutes ago Up 4 minutes 80
/tcp
my_nginx.3.rhbj4bcr4t2c3y2f8vyfmbi21 0dc7103f8030 nginx:latest
"nginx -g 'daemon of…"
About an hour ago Up About an hour 80
/tcp
my_nginx.1.yzonph0zu7km0211uj0ro5brj [root@node188 ~]
# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a63ef253f7dd nginx:latest
"nginx -g 'daemon of…"
3 minutes ago Up 3 minutes 80
/tcp
my_nginx.2.wb1cpk9k22rl1ydab7aozl2b5 74a1a1db81d4 nginx:latest
"nginx -g 'daemon of…"
8 minutes ago Up 8 minutes 80
/tcp
my_nginx.4.clolfl3zlvj0ewmh85c2ljnza 再次在node188和manager43節點上將從node139上轉移過來的兩個task關閉 [root@manager43 ~]
# docker stop my_nginx.3.rhbj4bcr4t2c3y2f8vyfmbi21 my_nginx.3.rhbj4bcr4t2c3y2f8vyfmbi21 [root@node188 ~]
# docker stop my_nginx.2.wb1cpk9k22rl1ydab7aozl2b5 my_nginx.2.wb1cpk9k22rl1ydab7aozl2b5 再次查詢服務的狀態列表,發現這兩個task又轉移到node139上了 [root@manager43 ~]
# docker service ps my_nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS yzonph0zu7km my_nginx.1 nginx:latest manager43 Running Running 2 hours ago j2q61f8jtzba my_nginx.2 nginx:latest node188 Running Running 24 seconds ago wb1cpk9k22rl \_ my_nginx.2 nginx:latest node188 Shutdown Complete 29 seconds ago mlprstt9ds5x \_ my_nginx.2 nginx:latest node139 Shutdown Running 11 minutes ago oz9wyjuldw1t my_nginx.3 nginx:latest manager43 Running Running 40 seconds ago rhbj4bcr4t2c \_ my_nginx.3 nginx:latest manager43 Shutdown Complete 45 seconds ago y09lk90tdzdp \_ my_nginx.3 nginx:latest node139 Shutdown Running 11 minutes ago clolfl3zlvj0 my_nginx.4 nginx:latest node188 Running Running 12 minutes ago 結論:即在swarm cluster叢集中啟動的容器,在worker node節點上刪除或停用後,該容器會自動轉移到其他的worker node節點上 5) Swarm 動態縮容服務(scale) 同理,swarm還可以縮容,同樣是使用scale命令 如下,將my_nginx容器變為1個 [root@manager43 ~]
# docker service scale my_nginx=1 my_nginx scaled to 1 overall progress: 1 out of 1 tasks 1
/1
: verify: Service converged [root@manager43 ~]
# docker service ls ID NAME MODE REPLICAS IMAGE PORTS zs7fw4ereo5w my_nginx replicated 1
/1
nginx:latest *:80->80
/tcp [root@manager43 ~]
# docker service ps my_nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS yzonph0zu7km my_nginx.1 nginx:latest manager43 Running Running 11 hours ago wb1cpk9k22rl my_nginx.2 nginx:latest node188 Shutdown Complete 9 hours ago mlprstt9ds5x \_ my_nginx.2 nginx:latest node139 Shutdown Shutdown 29 seconds ago rhbj4bcr4t2c my_nginx.3 nginx:latest manager43 Shutdown Complete 9 hours ago y09lk90tdzdp \_ my_nginx.3 nginx:latest node139 Shutdown Shutdown 29 seconds ago 透過docker service
ps
my_nginx 可以看到node節點上已經為Shutdown狀態了 在登入到node節點主機上檢視 [root@node188 ~]
# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f93c0a27374a nginx:latest
"nginx -g 'daemon of…"
9 hours ago Exited (0) 44 seconds ago my_nginx.2.j2q61f8jtzba9kb3unupkhl25 a63ef253f7dd nginx:latest
"nginx -g 'daemon of…"
9 hours ago Exited (0) 9 hours ago my_nginx.2.wb1cpk9k22rl1ydab7aozl2b5 [root@node139 ~]
# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e8ac2e44f5c4 nginx:latest
"nginx -g 'daemon of…"
9 hours ago Exited (0) 9 hours ago my_nginx.2.mlprstt9ds5xi48u1rzscgfdk 5b031aa5a2cc nginx:latest
"nginx -g 'daemon of…"
9 hours ago Exited (0) 9 hours ago my_nginx.3.y09lk90tdzdp8cwj6mm5oyr3f 登入node節點,使用docker
ps
-a 檢視,會發現容器被stop而非
rm 6) 除了上面使用scale進行容器的擴容或縮容之外,還可以使用docker service update 命令。 可對 服務的啟動 引數 進行 更新/修改。 [root@manager43 ~]
# docker service update --replicas 3 my_nginx my_nginx overall progress: 3 out of 3 tasks 1
/3
: running [==================================================>] 2
/3
: running [==================================================>] 3
/3
: running [==================================================>] verify: Service converged [root@manager43 ~]
# docker service ls ID NAME MODE REPLICAS IMAGE PORTS zs7fw4ereo5w my_nginx replicated 3
/3
nginx:latest *:80->80
/tcp [root@manager43 ~]
# docker service ps my_nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS yzonph0zu7km my_nginx.1 nginx:latest manager43 Running Running 11 hours ago j3hduzd9pret my_nginx.2 nginx:latest node188 Running Running 18 seconds ago wb1cpk9k22rl \_ my_nginx.2 nginx:latest node188 Shutdown Complete 9 hours ago mlprstt9ds5x \_ my_nginx.2 nginx:latest node139 Shutdown Shutdown 4 minutes ago gng96vc5vqpv my_nginx.3 nginx:latest node139 Running Running 18 seconds ago rhbj4bcr4t2c \_ my_nginx.3 nginx:latest manager43 Shutdown Complete 9 hours ago y09lk90tdzdp \_ my_nginx.3 nginx:latest node139 Shutdown Shutdown 4 minutes ago docker service update 命令,也可用於直接 升級 映象等 [root@manager43 ~]
# docker service update --image nginx:new my_nginx [root@manager43 ~]
# docker service ls ID NAME MODE REPLICAS IMAGE PORTS zs7fw4ereo5w my_nginx replicated 3
/3
nginx:new *:80->80
/tcp 注意IMAGE列 變成了nginx:new 7) 為了下面的直觀顯示,我這裡把my_nginx服務直接刪除了 [root@manager43 ~]
# docker service rm my_nginx 這樣就會把所有節點上的所有容器(task任務例項)全部刪除了 |
4、Swarm中使用Volume(掛在目錄,mount命令)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107 |
1) 檢視volume的幫助資訊 [root@manager43 ~]
# docker volume --help Usage: docker volume COMMAND Manage volumes Commands:
create Create a volume
inspect Display detailed information on one or
more
volumes
ls
List volumes
prune Remove all unused
local
volumes
rm
Remove one or
more
volumes Run
'docker volume COMMAND --help'
for
more
information on a
command
. 2) 建立一個volume [root@manager43 ~]
# docker volume create --name testvolume testvolume # 檢視建立的volume [root@manager43 ~]
# docker volume ls DRIVER VOLUME NAME local
testvolume # 檢視volume詳情 [root@manager43 ~]
# docker volume inspect testvolume [
{
"CreatedAt"
:
"2018-10-21T10:50:02+08:00"
,
"Driver"
:
"local"
,
"Labels"
: {},
"Mountpoint"
:
"/var/lib/docker/volumes/testvolume/_data"
,
"Name"
:
"testvolume"
,
"Options"
: {},
"Scope"
:
"local"
} ] 3) 建立新的服務並掛載testvolume(nginx為例) [root@manager43 ~]
# docker service create --replicas 3 --mount type=volume,src=testvolume,dst=/zjz --name test_nginx nginx sh7wc8yzcvr0xaedo4tnraj7l overall progress: 3 out of 3 tasks 1
/3
: running [==================================================>] 2
/3
: running [==================================================>] 3
/3
: running [==================================================>] verify: Service converged 溫馨提示: 引數src寫成
source
也可以;dst表示容器內的路徑,也可以寫成target # 檢視建立服務 [root@manager43 ~]
# docker service ls ID NAME MODE REPLICAS IMAGE PORTS sh7wc8yzcvr0 test_nginx replicated 3
/3
nginx:latest [root@manager43 ~]
# docker service ps test_nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS m7m41kwt4q6w test_nginx.1 nginx:latest node188 Running Running 56 seconds ago kayh81q1o1kx test_nginx.2 nginx:latest node139 Running Running 56 seconds ago eq11v0rcwy38 test_nginx.3 nginx:latest manager43 Running Running 56 seconds ago # 檢視有沒有掛載成功(登入各個節點的容器看看有沒有指定的目錄並建立檔案測試) # 容器中操作 [root@manager43 ~]
# docker exec -it 63451219cb4e /bin/bash root@63451219cb4e:/
# cd /zjz/ root@63451219cb4e:
/zjz
# ls root@63451219cb4e:
/zjz
# echo "gen wo xue docker" > docker.txt root@63451219cb4e:
/zjz
# ls docker.txt 執行docker volume inspect testvolume 可以看到本地的路徑(上面已經執行過了) 本地路徑:
/var/lib/docker/volumes/testvolume/_data [root@manager43 ~]
# cd /var/lib/docker/volumes/testvolume/_data [root@manager43 _data]
# ls docker.txt [root@manager43 _data]
# cat docker.txt gen wo xue docker 還可以將node節點機上的volume資料目錄做成軟連結 [root@manager43 _data]
# ln -s /var/lib/docker/volumes/testvolume/_data /zjz [root@manager43 _data]
# cd /zjz/ [root@manager43 zjz]
# ls docker.txt [root@manager43 zjz]
# echo "123" > 1.txt [root@manager43 zjz]
# ll 總用量 8 -rw-r--r-- 1 root root 4 10月 21 11:04 1.txt -rw-r--r-- 1 root root 18 10月 21 11:00 docker.txt # 容器中檢視 [root@manager43 zjz]
# docker exec -it 63451219cb4e /bin/bash root@63451219cb4e:/
# cd /zjz/ root@63451219cb4e:
/zjz
# ls 1.txt docker.txt root@63451219cb4e:
/zjz
# cat 1.txt 123 root@63451219cb4e:
/zjz
# cat docker.txt gen wo xue docker # 還有一種掛載方式簡單說一下吧,上面的會了下面的肯定簡單 命令格式: docker service create --
mount
type
=bind,target=
/container_data/
,
source
=
/host_data/ 其中,引數target表示容器裡面的路徑,
source
表示本地硬碟路徑 # 示例建立並掛載並使用網路 [root@manager43 ~]
# docker service create --replicas 1 --mount type=bind,target=/usr/share/nginx/html/,source=/opt/web/ --network nginx_net --name zjz_nginx -p 8880:80 nginx |
5、多服務Swarm叢集部署
問:上面我們只是對單獨的一個nginx服務進行的叢集部署,那如果要統一編排多個服務呢?
答:docker 三劍客中有個compose 這個就是對單機進行統一編排的,它的實現是透過docker-compose.yml的檔案,這裡我們就可以結合compose和swarm進行多服務的編排(
docker compose教程)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 |
溫馨提示: 我們這裡要部署的服務有三個(nginx服務,visualizer服務,portainer服務) 都是叢集 GUI 管理服務 docker service部署的是單個服務,我們可以使用docker stack進行多服務編排部署 1) 編寫docker-compose.yml檔案 [root@manager43 ~]
# mkdir testswarm [root@manager43 ~]
# cd testswarm/ [root@manager43 testswarm]
# cat docker-compose.yml version:
"3" services:
nginx:
image: nginx
ports:
- 8888:80
deploy:
mode: replicated
replocas: 3
visualizer:
image: dockersamples
/visualizer
ports:
-
"8080:8080"
volumes:
-
"/var/run/docker.sock:/var/run/docker.sock"
deploy:
replicas: 1
placement:
constraints: [node.role == manager]
portainer:
image: portainer
/portainer
ports:
-
"9000:9000"
volumes:
-
"/var/run/docker.sock:/var/run/docker.sock"
deploy:
replicas: 1
placement:
constraints: [node.role == manager] 2) 透過這個yml檔案部署服務 [root@manager43 testswarm]
# docker stack deploy -c docker-compose.yml deploy_deamon Creating network deploy_deamon_default Creating service deploy_deamon_portainer Creating service deploy_deamon_nginx Creating service deploy_deamon_visualizer 透過上面的執行過程可以看出這樣建立會預設建立一個網路並使用它,名字都是我們給的名字的字首加上服務名 # 檢視建立服務 [root@manager43 testswarm]
# docker service ls ID NAME MODE REPLICAS IMAGE PORTS xj2f1t5ax3nm deploy_deamon_nginx replicated 3
/3
nginx:latest *:8888->80
/tcp ky9qpldr5abb deploy_deamon_portainer replicated 1
/1
portainer
/portainer
:latest *:9000->9000
/tcp r47ff177x1ir deploy_deamon_visualizer replicated 1
/1
dockersamples
/visualizer
:latest *:8080->8080
/tcp [root@manager43 testswarm]
# docker service ps deploy_deamon_nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS z3v4uc1ujsnq deploy_deamon_nginx.1 nginx:latest node139 Running Running about a minute ago jhg3ups0cko5 deploy_deamon_nginx.2 nginx:latest manager43 Running Running about a minute ago 3e6guv791x21 deploy_deamon_nginx.3 nginx:latest node188 Running Running about a minute ago [root@manager43 testswarm]
# docker service ps deploy_deamon_portainer ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS whyuvy82cvvw deploy_deamon_portainer.1 portainer
/portainer
:latest manager43 Running Running about a minute ago [root@manager43 testswarm]
# docker service ps deploy_deamon_visualizer ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS wge5w1eqykg3 deploy_deamon_visualizer.1 dockersamples
/visualizer
:latest manager43 Running Starting 7 seconds ago |
測試
八、Docker Swarm 容器網路
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135 |
在Docker版本1.12之後swarm模式原生支援覆蓋網路(overlay networks),可以先建立一個覆蓋網路,然後啟動容器的時候啟用這個覆蓋網路, 這樣只要是這個覆蓋網路內的容器,不管在不在同一個宿主機上都能相互通訊,即跨主機通訊!不同覆蓋網路內的容器組之間是相互隔離的(相互
ping
不通)。 swarm模式的覆蓋網路包括以下功能: 1)可以附加多個服務到同一個網路。 2)預設情況下,service discovery為每個swarm服務分配一個虛擬IP地址(vip)和DNS名稱,使得在同一個網路中容器之間可以使用服務名稱為互相連線。 3)可以配置使用DNS輪循而不使用VIP 4)為了可以使用swarm的覆蓋網路,在啟用swarm模式之間你需要在swarm節點之間開放以下埠: 5)TCP
/UDP
埠7946 – 用於容器網路發現 6)UDP埠4789 – 用於容器覆蓋網路 例項如下: -----------在Swarm叢集中建立overlay網路------------ [root@manager-node ~]
# docker network create --driver overlay --opt encrypted --subnet 10.10.19.0/24 ngx_net 引數解釋: –opt encrypted 預設情況下swarm中的節點通訊是加密的。在不同節點的容器之間,可選的–opt encrypted引數能在它們的vxlan流量啟用附加的加密層。 --subnet 命令列引數指定overlay網路使用的子網網段。當不指定一個子網時,swarm管理器自動選擇一個子網並分配給網路。 [root@manager-node ~]
# docker network ls NETWORK ID NAME DRIVER SCOPE d7aa48d3e485 bridge bridge
local 9e637a97a3b9 docker_gwbridge bridge
local b5a41c8c71e7 host host
local 7f4fx3jf4dbr ingress overlay swarm 3x2wgugr6zmn ngx_net overlay swarm 0808a5c72a0a none null
local 由上可知,Swarm當中擁有2套覆蓋網路。其中
"ngx_net"
網路正是我們在部署容器時所建立的成果。而
"ingress"
覆蓋網路則為預設提供。 Swarm 管理節點會利用 ingress 負載均衡以將服務公佈至叢集之外。 在將服務連線到這個建立的網路之前,網路覆蓋到manager節點。上面輸出的SCOPE為 swarm 表示將服務部署到Swarm時可以使用此網路。 在將服務連線到這個網路後,Swarm只將該網路擴充套件到特定的worker節點,這個worker節點被swarm排程器分配了執行服務的任務。 在那些沒有執行該服務任務的worker節點上,網路並不擴充套件到該節點。 ------------------將服務連線到overlay網路------------------- [root@manager-node ~]
# docker service create --replicas 5 --network ngx_net --name my-test -p 80:80 nginx 上面名為
"my-test"
的服務啟動了3個task,用於執行每個任務的容器都可以彼此透過overlay網路進行通訊。Swarm叢集將網路擴充套件到所有任務處於Running狀態的節點上。 [root@manager-node ~]
# docker service ls ID NAME REPLICAS IMAGE COMMAND dsaxs6v463g9 my-
test
5
/5
nginx 在manager-node節點上,透過下面的命令檢視哪些節點有處於running狀態的任務: [root@manager-node ~]
# docker service ps my-test ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 8433fuiy7vpu0p80arl7vggfe my-
test
.1 nginx node2 Running Running 2 minutes ago f1h7a0vtojv18zrsiw8j0rzaw my-
test
.2 nginx node1 Running Running 2 minutes ago ex73ifk3jvzw8ukurl8yu7fyq my-
test
.3 nginx node1 Running Running 2 minutes ago cyu73jd8psupfhken23vvmpud my-
test
.4 nginx manager-node Running Running 2 minutes ago btorxekfix4hcqh4v83dr0tzw my-
test
.5 nginx manager-node Running Running 2 minutes ago 可見三個節點都有處於running狀態的任務,所以my-network網路擴充套件到三個節點上。 可以查詢某個節點上關於my-network的詳細資訊: [root@manager-node ~]
# docker network inspect ngx_net [
{
"Name"
:
"ngx_net"
,
"Id"
:
"3x2wgugr6zmn1mcyf9k1du27p"
,
"Scope"
:
"swarm"
,
"Driver"
:
"overlay"
,
"EnableIPv6"
:
false
,
"IPAM"
: {
"Driver"
:
"default"
,
"Options"
: null,
"Config"
: [
{
"Subnet"
:
"10.10.19.0/24"
,
"Gateway"
:
"10.10.19.1"
}
]
},
"Internal"
:
false
,
"Containers"
: {
"00f47e38deea76269eb03ba13695ec0b0c740601c85019546d6a9a17fd434663"
: {
"Name"
:
"my-test.5.btorxekfix4hcqh4v83dr0tzw"
,
"EndpointID"
:
"ea962d07eee150b263ae631b8a7f8c1950337c11ef2c3d488a7c3717defd8601"
,
"MacAddress"
:
"02:42:0a:0a:13:03"
,
"IPv4Address"
:
"10.10.19.3/24"
,
"IPv6Address"
:
""
},
"957620c6f7abb44ad8dd2d842d333f5e5c1655034dc43e49abbbd680de3a5341"
: {
"Name"
:
"my-test.4.cyu73jd8psupfhken23vvmpud"
,
"EndpointID"
:
"f33a6e9ddf1dd01bcfc43ffefd19e19514658f001cdf9b2fbe23bc3fdf56a42a"
,
"MacAddress"
:
"02:42:0a:0a:13:07"
,
"IPv4Address"
:
"10.10.19.7/24"
,
"IPv6Address"
:
""
}
},
"Options"
: {
"com.docker.network.driver.overlay.vxlanid_list"
:
"257"
},
"Labels"
: {}
} ] 從上面的資訊可以看出在manager-node節點上,名為my-
test
的服務有一個名為my-
test
.5.btorxekfix4hcqh4v83dr0tzw和 my-
test
.4.cyu73jd8psupfhken23vvmpud的task連線到名為ngx_net的網路上(另外兩個節點node1和node2同樣可以用上面命令檢視) [root@node1 ~]
# docker network inspect ngx_net .......
"Containers"
: {
"7d9986fad5a7d834676ba76ae75aff2258f840953f1dc633c3ef3c0efd2b2501"
: {
"Name"
:
"my-test.3.ex73ifk3jvzw8ukurl8yu7fyq"
,
"EndpointID"
:
"957ca19f3d5480762dbd14fd9a6a1cd01a8deac3e8e35b23d1350f480a7b2f37"
,
"MacAddress"
:
"02:42:0a:0a:13:06"
,
"IPv4Address"
:
"10.10.19.6/24"
,
"IPv6Address"
:
""
},
"9e50fceada1d7c653a886ca29d2bf2606debafe8c8a97f2d79104faf3ecf8a46"
: {
"Name"
:
"my-test.2.f1h7a0vtojv18zrsiw8j0rzaw"
,
"EndpointID"
:
"b1c209c7b68634e88e0bf5e100fe03435b3096054da6555c61e6c207ac651ac2"
,
"MacAddress"
:
"02:42:0a:0a:13:05"
,
"IPv4Address"
:
"10.10.19.5/24"
,
"IPv6Address"
:
""
}
}, ......... [root@node2 web]
# docker network inspect ngx_net ........
"Containers"
: {
"4bdcce0ee63edc08d943cf4a049eac027719ff2dc14b7c3aa85fdddc5d1da968"
: {
"Name"
:
"my-test.1.8433fuiy7vpu0p80arl7vggfe"
,
"EndpointID"
:
"df58de85b0a0e4d128bf332fc783f6528d1f179b0f9f3b7aa70ebc832640d3bc"
,
"MacAddress"
:
"02:42:0a:0a:13:04"
,
"IPv4Address"
:
"10.10.19.4/24"
,
"IPv6Address"
:
""
}
}, 可以透過查詢服務來獲得服務的虛擬IP地址,如下: [root@manager-node ~]
# docker service inspect --format='{{json .Endpoint.VirtualIPs}}' my-test [{
"NetworkID"
:
"7f4fx3jf4dbrp97aioc05pul4"
,
"Addr"
:
"10.255.0.6/16"
},{
"NetworkID"
:
"3x2wgugr6zmn1mcyf9k1du27p"
,
"Addr"
:
"10.10.19.2/24"
}] 由上結果可知,10.10.19.2其實就是swarm叢集內部的vip,整個網路結構如下圖所示: |
加入ngx_net網路的容器彼此之間可以透過IP地址通訊,也可以透過名稱通訊。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127 |
[root@node2 ~]
# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4bdcce0ee63e nginx:latest
"nginx -g 'daemon off"
22 minutes ago Up 22 minutes 80
/tcp
my-
test
.1.8433fuiy7vpu0p80arl7vggfe [root@node2 ~]
# docker exec -ti 4bdcce0ee63e /bin/bash root@4bdcce0ee63e:/
# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link
/loopback
00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1
/8
scope host lo
valid_lft forever preferred_lft forever
inet6 ::1
/128
scope host
valid_lft forever preferred_lft forever 1786: eth0@if1787: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default
link
/ether
02:42:0a:ff:00:08 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.255.0.8
/16
scope global eth0
valid_lft forever preferred_lft forever
inet 10.255.0.6
/32
scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:aff:feff:8
/64
scope link
valid_lft forever preferred_lft forever 1788: eth1@if1789: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link
/ether
02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet 172.18.0.3
/16
scope global eth1
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe12:3
/64
scope link
valid_lft forever preferred_lft forever 1791: eth2@if1792: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default
link
/ether
02:42:0a:0a:13:04 brd ff:ff:ff:ff:ff:ff link-netnsid 2
inet 10.10.19.4
/24
scope global eth2
valid_lft forever preferred_lft forever
inet 10.10.19.2
/32
scope global eth2
valid_lft forever preferred_lft forever
inet6 fe80::42:aff:fe0a:1304
/64
scope link
valid_lft forever preferred_lft forever root@4bdcce0ee63e:/
# ping 10.10.19.3 PING 10.10.19.3 (10.10.19.3): 56 data bytes 64 bytes from 10.10.19.3: icmp_seq=0 ttl=64
time
=0.890 ms 64 bytes from 10.10.19.3: icmp_seq=1 ttl=64
time
=0.622 ms .....- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min
/avg/max/stddev
= 0.622
/0
.756
/0
.890
/0
.134 ms root@4bdcce0ee63e:/
# ping 10.10.19.6 PING 10.10.19.6 (10.10.19.6): 56 data bytes 64 bytes from 10.10.19.6: icmp_seq=0 ttl=64
time
=0.939 ms 64 bytes from 10.10.19.6: icmp_seq=1 ttl=64
time
=0.590 ms ----------------------------使用swarm模式的服務發現-------------------------- 預設情況下,當建立了一個服務並連線到某個網路後,swarm會為該服務分配一個VIP。此VIP根據服務名對映到DNS。在網路上的容器共享該服務的DNS對映, 所以網路上的任意容器可以透過服務名訪問服務。 在同一overlay網路中,不用透過埠對映來使某個服務可以被其它服務訪問。Swarm內部的負載均衡器自動將請求傳送到服務的VIP上,然後分發到所有的 active的task上。 如下示例: 在同一個網路中新增了一個centos服務,此服務可以透過名稱my-
test
訪問前面建立的nginx服務: [root@manager-node ~]
# docker service create --name my-centos --network ngx_net centos 查詢centos執行在哪個節點上(上面建立命令執行後,需要一段時間才能完成這個centos服務的建立) [root@manager-node ~]
# docker service ps my-centos ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR e03pqgkjs3l1qizc6v4aqaune my-centos.1 centos node2 Running Preparing 4 seconds ago 登入centos執行的節點(由上可知是node2節點),開啟centos的互動shell: [root@node2 ~]
# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES e4554490d891 centos:latest
"/bin/bash"
About an hour ago Up About an hour my-centos.1.9yk5ie28gwk9mw1h1jovb68ki [root@node2 ~]
# docker exec -ti my-centos.1.9yk5ie28gwk9mw1h1jovb68ki /bin/bash root@4bdcce0ee63e:/
# nslookup my-test Server: 127.0.0.11 Address 1: 127.0.0.11 Name: my-
test Address 1: 10.10.19.2 10.10.19.2 從centos容器內部,使用特殊查詢 查詢DNS,來找到my-
test
服務的所有容器的IP地址: root@4bdcce0ee63e:/
# nslookup tasks.my-test Server: 127.0.0.11 Address 1: 127.0.0.11 Name: tasks.my-
test Address 1: 10.10.19.4 my-
test
.1.8433fuiy7vpu0p80arl7vggfe Address 2: 10.10.19.5 my-
test
.2.f1h7a0vtojv18zrsiw8j0rzaw Address 3: 10.10.19.6 my-
test
.3.ex73ifk3jvzw8ukurl8yu7fyq Address 2: 10.10.19.7 my-
test
.4.cyu73jd8psupfhken23vvmpud Address 3: 10.10.19.3 my-
test
.5.btorxekfix4hcqh4v83dr0tzw 從centos容器內部,透過wget來訪問my-
test
服務中執行的nginx網頁伺服器 root@4bdcce0ee63e:/
# wget -O- my-test Connecting to my-
test
(10.10.19.2:80) <!DOCTYPE html> <html> <
head
> <title>Welcome to nginx!<
/title
> ... Swarm的負載均衡器自動將HTTP請求路由到VIP上,然後到一個active的task容器上。它根據round-robin選擇演算法將後續的請求分發到另一個active的task上。 -----------------------------------為服務使用DNS round-robin----------------------------- 在建立服務時,可以配置服務直接使用DNS round-robin而無需使用VIP。這是透過在建立服務時指定 --endpoint-mode dnsrr 命令列引數實現的。 當你想要使用自己的負載均衡器時可以使用這種方式。 如下示例(注意:使用DNS round-robin方式建立服務,不能直接在命令裡使用-p指定埠) [root@manager-node ~]
# docker service create --replicas 3 --name my-dnsrr-nginx --network ngx_net --endpoint-mode dnsrr nginx [root@manager-node ~]
# docker service ps my-dnsrr-nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 65li2zbhxvvoaesndmwjokouj my-dnsrr-nginx.1 nginx node1 Running Running 2 minutes ago 5hjw7wm4xr877879m0ewjciuj my-dnsrr-nginx.2 nginx manager-node Running Running 2 minutes ago afo7acduge2qfy60e87liz557 my-dnsrr-nginx.3 nginx manager-node Running Running 2 minutes ago 當透過服務名稱查詢DNS時,DNS服務返回所有任務容器的IP地址: root@4bdcce0ee63e:/
# nslookup my-dnsrr-nginx Server: 127.0.0.11 Address 1: 127.0.0.11 Name: my-dnsrr-nginx Address 1: 10.10.19.10 my-dnsrr-nginx.3.0sm1n9o8hygzarv5t5eq46okn.my-network Address 2: 10.10.19.9 my-dnsrr-nginx.2.b3o1uoa8m003b2kk0ytl9lawh.my-network Address 3: 10.10.19.8 my-dnsrr-nginx.1.55za4c83jq9846rle6eigiq15.my-network 需要注意的是:一定要確認VIP的連通性 通常Docker官方推薦使用
dig
,
nslookup
或其它DNS查詢工具來查詢透過DNS對服務名的訪問。因為VIP是邏輯IP,
ping
並不是確認VIP連通性的正確的工具。 |