摘要:基于近期學(xué)習(xí)的內(nèi)容,整理與網(wǎng)絡(luò)相關(guān)的知識(shí)。針對(duì)這一問題,采用網(wǎng)絡(luò)來解決。但這篇博客的重點(diǎn)不在,我們可以在啟動(dòng)時(shí),為其指定一個(gè)分布式存儲(chǔ),從而使得我們能夠?qū)嶒?yàn)網(wǎng)絡(luò)。
基于近期學(xué)習(xí)的 Docker 內(nèi)容,整理與 Docker 網(wǎng)絡(luò)相關(guān)的知識(shí)。實(shí)驗(yàn)環(huán)境:Centos 7.4
Docker 版本如下:
Client: Version: 18.03.1-ce API version: 1.37 Go version: go1.9.5 Git commit: 9ee9f40 Built: Thu Apr 26 07:20:16 2018 OS/Arch: linux/amd64 Experimental: false Orchestrator: swarm Server: Engine: Version: 18.03.1-ce API version: 1.37 (minimum version 1.12) Go version: go1.9.5 Git commit: 9ee9f40 Built: Thu Apr 26 07:23:58 2018 OS/Arch: linux/amd64 Experimental: false1. Linux 網(wǎng)絡(luò)命名空間與 Veth 1.1 Linux 網(wǎng)絡(luò)命名空間
以下摘自 linux 網(wǎng)絡(luò)命名空間 Network namespaces - CSDN博客 :
Linux命名空間是一個(gè)相對(duì)較新的內(nèi)核功能,對(duì)于實(shí)現(xiàn)容器至關(guān)重要。 命名空間將全局系統(tǒng)資源包裝到一個(gè)抽象中,該抽象只會(huì)與命名空間中的進(jìn)程綁定,從而提供資源隔離。Linux內(nèi)核提供了6種類型的命名空間:pid,net,mnt,uts,ipc和user。網(wǎng)絡(luò)命名空間為命名空間中的所有進(jìn)程提供了全新的網(wǎng)絡(luò)堆棧。 這包括網(wǎng)絡(luò)接口,路由表和iptables規(guī)則。
我們可以使用:
ip netns list
查看當(dāng)前系統(tǒng)中存在的網(wǎng)絡(luò)空間
或者通過以下指令增加或刪除:
# 增加 ip netns add ns1 # 刪除 ip netns delete ns1
這里,我們使用如下指令,查看 ns1 網(wǎng)絡(luò)命名空間中網(wǎng)絡(luò)情況:
[root@localhost vagrant]# ip netns exec ns1 ip a 1: lo:mtu 65536 qdisc noop state DOWN qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
可以看到,在新創(chuàng)建的 ns1 中,僅存在一個(gè)處于 DOWN 狀態(tài)的本地回環(huán)端口。
此時(shí),我們使用以下指令執(zhí)行時(shí),會(huì)發(fā)現(xiàn)網(wǎng)絡(luò)不通:
[root@localhost vagrant]# ip netns exec ns1 ping localhost -c 4 connect: 網(wǎng)絡(luò)不可達(dá)
此時(shí)我們需要借助 ip link,將 lo 端口 UP 起來:
ip netns exec ns1 set dev lo up
此時(shí),對(duì)本地端口的 ping 請(qǐng)求就可達(dá)了:
[root@localhost vagrant]# ip netns exec ns1 ping localhost -c 4 PING localhost (127.0.0.1) 56(84) bytes of data. 64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.031 ms 64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.060 ms 64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.070 ms 64 bytes from localhost (127.0.0.1): icmp_seq=4 ttl=64 time=0.036 ms --- localhost ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3004ms rtt min/avg/max/mdev = 0.031/0.049/0.070/0.017 ms
注:ip link 指令可以查到本機(jī)網(wǎng)絡(luò)接口情況,這一指令在 Veth 中還會(huì)提到。
1.2 Veth關(guān)于 Veth 的特點(diǎn),以下摘自:Linux虛擬網(wǎng)絡(luò)設(shè)備之veth - Linux程序員 - SegmentFault 思否:
veth和其它的網(wǎng)絡(luò)設(shè)備都一樣,一端連接的是內(nèi)核協(xié)議棧。
veth設(shè)備是成對(duì)出現(xiàn)的,另一端兩個(gè)設(shè)備彼此相連
一個(gè)設(shè)備收到協(xié)議棧的數(shù)據(jù)發(fā)送請(qǐng)求后,會(huì)將數(shù)據(jù)發(fā)送到另一個(gè)設(shè)備上去。
這里,我們?cè)傩陆ㄒ粋€(gè) ns2 的網(wǎng)絡(luò)命名空間,并通過 Veth,實(shí)現(xiàn) ns1 和 ns2 之間的連通,步驟如下:
1.2.1 準(zhǔn)備 ns1 和 ns2 網(wǎng)絡(luò)命名空間首先,我們通過:
ip netns add ns2
創(chuàng)建 ns2 網(wǎng)絡(luò)命名空間。
注:也可仿照上述 ns1 的做法,將 ns2 中 lo 置于 UP 狀態(tài)。
1.2.2 創(chuàng)建 Veth pair下面,我們執(zhí)行如下指令,創(chuàng)建 Veth pair:
ip link add veth-ns1 type veth peer name veth-ns2
之后,我們可以通過 ip link 指令,看到接口列表中新增了我們剛剛添加的那個(gè) veth pair:
[root@localhost vagrant]# ip link ... 4: veth-ns2@veth-ns1:1.2.3 將 Veth pair 兩端分別加入到 ns1 和 ns2mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000 link/ether 8e:3c:d3:98:29:9d brd ff:ff:ff:ff:ff:ff 5: veth-ns1@veth-ns2: mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000 link/ether 92:8a:2f:d6:e0:72 brd ff:ff:ff:ff:ff:ff
執(zhí)行以下指令:
# 將 Veth pair 的 veth-ns1 添加到 ns1 ip link set veth-ns1 netns ns1 # 將 Veth pair 的 veth-ns2 添加到 ns2 ip link set veth-ns2 netns ns2
此時(shí),我們?cè)俅螆?zhí)行 ip link,會(huì)發(fā)現(xiàn),之前創(chuàng)建 Veth pair 的兩端已經(jīng)分別存在于 ns1 和 ns2 中:
ip netns exec ns1 ip link ip netns exec ns2 ip link1.2.4 為 Veth pair 的兩端分別配置 IP 地址
執(zhí)行以下指令:
ip netns exec ns1 ip addr add 192.168.1.1/24 dev veth-ns1 ip netns exec ns2 ip addr add 192.168.1.2/24 dev veth-ns2
注意,這一步一定要在 Veth pair 的兩端加入到 ns1、ns2 之后進(jìn)行。
1.2.5 將 Veth pair 的兩端置為 UP 狀態(tài)執(zhí)行以下指令:
ip netns exec ns1 ip link set dev veth-ns1 up ip netns exec ns2 ip link set dev veth-ns2 up
此時(shí),我們便可以通過 ip a 看到目前該網(wǎng)絡(luò)空間的情況了:
###### ns1 ###### [root@localhost vagrant]# ip netns exec ns1 ip a 1: lo:1.2.6 檢驗(yàn)連通mtu 65536 qdisc noqueue state UNKNOWN qlen 1 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 5: veth-ns1@if4: mtu 1500 qdisc noqueue state UP qlen 1000 link/ether 92:8a:2f:d6:e0:72 brd ff:ff:ff:ff:ff:ff link-netnsid 1 inet 192.168.1.1/24 scope global veth-ns1 valid_lft forever preferred_lft forever inet6 fe80::908a:2fff:fed6:e072/64 scope link valid_lft forever preferred_lft forever ###### ns1 ###### [root@localhost vagrant]# ip netns exec ns2 ip a 1: lo: mtu 65536 qdisc noqueue state UNKNOWN qlen 1 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 4: veth-ns2@if5: mtu 1500 qdisc noqueue state UP qlen 1000 link/ether 8e:3c:d3:98:29:9d brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 192.168.1.2/24 scope global veth-ns2 valid_lft forever preferred_lft forever inet6 fe80::8c3c:d3ff:fe98:299d/64 scope link valid_lft forever preferred_lft forever
通過兩端互 ping 的方式,檢測(cè)連通性:
ns1 -> ns2
[root@localhost vagrant]# ip netns exec ns1 ping 192.168.1.2 -c 4 PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data. 64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.037 ms 64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=0.040 ms 64 bytes from 192.168.1.2: icmp_seq=3 ttl=64 time=0.046 ms 64 bytes from 192.168.1.2: icmp_seq=4 ttl=64 time=0.044 ms --- 192.168.1.2 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3000ms rtt min/avg/max/mdev = 0.037/0.041/0.046/0.008 ms
ns2 -> ns1
[root@localhost vagrant]# ip netns exec ns2 ping 192.168.1.1 -c 4 PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.030 ms 64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.038 ms 64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=0.068 ms 64 bytes from 192.168.1.1: icmp_seq=4 ttl=64 time=0.067 ms --- 192.168.1.1 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3006ms rtt min/avg/max/mdev = 0.030/0.050/0.068/0.019 ms1.2.7 總結(jié)
以上過程的核心步驟示意如下:
2. Docker bridge 型網(wǎng)絡(luò) 與 bridge0 2.1 bridge 連通實(shí)驗(yàn)執(zhí)行 ip link,我們可以看到:
[root@localhost vagrant]# ip link ... 3: docker0:mtu 1500 qdisc noqueue state UP mode DEFAULT link/ether 02:42:7f:68:8e:01 brd ff:ff:ff:ff:ff:ff
這里存在一個(gè) docker0,這在 Docker bridge 型網(wǎng)絡(luò)中起到至關(guān)重要的作用。
注意:根據(jù) Docker 官方文檔:Networking features in Docker for Mac | Docker Documentation,在 Mac OS 中是沒有 bridge0 的。推薦使用 Centos 系統(tǒng)進(jìn)行試驗(yàn)。
接著,我們使用如下指令創(chuàng)建一個(gè) Container,用以觀察容器 bridge 型網(wǎng)絡(luò)的實(shí)現(xiàn)方式:
docker run -d --name box1 busybox /bin/sh -c "while true; do sleep 3600; done;"
注:
使用一個(gè)死循環(huán)指令可以使得容器不會(huì)立刻停止;
Docker 容器默認(rèn)的網(wǎng)絡(luò)為 bridge
然后執(zhí)行 ip link 觀察變化,可以發(fā)現(xiàn),列表中多出了如下部分:
[root@localhost vagrant]# ip link ... 11: veth4f19367@if10:mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT link/ether 42:01:42:6c:52:5a brd ff:ff:ff:ff:ff:ff link-netnsid 0
接著,為了觀察網(wǎng)絡(luò)橋接情況,我們需要安裝一個(gè)軟件:
yum install bridge-utils
然后使用:
[root@localhost vagrant]# brctl show bridge name bridge id STP enabled interfaces docker0 8000.02427f688e01 no veth4f19367
可以看到,創(chuàng)建 box1 容器后,新增的 Veth 通過橋接連接到了 docker0 上,使得容器和宿主機(jī)之間可以互相連通。
為了檢測(cè)連通性,首先我們執(zhí)行:
[root@localhost vagrant]# ip a ... 3: docker0:mtu 1500 qdisc noqueue state UP link/ether 02:42:7f:68:8e:01 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:7fff:fe68:8e01/64 scope link valid_lft forever preferred_lft forever ...
得到宿主機(jī)的 IP 為 172.17.0.1/16
然后通過:
[root@localhost vagrant]# docker exec box1 ip a ... 10: eth0@if11:mtu 1500 qdisc noqueue link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever
得到 box1 這一容器的 IP 為 172.17.0.2/16
之后,便可以通過以下方式檢測(cè)二者互相的連通性:
宿主機(jī)( 172.17.0.1 )-> 容器( 172.17.0.2 )
[root@localhost vagrant]# ping 172.17.0.2 -c 4 PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data. 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.049 ms 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.054 ms 64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.057 ms 64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.082 ms --- 172.17.0.2 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3001ms rtt min/avg/max/mdev = 0.049/0.060/0.082/0.014 ms
容器( 172.17.0.2 )-> 宿主機(jī)( 172.17.0.1 )
[root@localhost vagrant]# docker exec box1 ping 172.17.0.1 -c 4 PING 172.17.0.1 (172.17.0.1): 56 data bytes 64 bytes from 172.17.0.1: seq=0 ttl=64 time=0.068 ms 64 bytes from 172.17.0.1: seq=1 ttl=64 time=0.258 ms 64 bytes from 172.17.0.1: seq=2 ttl=64 time=0.084 ms 64 bytes from 172.17.0.1: seq=3 ttl=64 time=0.087 ms --- 172.17.0.1 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.068/0.124/0.258 ms
同理,我們可以再創(chuàng)建一個(gè) box2 容器,檢測(cè) box1 與 box2 之間的連通性。由于方法相同,這里簡(jiǎn)述如下:
# 創(chuàng)建 box2 容器 docker run -d --name box2 busybox /bin/sh -c "while true; do sleep 3600; done;" # 【省略】通過 ip a 分別查詢 box1 和 box2 的 ip # 連通測(cè)試 box1 -> box2 docker exec box1 ping 172.17.0.3 -c 4 # 連通測(cè)試 box2 -> box1 docker exec box2 ping 172.17.0.2 -c 42.2 總結(jié)
如上,Docker 中實(shí)現(xiàn) bridge 型網(wǎng)絡(luò)互連的方式如下圖:
此外,bridge 型網(wǎng)絡(luò)中,容器與公網(wǎng)連通的方式如下:
注:bridge 指的是網(wǎng)絡(luò)類型,bridge0 是接口名。
3. 以容器名進(jìn)行網(wǎng)絡(luò)連接在 Docker 容器中,以 IP 方式進(jìn)行彼此連通,會(huì)使得很多業(yè)務(wù)場(chǎng)景首先,我們更期望使用域名或者別名進(jìn)行網(wǎng)絡(luò)訪問,從而在 IP 地址變化時(shí),依然保證系統(tǒng)各模塊的穩(wěn)定( 每次創(chuàng)建容器,其 IP 地址不是恒定的 )。
由此,我們可以使用如下方式實(shí)現(xiàn)這一功能。
首先,我們需要將先前啟動(dòng)的容器停止并刪除:
docker rm -f $(docker ps -aq)
注:這一指令會(huì)停止并刪除所有容器。
3.1 Docker link此方法旨在使用 docker 啟動(dòng)時(shí)的 --link
docker run -d --name box1 busybox /bin/sh -c "while true; do sleep 3600; done;" # 注意,這里添加了 --link box1 參數(shù) docker run -d --name box2 --link box1 busybox /bin/sh -c "while true; do sleep 3600; done;"3.1.2 連通測(cè)試——以 IP
box1 -> box2
[root@localhost vagrant]# docker exec box1 ping 172.17.0.3 -c 4 PING 172.17.0.3 (172.17.0.3): 56 data bytes 64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.071 ms 64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.158 ms 64 bytes from 172.17.0.3: seq=2 ttl=64 time=0.110 ms 64 bytes from 172.17.0.3: seq=3 ttl=64 time=0.146 ms --- 172.17.0.3 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.071/0.121/0.158 ms
box2 -> box1
[root@localhost vagrant]# docker exec box2 ping 172.17.0.2 -c 4 PING 172.17.0.2 (172.17.0.2): 56 data bytes 64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.081 ms 64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.082 ms 64 bytes from 172.17.0.2: seq=2 ttl=64 time=0.091 ms 64 bytes from 172.17.0.2: seq=3 ttl=64 time=0.109 ms --- 172.17.0.2 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.081/0.090/0.109 ms3.1.3 連通測(cè)試——以容器名
box1 -> box2
[root@localhost vagrant]# docker exec box1 ping box2 -c 4 ping: bad address "box2"
box2 -> box1
[root@localhost vagrant]# docker exec box2 ping box1 -c 4 PING box1 (172.17.0.2): 56 data bytes 64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.073 ms 64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.106 ms 64 bytes from 172.17.0.2: seq=2 ttl=64 time=0.173 ms 64 bytes from 172.17.0.2: seq=3 ttl=64 time=0.078 ms --- box1 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.073/0.107/0.173 ms3.2 自定義 bridge 類型網(wǎng)絡(luò)
對(duì) Docker 而言,我們可以新建一個(gè) bridge 類型的網(wǎng)絡(luò),并將需要以彼此的容器名互聯(lián)的容器添加到這一網(wǎng)絡(luò)中,即可實(shí)現(xiàn)上述需求。注意,一定要使用新建的 bridge 網(wǎng)絡(luò),采用默認(rèn)的那個(gè)是不行的。
為了進(jìn)行試驗(yàn),我們需要先將 3.1 中創(chuàng)建的容器刪除,然后進(jìn)行如下步驟:
3.2.1 新建 bridge 類型網(wǎng)絡(luò)執(zhí)行如下指令,創(chuàng)建 bridge 類型網(wǎng)絡(luò):
docker network create my-bridge --driver bridge3.2.2 創(chuàng)建容器
這里,我們創(chuàng)建三個(gè)容器:box1、box2、box3,并將 box1 和 box2 加入新創(chuàng)建的 my-bridge 網(wǎng)絡(luò)中:
docker run -d --name box1 --network my-bridge busybox /bin/sh -c "while true; do sleep 3600; done;" docker run -d --name box2 --network my-bridge busybox /bin/sh -c "while true; do sleep 3600; done;" docker run -d --name box3 busybox /bin/sh -c "while true; do sleep 3600; done;"
然后,我們同一下指令,檢測(cè)容器是否存在于網(wǎng)絡(luò)中:
檢查 my-bridge 網(wǎng)絡(luò)中有哪些容器:
# 指令 docker network inspect my-bridge # 結(jié)果 "Containers": { "70b929cee25b665ff0d55cd4e979fcf8dd21190c6200d49af0f2bef07efb723e": { "Name": "box2", "EndpointID": "6c19d556751f3e745f947cc0b0e2995312b6712055fac4d79a52114b6f21ffffd2", "MacAddress": "02:42:ac:12:00:03", "IPv4Address": "172.18.0.3/16", "IPv6Address": "" }, "92d63195660f1e666028294144ffffd65be06e38827debaad1ebd90ce9c79dbaa7": { "Name": "box1", "EndpointID": "9b28b2e724ff19e1cbce1fb05afe4a439f51735c0a2a7671c8002fa58c087199", "MacAddress": "02:42:ac:12:00:02", "IPv4Address": "172.18.0.2/16", "IPv6Address": "" } }
檢查 bridge 網(wǎng)絡(luò)中有哪些容器:
# 指令 docker network inspect bridge # 結(jié)果 "Containers": { "5526023acd4197c9abf6f17c9a59585322cd2154b70238872083e48b7012ab4e": { "Name": "box3", "EndpointID": "6ceb455b487e533439c715a48849986a62ecda68d51d141f228ebdb7d06cf560", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" } }3.2.3 測(cè)試
首先,我們對(duì)處于 my-bridge 這一自定義網(wǎng)絡(luò)中的容器 box1、box2 之間的連通性進(jìn)行測(cè)試( 通過容器名 ):
[root@localhost vagrant]# docker exec box1 ping box2 -c 1 PING box2 (172.18.0.3): 56 data bytes 64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.052 ms --- box2 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.052/0.052/0.052 ms [root@localhost vagrant]# docker exec box2 ping box1 -c 1 PING box1 (172.18.0.2): 56 data bytes 64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.053 ms --- box1 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.053/0.053/0.053 ms
然后我們測(cè)試 box3 與 box1、box2 之間的連通性( 通過容器名 ):
[root@localhost vagrant]# docker exec box1 ping box3 -c 1 ping: bad address "box3" [root@localhost vagrant]# docker exec box2 ping box3 -c 1 ping: bad address "box3" [root@localhost vagrant]# docker exec box3 ping box1 -c 1 ping: bad address "box1" [root@localhost vagrant]# docker exec box3 ping box2 -c 1 ping: bad address "box2"
然后,我們測(cè)試一下這三個(gè)容器對(duì)公網(wǎng)的連通性:
[root@localhost vagrant]# docker exec box1 ping www.baidu.com -c 1 PING www.baidu.com (115.239.210.27): 56 data bytes 64 bytes from 115.239.210.27: seq=0 ttl=61 time=22.467 ms --- www.baidu.com ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 22.467/22.467/22.467 ms [root@localhost vagrant]# docker exec box2 ping www.baidu.com -c 1 PING www.baidu.com (115.239.210.27): 56 data bytes 64 bytes from 115.239.210.27: seq=0 ttl=61 time=19.068 ms --- www.baidu.com ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 19.068/19.068/19.068 ms [root@localhost vagrant]# docker exec box3 ping www.baidu.com -c 1 PING www.baidu.com (115.239.211.112): 56 data bytes 64 bytes from 115.239.211.112: seq=0 ttl=61 time=20.087 ms --- www.baidu.com ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 20.087/20.087/20.087 ms
可以發(fā)現(xiàn):
box1 和 box2 之間是相互連通的( 通過容器名 );
box3 之于 box1、box2 都是不連通的( 通過容器名 );
這三個(gè)容器對(duì)公網(wǎng)都是連通的。
3.3 Docker network connect對(duì)于已經(jīng)啟動(dòng)的容器,可以通過 docker network connect
接著 3.2 中的試驗(yàn),我們將 box3 容器加入到 my-bridge 網(wǎng)絡(luò)中,然后重新檢測(cè)其對(duì) box1、box2 的連通性:
3.3.1 將 box3 加入 my-bridge 網(wǎng)絡(luò)中docker network connect my-bridge box33.3.2 檢驗(yàn) my-bridge 網(wǎng)絡(luò)中現(xiàn)有容器情況
# 指令 docker network inspect my-bridge # 結(jié)果 "Containers": { "5526023acd4197c9abf6f17c9a59585322cd2154b70238872083e48b7012ab4e": { "Name": "box3", "EndpointID": "b7fe8d2697ab20ec5a92886768e33345dd7d161488ac30488e8800e4b0fb0166", "MacAddress": "02:42:ac:12:00:04", "IPv4Address": "172.18.0.4/16", "IPv6Address": "" }, "70b929cee25b665ff0d55cd4e979fcf8dd21190c6200d49af0f2bef07efb723e": { "Name": "box2", "EndpointID": "6c19d556751f3e745f947cc0b0e2995312b6712055fac4d79a52114b6f21ffffd2", "MacAddress": "02:42:ac:12:00:03", "IPv4Address": "172.18.0.3/16", "IPv6Address": "" }, "92d63195660f1e666028294144ffffd65be06e38827debaad1ebd90ce9c79dbaa7": { "Name": "box1", "EndpointID": "9b28b2e724ff19e1cbce1fb05afe4a439f51735c0a2a7671c8002fa58c087199", "MacAddress": "02:42:ac:12:00:02", "IPv4Address": "172.18.0.2/16", "IPv6Address": "" } }
可以發(fā)現(xiàn),box3 已經(jīng)加入到了 my-bridge 網(wǎng)絡(luò)之中。
3.3.3 檢驗(yàn) box3 對(duì) box1、box2 之間的連通性( 通過容器名 )[root@localhost vagrant]# docker exec box3 ping box1 PING box1 (172.18.0.2): 56 data bytes 64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.075 ms ^C [root@localhost vagrant]# docker exec box3 ping box1 -c 1 PING box1 (172.18.0.2): 56 data bytes 64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.066 ms --- box1 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.066/0.066/0.066 ms [root@localhost vagrant]# docker exec box3 ping box2 -c 1 PING box2 (172.18.0.3): 56 data bytes 64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.069 ms --- box2 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.069/0.069/0.069 ms [root@localhost vagrant]# docker exec box1 ping box3 -c 1 PING box3 (172.18.0.4): 56 data bytes 64 bytes from 172.18.0.4: seq=0 ttl=64 time=0.050 ms --- box3 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.050/0.050/0.050 ms [root@localhost vagrant]# docker exec box2 ping box3 -c 1 PING box3 (172.18.0.4): 56 data bytes 64 bytes from 172.18.0.4: seq=0 ttl=64 time=0.052 ms --- box3 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.052/0.052/0.052 ms
可以發(fā)現(xiàn),現(xiàn)在 box1、box2、box3 之間可以互相通過容器名連通了。
4. Overlay 網(wǎng)絡(luò)實(shí)現(xiàn)多 Docker 節(jié)點(diǎn)中容器間通信 4.1 多 Docker 節(jié)點(diǎn)中容器間通信問題在實(shí)際生產(chǎn)中,往往存在不同主機(jī)間 Docker 容器的互訪問題,如下圖所示:
由于 box_o_1 和 box_o_2 處于各自機(jī)器的 Docker 中,若想互相訪問,可以通過層層路由配置,使數(shù)據(jù)包可以在二者之間傳遞。
這一過程在管理和擴(kuò)展上都比較麻煩。針對(duì)這一問題,Docker 采用 Overlay 網(wǎng)絡(luò)來解決。
4.2 Overlay 網(wǎng)絡(luò)與 VXLAN簡(jiǎn)而言之,Overlay 可以使得我們將報(bào)文在 IP 報(bào)文之上再次封裝。以 4.1 中的圖舉例,Overlay 使得數(shù)據(jù)可以先通過傳統(tǒng)網(wǎng)絡(luò)由左側(cè)節(jié)點(diǎn)到達(dá)右側(cè)節(jié)點(diǎn),數(shù)據(jù)包在右側(cè)節(jié)點(diǎn)拆包后,其內(nèi)容又是一個(gè)標(biāo)準(zhǔn)的網(wǎng)絡(luò)數(shù)據(jù)包,進(jìn)而能夠傳遞到 box_o_2 容器中。
在 Overlay 網(wǎng)絡(luò)中,VXLAN 技術(shù)為其核心,以下內(nèi)容摘自:Overlay之VXLAN架構(gòu):
VXLAN: VXLAN是將以太網(wǎng)報(bào)文封裝成UDP報(bào)文進(jìn)行隧道傳輸,UDP目的端口為已知端口,源端口可按流分配,標(biāo)準(zhǔn)5元組方式有利于在IP網(wǎng)絡(luò)轉(zhuǎn)發(fā)過程中進(jìn)行負(fù)載分擔(dān);隔離標(biāo)識(shí)采用24比特來表示;未知目的、廣播、組播等網(wǎng)絡(luò)流量均被封裝為組播轉(zhuǎn)發(fā)。
VXLAN 報(bào)文結(jié)構(gòu)如下,下圖取自:QinQ vs VLAN vs VXLAN:
4.3 在 Docker 中使用 Overlay 4.3.1 實(shí)驗(yàn)?zāi)康募扒爸脺?zhǔn)備在這一實(shí)驗(yàn)中,我們需要準(zhǔn)備:
兩臺(tái)已安裝 Docker 的機(jī)器。這里的機(jī)器系統(tǒng)為:Centos7.4,機(jī)器 IP 分別為:192.168.33.10 及 192.168.33.11;
兩臺(tái) Docker 機(jī)器之間彼此互通。
實(shí)驗(yàn)的目的是實(shí)現(xiàn)位于兩臺(tái)機(jī)器上兩個(gè)容器彼此互通。
4.3.2 etcd當(dāng)我們?cè)谄渲幸慌_(tái)機(jī)器上創(chuàng)建一個(gè) overlay 類型的網(wǎng)絡(luò)時(shí),會(huì)報(bào)錯(cuò)如下:
[vagrant@192-168-33-10 ~]$ docker network create -d overlay my-overlay Error response from daemon: This node is not a swarm manager. Use "docker swarm init" or "docker swarm join" to connect this node to swarm and try again.
這里是提示我們,單機(jī)模式時(shí),是無法創(chuàng)建 overlay 類型網(wǎng)絡(luò)的。要想實(shí)現(xiàn),這一需求,可以使用 Docker 編排工具,如 swarm。
但這篇博客的重點(diǎn)不在 swarm,我們可以在 docker 啟動(dòng)時(shí),為其指定一個(gè)分布式存儲(chǔ),從而使得我們能夠?qū)嶒?yàn) overlay 網(wǎng)絡(luò)。
etcd 是一個(gè)分布式鍵值存儲(chǔ)系統(tǒng),其 Github 地址為:GitHub - coreos/etcd: Distributed reliable key-value store for the most critical data of a distributed system。
關(guān)于 etcd 的安裝細(xì)節(jié)可以參考另一篇博文:分布式 key-value 存儲(chǔ)系統(tǒng) etcd 的安裝備忘。這里直接貼出安裝指令:
# 在兩臺(tái)機(jī)器上下載、解壓 etcd,并進(jìn)入 etcd 目錄 wget https://github.com/coreos/etcd/releases/download/v3.3.8/etcd-v3.3.8-linux-amd64.tar.gz tar -zvxf etcd-v3.3.8-linux-amd64.tar.gz cd etcd-v3.3.8-linux-amd64 # 在 192.168.33.10 中執(zhí)行 nohup ./etcd --name my-etcd-1 --listen-client-urls http://192.168.33.10:2379 --advertise-client-urls http://192.168.33.10:2379 --listen-peer-urls http://192.168.33.10:2380 --initial-advertise-peer-urls http://192.168.33.10:2380 --initial-cluster my-etcd-1=http://192.168.33.10:2380,my-etcd-2=http://192.168.33.11:2380 --initial-cluster-token my-etcd-token --initial-cluster-state new >/dev/null 2>&1 & # 在 192.168.33.11 中執(zhí)行 nohup ./etcd --name my-etcd-2 --listen-client-urls http://192.168.33.11:2379 --advertise-client-urls http://192.168.33.11:2379 --listen-peer-urls http://192.168.33.11:2380 --initial-advertise-peer-urls http://192.168.33.11:2380 --initial-cluster my-etcd-1=http://192.168.33.10:2380,my-etcd-2=http://192.168.33.11:2380 --initial-cluster-token my-etcd-token --initial-cluster-state new >/dev/null 2>&1 &
最終可以通過以下方式檢測(cè)集群的啟動(dòng)情況:
[vagrant@192-168-33-10 etcd-v3.3.8-linux-amd64]$ ./etcdctl --endpoints http://192.168.33.10:2379 cluster-health member 42ab269b4f75b118 is healthy: got healthy result from http://192.168.33.11:2379 member 7118e8ab00eced36 is healthy: got healthy result from http://192.168.33.10:2379 cluster is healthy
注:建議 etcd 啟動(dòng)后,重新 ssh 一次,以免出現(xiàn) etcd 的一些莫名其妙的報(bào)錯(cuò)信息。
4.3.3 借助 etcd 重啟 docker接下來我們要借助 etcd,重啟 docker,并為其指定分布式存儲(chǔ):
首先,在兩臺(tái)機(jī)器上停止 docker:
systemctl stop docker
然后,重啟 docker。注意,這一步需要在 etcd 啟動(dòng)后進(jìn)行:
# 在 192.168.33.10 中執(zhí)行: sudo /usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-store=etcd://192.168.33.10:2379 --cluster-advertise=192.168.33.10:2375 & # 在 192.168.33.11 中執(zhí)行: sudo /usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-store=etcd://192.168.33.11:2379 --cluster-advertise=192.168.33.11:2375 &4.3.4 創(chuàng)建 overlay 網(wǎng)絡(luò)
接下來,我們?cè)俅蝿?chuàng)建 overlay 網(wǎng)絡(luò)
在 192.168.33.10 中執(zhí)行:
[vagrant@192-168-33-10 etcd-v3.3.8-linux-amd64]$ docker network create -d overlay my-overlay 989fbe070eed940a0c3ec4182e7d04413a16eb9e33547b0d88002a7ec5138a07
由于在 docker 啟動(dòng)時(shí)指定了分布式存儲(chǔ),因而我們無需再在 192.168.33.11 中創(chuàng)建這一 overlay 網(wǎng)絡(luò),創(chuàng)建過程已經(jīng)在節(jié)點(diǎn)之間同步了:
# 192.168.33.10 中的網(wǎng)絡(luò)創(chuàng)建行為已經(jīng)在 192.168.33.11 中同步了 [vagrant@192-168-33-11 etcd-v3.3.8-linux-amd64]$ docker network ls NETWORK ID NAME DRIVER SCOPE 16498c285808 bridge bridge local b5cb83566f18 host host local 989fbe070eed my-overlay overlay global 80fe629bd0c3 none null local
為了證明這一點(diǎn),我們可以在 etcd 中看到這一存儲(chǔ):
[vagrant@192-168-33-11 etcd-v3.3.8-linux-amd64]$ ./etcdctl --endpoints http://192.168.33.11:2379 ls /docker/network/v1.0/network /docker/network/v1.0/network/989fbe070eed940a0c3ec4182e7d04413a16eb9e33547b0d88002a7ec5138a07
可以看到,這一網(wǎng)絡(luò)的 Hash 名正是我們?cè)谙惹皠?chuàng)建時(shí)所生成的名字。
注:不同的 docker 版本可能使得這一路徑不同。
4.3.5 創(chuàng)建容器,并使其加入 my-overlay 網(wǎng)絡(luò)# 在 192.168.33.10 上啟動(dòng) box1 [vagrant@192-168-33-10 ~]$ docker run -d --name box1 --network my-overlay busybox /bin/sh -c "while true; do sleep 3600; done" # 在 192.168.33.11 上啟動(dòng) box2 [vagrant@192-168-33-11 ~]$ docker run -d --name box2 --network my-overlay busybox /bin/sh -c "while true; do sleep 3600; done"
接著,我們使用以下指令,查看該網(wǎng)絡(luò)中的容器情況:
docker network inspect my-overlay "Containers": { "46397d0f23812e4252858b8e28c76f6fe5ecc34a95389af0abb22473058cd930": { "Name": "box1", "EndpointID": "b9826147f5b9bdd9e504ecd5860caf85d52151da1c03d47a9627403c55099b2e", "MacAddress": "", "IPv4Address": "10.0.0.2/24", "IPv6Address": "" }, "ep-740ffaf6b455a7f3214ac83d9452d2229f1b19b847c4fba478a1b3650af97927": { "Name": "box2", "EndpointID": "740ffaf6b455a7f3214ac83d9452d2229f1b19b847c4fba478a1b3650af97927", "MacAddress": "", "IPv4Address": "10.0.0.3/24", "IPv6Address": "" } }
可以發(fā)現(xiàn),及時(shí)處于不同的主機(jī)上,我們也在打印的信息中看到這兩個(gè)容器。此外,這兩個(gè)容器的 IP 并沒有重復(fù),這也是借助分布式存儲(chǔ)系統(tǒng)起到的效果。
4.3.6 連接測(cè)試192.168.33.10 - box1(10.0.0.2) -> 192.168.33.11 - box2(10.0.0.3)
[vagrant@192-168-33-10 ~]$ docker exec box1 ping box2 -c 4 PING box2 (10.0.0.3): 56 data bytes 64 bytes from 10.0.0.3: seq=0 ttl=64 time=0.785 ms 64 bytes from 10.0.0.3: seq=1 ttl=64 time=0.643 ms 64 bytes from 10.0.0.3: seq=2 ttl=64 time=0.601 ms 64 bytes from 10.0.0.3: seq=3 ttl=64 time=0.638 ms --- box2 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.601/0.666/0.785 ms [vagrant@192-168-33-10 ~]$ docker exec box1 ping 10.0.0.3 -c 4 PING 10.0.0.3 (10.0.0.3): 56 data bytes 64 bytes from 10.0.0.3: seq=0 ttl=64 time=1.020 ms 64 bytes from 10.0.0.3: seq=1 ttl=64 time=0.690 ms 64 bytes from 10.0.0.3: seq=2 ttl=64 time=1.003 ms 64 bytes from 10.0.0.3: seq=3 ttl=64 time=0.918 ms --- 10.0.0.3 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.690/0.907/1.020 ms
192.168.33.11 - box2(10.0.0.3) -> 192.168.33.10 - box1(10.0.0.2)
[vagrant@192-168-33-11 ~]$ docker exec box2 ping box1 -c 4 PING box1 (10.0.0.2): 56 data bytes 64 bytes from 10.0.0.2: seq=0 ttl=64 time=0.593 ms 64 bytes from 10.0.0.2: seq=1 ttl=64 time=0.691 ms 64 bytes from 10.0.0.2: seq=2 ttl=64 time=0.690 ms 64 bytes from 10.0.0.2: seq=3 ttl=64 time=0.671 ms --- box1 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.593/0.661/0.691 ms [vagrant@192-168-33-11 ~]$ docker exec box2 ping 10.0.0.2 -c 4 PING 10.0.0.2 (10.0.0.2): 56 data bytes 64 bytes from 10.0.0.2: seq=0 ttl=64 time=0.987 ms 64 bytes from 10.0.0.2: seq=1 ttl=64 time=0.699 ms 64 bytes from 10.0.0.2: seq=2 ttl=64 time=0.769 ms 64 bytes from 10.0.0.2: seq=3 ttl=64 time=1.054 ms --- 10.0.0.2 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.699/0.877/1.054 ms
可見,采用 overlay 網(wǎng)絡(luò),可以實(shí)現(xiàn)不同機(jī)器上,docker 容器間的互通。
下面,我們補(bǔ)充之前的圖,用于展示這一實(shí)驗(yàn)中的網(wǎng)絡(luò)拓?fù)淝闆r:
參考鏈接linux 網(wǎng)絡(luò)命名空間 Network namespaces - CSDN博客
Linux虛擬網(wǎng)絡(luò)設(shè)備之veth - Linux程序員 - SegmentFault 思否
Overlay之VXLAN架構(gòu) - CSDN博客
QinQ vs VLAN vs VXLAN
分布式 key-value 存儲(chǔ)系統(tǒng) etcd 的安裝備忘 - DB.Reid - SegmentFault 思否
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/27370.html
摘要:本文整理自時(shí)速云線上微信群分享第十期本文主要包括的基本概念使用場(chǎng)景,以及如何在時(shí)速云平臺(tái)上進(jìn)行的編排部署,希望對(duì)大家在進(jìn)行微服務(wù)架構(gòu)實(shí)踐時(shí)有所幫助。問關(guān)于提供訪問容器數(shù)據(jù)的能力,中包含一個(gè)業(yè)務(wù)和一個(gè)服務(wù),時(shí)速云的控制臺(tái)可以進(jìn)入到容器內(nèi)部。 本文整理自【時(shí)速云線上微信群分享】第十期 本文主要包括Pod的基本概念、使用場(chǎng)景,以及如何在時(shí)速云平臺(tái)上進(jìn)行Pod的編排部署,希望對(duì)大家在進(jìn)行微服務(wù)...
摘要:由于隔離的進(jìn)程獨(dú)立于宿主和其它的隔離的進(jìn)程,因此也稱其為容器。設(shè)計(jì)時(shí),就充分利用的技術(shù),將其設(shè)計(jì)為分層存儲(chǔ)的架構(gòu)。鏡像實(shí)際是由多層文件系統(tǒng)聯(lián)合組成。分層存儲(chǔ)的特征還使得鏡像的復(fù)用定制變的更為容易。前面講過鏡像使用的是分層存儲(chǔ),容器也是如此。 本文只是對(duì)Docker的概念做了較為詳細(xì)的介紹,并不涉及一些像Docker環(huán)境的安裝以及Docker的一些常見操作和命令。 閱讀本文大概需要15分...
摘要:去年換工作后,開始真正在生產(chǎn)環(huán)境中接觸容器與。今天想先談?wù)劊依斫獾娜萜魇鞘裁?,以及為什么它們能火起來。一個(gè)容器鏡像的實(shí)質(zhì)就是程序進(jìn)程加所有運(yùn)行時(shí)環(huán)境及配置依賴的集合。這里再談?wù)勎依斫獾?。而,就是目前的容器編排的平臺(tái)的事實(shí)標(biāo)準(zhǔn)了。 去年換工作后,開始真正在生產(chǎn)環(huán)境中接觸容器與Kubernetes。邊惡補(bǔ)相關(guān)知識(shí)的同時(shí),也想把學(xué)到的內(nèi)容和自己的理解整理出來。學(xué)習(xí)的途徑包括k8s官方文檔...
摘要:去年換工作后,開始真正在生產(chǎn)環(huán)境中接觸容器與。今天想先談?wù)?,我理解的容器是什么,以及為什么它們能火起來。一個(gè)容器鏡像的實(shí)質(zhì)就是程序進(jìn)程加所有運(yùn)行時(shí)環(huán)境及配置依賴的集合。這里再談?wù)勎依斫獾?。而,就是目前的容器編排的平臺(tái)的事實(shí)標(biāo)準(zhǔn)了。 去年換工作后,開始真正在生產(chǎn)環(huán)境中接觸容器與Kubernetes。邊惡補(bǔ)相關(guān)知識(shí)的同時(shí),也想把學(xué)到的內(nèi)容和自己的理解整理出來。學(xué)習(xí)的途徑包括k8s官方文檔...
摘要:一個(gè)卷的掛載傳播由中的字段控制。此模式等同于內(nèi)核文檔中描述的掛載傳播。此卷掛載的行為與掛載相同。掛載傳播可能很危險(xiǎn)。所謂傳播事件,是指由一個(gè)掛載對(duì)象的狀態(tài)變化導(dǎo)致的其它掛載對(duì)象的掛載與解除掛載動(dòng)作的事件。 Mount propagation 掛載傳播允許將Container掛載的卷共享到同一Pod中的其他Container,甚至可以共享到同一節(jié)點(diǎn)上的其他Pod。一個(gè)卷的掛載傳播由Con...
閱讀 1546·2021-11-24 09:39
閱讀 3757·2021-11-24 09:39
閱讀 1940·2021-11-16 11:54
閱讀 1540·2021-09-30 09:47
閱讀 1820·2021-09-26 10:16
閱讀 2397·2021-09-22 15:33
閱讀 1531·2021-09-14 18:01
閱讀 2526·2021-09-07 09:59