天天看點

Swarm基于多主機容器網絡-overlay networks 梳理

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>

Swarm基于多主機容器網絡-overlay networks 梳理

加入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: &lt;LOOPBACK,UP,LOWER_UP&gt; 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: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; 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: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; 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: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; 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>&lt;!DOCTYPE html&gt;</code>

<code>&lt;html&gt;</code>

<code>&lt;</code><code>head</code><code>&gt;</code>

<code>&lt;title&gt;Welcome to nginx!&lt;</code><code>/title</code><code>&gt;</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,如需轉載請自行聯系原作者