天天看点

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,如需转载请自行联系原作者