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
<code>在Docker版本1.12之後swarm模式原生支援覆寫網絡(overlay networks),可以先建立一個覆寫網絡,然後啟動容器的時候啟用這個覆寫網絡,</code>
<code>這樣隻要是這個覆寫網絡内的容器,不管在不在同一個主控端上都能互相通信,即跨主機通信!不同覆寫網絡内的容器組之間是互相隔離的(互相</code><code>ping</code><code>不通)。</code>
<code> </code>
<code>swarm模式的覆寫網絡包括以下功能:</code>
<code>1)可以附加多個服務到同一個網絡。</code>
<code>2)預設情況下,service discovery為每個swarm服務配置設定一個虛拟IP位址(vip)和DNS名稱,使得在同一個網絡中容器之間可以使用服務名稱為互相連接配接。</code>
<code>3)可以配置使用DNS輪循而不使用VIP</code>
<code>4)為了可以使用swarm的覆寫網絡,在啟用swarm模式之間你需要在swarm節點之間開放以下端口:</code>
<code>5)TCP</code><code>/UDP</code><code>端口7946 – 用于容器網絡發現</code>
<code>6)UDP端口4789 – 用于容器覆寫網絡</code>
<code>執行個體如下:</code>
<code>-----------在Swarm叢集中建立overlay網絡------------</code>
<code>[root@manager-node ~]</code><code># docker network create --driver overlay --opt encrypted --subnet 10.10.19.0/24 ngx_net</code>
<code>參數解釋:</code>
<code>–opt encrypted 預設情況下swarm中的節點通信是加密的。在不同節點的容器之間,可選的–opt encrypted參數能在它們的vxlan流量啟用附加的加密層。</code>
<code>--subnet 指令行參數指定overlay網絡使用的子網網段。當不指定一個子網時,swarm管理器自動選擇一個子網并配置設定給網絡。</code>
<code>[root@manager-node ~]</code><code># docker network ls</code>
<code>NETWORK ID NAME DRIVER SCOPE</code>
<code>d7aa48d3e485 bridge bridge </code><code>local</code>
<code>9e637a97a3b9 docker_gwbridge bridge </code><code>local</code>
<code>b5a41c8c71e7 host host </code><code>local</code>
<code>7f4fx3jf4dbr ingress overlay swarm </code>
<code>3x2wgugr6zmn ngx_net overlay swarm </code>
<code>0808a5c72a0a none null </code><code>local</code>
<code>由上可知,Swarm當中擁有2套覆寫網絡。其中</code><code>"ngx_net"</code><code>網絡正是我們在部署容器時所建立的成果。而</code><code>"ingress"</code><code>覆寫網絡則為預設提供。</code>
<code>Swarm 管理節點會利用 ingress 負載均衡以将服務公布至叢集之外。</code>
<code>在将服務連接配接到這個建立的網絡之前,網絡覆寫到manager節點。上面輸出的SCOPE為 swarm 表示将服務部署到Swarm時可以使用此網絡。</code>
<code>在将服務連接配接到這個網絡後,Swarm隻将該網絡擴充到特定的worker節點,這個worker節點被swarm排程器配置設定了運作服務的任務。</code>
<code>在那些沒有運作該服務任務的worker節點上,網絡并不擴充到該節點。</code>
<code>------------------将服務連接配接到overlay網絡-------------------</code>
<code>[root@manager-node ~]</code><code># docker service create --replicas 5 --network ngx_net --name my-test -p 80:80 nginx</code>
<code>上面名為</code><code>"my-test"</code><code>的服務啟動了3個task,用于運作每個任務的容器都可以彼此通過overlay網絡進行通信。Swarm叢集将網絡擴充到所有任務處于Running狀态的節點上。</code>
<code>[root@manager-node ~]</code><code># docker service ls</code>
<code>ID NAME REPLICAS IMAGE COMMAND</code>
<code>dsaxs6v463g9 my-</code><code>test</code> <code>5</code><code>/5</code> <code>nginx</code>
<code>在manager-node節點上,通過下面的指令檢視哪些節點有處于running狀态的任務:</code>
<code>[root@manager-node ~]</code><code># docker service ps my-test</code>
<code>ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR</code>
<code>8433fuiy7vpu0p80arl7vggfe my-</code><code>test</code><code>.1 nginx node2 Running Running 2 minutes ago</code>
<code>f1h7a0vtojv18zrsiw8j0rzaw my-</code><code>test</code><code>.2 nginx node1 Running Running 2 minutes ago</code>
<code>ex73ifk3jvzw8ukurl8yu7fyq my-</code><code>test</code><code>.3 nginx node1 Running Running 2 minutes ago</code>
<code>cyu73jd8psupfhken23vvmpud my-</code><code>test</code><code>.4 nginx manager-node Running Running 2 minutes ago</code>
<code>btorxekfix4hcqh4v83dr0tzw my-</code><code>test</code><code>.5 nginx manager-node Running Running 2 minutes ago</code>
<code>可見三個節點都有處于running狀态的任務,是以my-network網絡擴充到三個節點上。</code>
<code>可以查詢某個節點上關于my-network的詳細資訊:</code>
<code>[root@manager-node ~]</code><code># docker network inspect ngx_net</code>
<code>[</code>
<code> </code><code>{</code>
<code> </code><code>"Name"</code><code>: </code><code>"ngx_net"</code><code>,</code>
<code> </code><code>"Id"</code><code>: </code><code>"3x2wgugr6zmn1mcyf9k1du27p"</code><code>,</code>
<code> </code><code>"Scope"</code><code>: </code><code>"swarm"</code><code>,</code>
<code> </code><code>"Driver"</code><code>: </code><code>"overlay"</code><code>,</code>
<code> </code><code>"EnableIPv6"</code><code>: </code><code>false</code><code>,</code>
<code> </code><code>"IPAM"</code><code>: {</code>
<code> </code><code>"Driver"</code><code>: </code><code>"default"</code><code>,</code>
<code> </code><code>"Options"</code><code>: null,</code>
<code> </code><code>"Config"</code><code>: [</code>
<code> </code><code>{</code>
<code> </code><code>"Subnet"</code><code>: </code><code>"10.10.19.0/24"</code><code>,</code>
<code> </code><code>"Gateway"</code><code>: </code><code>"10.10.19.1"</code>
<code> </code><code>}</code>
<code> </code><code>]</code>
<code> </code><code>},</code>
<code> </code><code>"Internal"</code><code>: </code><code>false</code><code>,</code>
<code> </code><code>"Containers"</code><code>: {</code>
<code> </code><code>"00f47e38deea76269eb03ba13695ec0b0c740601c85019546d6a9a17fd434663"</code><code>: {</code>
<code> </code><code>"Name"</code><code>: </code><code>"my-test.5.btorxekfix4hcqh4v83dr0tzw"</code><code>,</code>
<code> </code><code>"EndpointID"</code><code>: </code><code>"ea962d07eee150b263ae631b8a7f8c1950337c11ef2c3d488a7c3717defd8601"</code><code>,</code>
<code> </code><code>"MacAddress"</code><code>: </code><code>"02:42:0a:0a:13:03"</code><code>,</code>
<code> </code><code>"IPv4Address"</code><code>: </code><code>"10.10.19.3/24"</code><code>,</code>
<code> </code><code>"IPv6Address"</code><code>: </code><code>""</code>
<code> </code><code>},</code>
<code> </code><code>"957620c6f7abb44ad8dd2d842d333f5e5c1655034dc43e49abbbd680de3a5341"</code><code>: {</code>
<code> </code><code>"Name"</code><code>: </code><code>"my-test.4.cyu73jd8psupfhken23vvmpud"</code><code>,</code>
<code> </code><code>"EndpointID"</code><code>: </code><code>"f33a6e9ddf1dd01bcfc43ffefd19e19514658f001cdf9b2fbe23bc3fdf56a42a"</code><code>,</code>
<code> </code><code>"MacAddress"</code><code>: </code><code>"02:42:0a:0a:13:07"</code><code>,</code>
<code> </code><code>"IPv4Address"</code><code>: </code><code>"10.10.19.7/24"</code><code>,</code>
<code> </code><code>}</code>
<code> </code><code>"Options"</code><code>: {</code>
<code> </code><code>"com.docker.network.driver.overlay.vxlanid_list"</code><code>: </code><code>"257"</code>
<code> </code><code>"Labels"</code><code>: {}</code>
<code> </code><code>}</code>
<code>]</code>
<code>從上面的資訊可以看出在manager-node節點上,名為my-</code><code>test</code><code>的服務有一個名為my-</code><code>test</code><code>.5.btorxekfix4hcqh4v83dr0tzw和</code>
<code>my-</code><code>test</code><code>.4.cyu73jd8psupfhken23vvmpud的task連接配接到名為ngx_net的網絡上(另外兩個節點node1和node2同樣可以用上面指令檢視)</code>
<code>[root@node1 ~]</code><code># docker network inspect ngx_net</code>
<code>.......</code>
<code> </code><code>"7d9986fad5a7d834676ba76ae75aff2258f840953f1dc633c3ef3c0efd2b2501"</code><code>: {</code>
<code> </code><code>"Name"</code><code>: </code><code>"my-test.3.ex73ifk3jvzw8ukurl8yu7fyq"</code><code>,</code>
<code> </code><code>"EndpointID"</code><code>: </code><code>"957ca19f3d5480762dbd14fd9a6a1cd01a8deac3e8e35b23d1350f480a7b2f37"</code><code>,</code>
<code> </code><code>"MacAddress"</code><code>: </code><code>"02:42:0a:0a:13:06"</code><code>,</code>
<code> </code><code>"IPv4Address"</code><code>: </code><code>"10.10.19.6/24"</code><code>,</code>
<code> </code><code>"9e50fceada1d7c653a886ca29d2bf2606debafe8c8a97f2d79104faf3ecf8a46"</code><code>: {</code>
<code> </code><code>"Name"</code><code>: </code><code>"my-test.2.f1h7a0vtojv18zrsiw8j0rzaw"</code><code>,</code>
<code> </code><code>"EndpointID"</code><code>: </code><code>"b1c209c7b68634e88e0bf5e100fe03435b3096054da6555c61e6c207ac651ac2"</code><code>,</code>
<code> </code><code>"MacAddress"</code><code>: </code><code>"02:42:0a:0a:13:05"</code><code>,</code>
<code> </code><code>"IPv4Address"</code><code>: </code><code>"10.10.19.5/24"</code><code>,</code>
<code>.........</code>
<code>[root@node2 web]</code><code># docker network inspect ngx_net</code>
<code>........</code>
<code> </code><code>"4bdcce0ee63edc08d943cf4a049eac027719ff2dc14b7c3aa85fdddc5d1da968"</code><code>: {</code>
<code> </code><code>"Name"</code><code>: </code><code>"my-test.1.8433fuiy7vpu0p80arl7vggfe"</code><code>,</code>
<code> </code><code>"EndpointID"</code><code>: </code><code>"df58de85b0a0e4d128bf332fc783f6528d1f179b0f9f3b7aa70ebc832640d3bc"</code><code>,</code>
<code> </code><code>"MacAddress"</code><code>: </code><code>"02:42:0a:0a:13:04"</code><code>,</code>
<code> </code><code>"IPv4Address"</code><code>: </code><code>"10.10.19.4/24"</code><code>,</code>
<code>可以通過查詢服務來獲得服務的虛拟IP位址,如下:</code>
<code>[root@manager-node ~]</code><code># docker service inspect --format='{{json .Endpoint.VirtualIPs}}' my-test</code>
<code>[{</code><code>"NetworkID"</code><code>:</code><code>"7f4fx3jf4dbrp97aioc05pul4"</code><code>,</code><code>"Addr"</code><code>:</code><code>"10.255.0.6/16"</code><code>},{</code><code>"NetworkID"</code><code>:</code><code>"3x2wgugr6zmn1mcyf9k1du27p"</code><code>,</code><code>"Addr"</code><code>:</code><code>"10.10.19.2/24"</code><code>}]</code>
<code>由上結果可知,10.10.19.2其實就是swarm叢集内部的vip,整個網絡結構如下圖所示:</code>
加入ngx_net網絡的容器彼此之間可以通過IP位址通信,也可以通過名稱通信。
<code>[root@node2 ~]</code><code># docker ps</code>
<code>CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES</code>
<code>4bdcce0ee63e nginx:latest </code><code>"nginx -g 'daemon off"</code> <code>22 minutes ago Up 22 minutes 80</code><code>/tcp</code> <code>my-</code><code>test</code><code>.1.8433fuiy7vpu0p80arl7vggfe</code>
<code>[root@node2 ~]</code><code># docker exec -ti 4bdcce0ee63e /bin/bash</code>
<code>root@4bdcce0ee63e:/</code><code># ip addr </code>
<code>1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default</code>
<code> </code><code>link</code><code>/loopback</code> <code>00:00:00:00:00:00 brd 00:00:00:00:00:00</code>
<code> </code><code>inet 127.0.0.1</code><code>/8</code> <code>scope host lo</code>
<code> </code><code>valid_lft forever preferred_lft forever</code>
<code> </code><code>inet6 ::1</code><code>/128</code> <code>scope host</code>
<code>1786: eth0@if1787: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default</code>
<code> </code><code>link</code><code>/ether</code> <code>02:42:0a:ff:00:08 brd ff:ff:ff:ff:ff:ff link-netnsid 0</code>
<code> </code><code>inet 10.255.0.8</code><code>/16</code> <code>scope global eth0</code>
<code> </code><code>inet 10.255.0.6</code><code>/32</code> <code>scope global eth0</code>
<code> </code><code>inet6 fe80::42:aff:feff:8</code><code>/64</code> <code>scope link</code>
<code>1788: eth1@if1789: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default</code>
<code> </code><code>link</code><code>/ether</code> <code>02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 1</code>
<code> </code><code>inet 172.18.0.3</code><code>/16</code> <code>scope global eth1</code>
<code> </code><code>inet6 fe80::42:acff:fe12:3</code><code>/64</code> <code>scope link</code>
<code>1791: eth2@if1792: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default</code>
<code> </code><code>link</code><code>/ether</code> <code>02:42:0a:0a:13:04 brd ff:ff:ff:ff:ff:ff link-netnsid 2</code>
<code> </code><code>inet 10.10.19.4</code><code>/24</code> <code>scope global eth2</code>
<code> </code><code>inet 10.10.19.2</code><code>/32</code> <code>scope global eth2</code>
<code> </code><code>inet6 fe80::42:aff:fe0a:1304</code><code>/64</code> <code>scope link</code>
<code>root@4bdcce0ee63e:/</code><code># ping 10.10.19.3</code>
<code>PING 10.10.19.3 (10.10.19.3): 56 data bytes</code>
<code>64 bytes from 10.10.19.3: icmp_seq=0 ttl=64 </code><code>time</code><code>=0.890 ms</code>
<code>64 bytes from 10.10.19.3: icmp_seq=1 ttl=64 </code><code>time</code><code>=0.622 ms</code>
<code>.....-</code>
<code>2 packets transmitted, 2 packets received, 0% packet loss</code>
<code>round-trip min</code><code>/avg/max/stddev</code> <code>= 0.622</code><code>/0</code><code>.756</code><code>/0</code><code>.890</code><code>/0</code><code>.134 ms</code>
<code>root@4bdcce0ee63e:/</code><code># ping 10.10.19.6</code>
<code>PING 10.10.19.6 (10.10.19.6): 56 data bytes</code>
<code>64 bytes from 10.10.19.6: icmp_seq=0 ttl=64 </code><code>time</code><code>=0.939 ms</code>
<code>64 bytes from 10.10.19.6: icmp_seq=1 ttl=64 </code><code>time</code><code>=0.590 ms</code>
<code>----------------------------使用swarm模式的服務發現--------------------------</code>
<code>預設情況下,當建立了一個服務并連接配接到某個網絡後,swarm會為該服務配置設定一個VIP。此VIP根據服務名映射到DNS。在網絡上的容器共享該服務的DNS映射,</code>
<code>是以網絡上的任意容器可以通過服務名通路服務。</code>
<code>在同一overlay網絡中,不用通過端口映射來使某個服務可以被其它服務通路。Swarm内部的負載均衡器自動将請求發送到服務的VIP上,然後分發到所有的</code>
<code>active的task上。</code>
<code>如下示例:</code>
<code>在同一個網絡中添加了一個centos服務,此服務可以通過名稱my-</code><code>test</code><code>通路前面建立的nginx服務:</code>
<code>[root@manager-node ~]</code><code># docker service create --name my-centos --network ngx_net centos </code>
<code>查詢centos運作在哪個節點上(上面建立指令執行後,需要一段時間才能完成這個centos服務的建立)</code>
<code>[root@manager-node ~]</code><code># docker service ps my-centos</code>
<code>ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR</code>
<code>e03pqgkjs3l1qizc6v4aqaune my-centos.1 centos node2 Running Preparing 4 seconds ago</code>
<code>登入centos運作的節點(由上可知是node2節點),打開centos的互動shell:</code>
<code>CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES</code>
<code>e4554490d891 centos:latest </code><code>"/bin/bash"</code> <code>About an hour ago Up About an hour my-centos.1.9yk5ie28gwk9mw1h1jovb68ki</code>
<code>[root@node2 ~]</code><code># docker exec -ti my-centos.1.9yk5ie28gwk9mw1h1jovb68ki /bin/bash</code>
<code>root@4bdcce0ee63e:/</code><code># nslookup my-test</code>
<code>Server: 127.0.0.11</code>
<code>Address 1: 127.0.0.11</code>
<code>Name: my-</code><code>test</code>
<code>Address 1: 10.10.19.2 10.10.19.2</code>
<code>從centos容器内部,使用特殊查詢 查詢DNS,來找到my-</code><code>test</code><code>服務的所有容器的IP位址:</code>
<code>root@4bdcce0ee63e:/</code><code># nslookup tasks.my-test</code>
<code>Name: tasks.my-</code><code>test</code>
<code>Address 1: 10.10.19.4 my-</code><code>test</code><code>.1.8433fuiy7vpu0p80arl7vggfe</code>
<code>Address 2: 10.10.19.5 my-</code><code>test</code><code>.2.f1h7a0vtojv18zrsiw8j0rzaw</code>
<code>Address 3: 10.10.19.6 my-</code><code>test</code><code>.3.ex73ifk3jvzw8ukurl8yu7fyq</code>
<code>Address 2: 10.10.19.7 my-</code><code>test</code><code>.4.cyu73jd8psupfhken23vvmpud</code>
<code>Address 3: 10.10.19.3 my-</code><code>test</code><code>.5.btorxekfix4hcqh4v83dr0tzw</code>
<code>從centos容器内部,通過wget來通路my-</code><code>test</code><code>服務中運作的nginx網頁伺服器</code>
<code>root@4bdcce0ee63e:/</code><code># wget -O- my-test </code>
<code>Connecting to my-</code><code>test</code> <code>(10.10.19.2:80)</code>
<code><!DOCTYPE html></code>
<code><html></code>
<code><</code><code>head</code><code>></code>
<code><title>Welcome to nginx!<</code><code>/title</code><code>></code>
<code>...</code>
<code>Swarm的負載均衡器自動将HTTP請求路由到VIP上,然後到一個active的task容器上。它根據round-robin選擇算法将後續的請求分發到另一個active的task上。</code>
<code>-----------------------------------為服務使用DNS round-robin-----------------------------</code>
<code>在建立服務時,可以配置服務直接使用DNS round-robin而無需使用VIP。這是通過在建立服務時指定 --endpoint-mode dnsrr 指令行參數實作的。</code>
<code>當你想要使用自己的負載均衡器時可以使用這種方式。</code>
<code>如下示例(注意:使用DNS round-robin方式建立服務,不能直接在指令裡使用-p指定端口)</code>
<code>[root@manager-node ~]</code><code># docker service create --replicas 3 --name my-dnsrr-nginx --network ngx_net --endpoint-mode dnsrr nginx</code>
<code>[root@manager-node ~]</code><code># docker service ps my-dnsrr-nginx</code>
<code>ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR</code>
<code>65li2zbhxvvoaesndmwjokouj my-dnsrr-nginx.1 nginx node1 Running Running 2 minutes ago </code>
<code>5hjw7wm4xr877879m0ewjciuj my-dnsrr-nginx.2 nginx manager-node Running Running 2 minutes ago </code>
<code>afo7acduge2qfy60e87liz557 my-dnsrr-nginx.3 nginx manager-node Running Running 2 minutes ago</code>
<code>當通過服務名稱查詢DNS時,DNS服務傳回所有任務容器的IP位址:</code>
<code>root@4bdcce0ee63e:/</code><code># nslookup my-dnsrr-nginx </code>
<code>Server: 127.0.0.11</code>
<code>Name: my-dnsrr-nginx</code>
<code>Address 1: 10.10.19.10 my-dnsrr-nginx.3.0sm1n9o8hygzarv5t5eq46okn.my-network</code>
<code>Address 2: 10.10.19.9 my-dnsrr-nginx.2.b3o1uoa8m003b2kk0ytl9lawh.my-network</code>
<code>Address 3: 10.10.19.8 my-dnsrr-nginx.1.55za4c83jq9846rle6eigiq15.my-network</code>
<code>需要注意的是:一定要确認VIP的連通性</code>
<code>通常Docker官方推薦使用</code><code>dig</code><code>,</code><code>nslookup</code><code>或其它DNS查詢工具來查詢通過DNS對服務名的通路。因為VIP是邏輯IP,</code><code>ping</code><code>并不是确認VIP連通性的正确的工具。</code>
***************當你發現自己的才華撐不起野心時,就請安靜下來學習吧***************
本文轉自散盡浮華部落格園部落格,原文連結:http://www.cnblogs.com/kevingrace/p/6883750.html,如需轉載請自行聯系原作者