昨天我們做了一個小實驗,建立了一對 veth,並且分別把他們放在不同的 net namespace,透過 ping
指令驗證了 veth 可以可以幫我們進行跨 namespace 的溝通,昨天這樣的方式是讓 veth pair 之間直接溝通,今天我們來試試看另外一種溝通方式,也是 docker bridge 使用的方式。
今天的步驟如下:
今天的結構比昨天又更複雜了一點點,所以我們先來看最後想完成的樣子:
那現在就讓我們開始:
ubuntu@ip-xxx:~$ ip link list
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 0e:24:0e:79:cc:2d brd ff:ff:ff:ff:ff:ff
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default
link/ether 02:42:ea:22:dd:97 brd ff:ff:ff:ff:ff:ff
ubuntu@ip-xxx:~$ sudo ip netns add ns1
ubuntu@ip-xxx:~$ sudo ip netns add ns2
# 確認一下目前的 netns 的情況:
ubuntu@ip-xxx:~$ sudo ip netns list
ns2
ns1
# 在 /var/run/netns 也可以看到
ubuntu@ip-xxx:~$ sudo ls -l /var/run/netns/
docker1
好了,建立完成後啟動這個 bridge:ubuntu@ip-xxx:~$ sudo ip link add docker1 type bridge
# 建立後先觀察一下,可以看到多了一個 278 docker1,但 state 是 DOWN
ubuntu@ip-xxx:~$ ip link list
1: lo: ...略
2: ens5: ...略
4: docker0: ...略
278: docker1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 9e:74:76:1e:f7:1e brd ff:ff:ff:ff:ff:ff
# 啟動一下這個 bridge,啟動後可以看到 state 變成 UNKNOWN 了
ubuntu@ip-xxx:~$ sudo ip link set docker1 up
ubuntu@ip-xxx:~$ ip link list
1: lo: ...略
2: ens5: ...略
4: docker0: ...略
278: docker1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/ether 9e:74:76:1e:f7:1e brd ff:ff:ff:ff:ff:ff
# 也可以透過 brctl 這個指令來管理 bridge
ubuntu@ip-xxx:~$ brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242ea22dd97 no
docker1 8000.000000000000 no
ubuntu@ip-xxx:~$ sudo ip link add veth0 type veth peer name veth0-br
ubuntu@ip-xxx:~$ sudo ip link add veth1 type veth peer name veth1-br
ubuntu@ip-xxx:~$ sudo ip link list
1: lo: ...略
2: ens5: ...略
4: docker0: ...略
278: docker1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/ether 9e:74:76:1e:f7:1e brd ff:ff:ff:ff:ff:ff
279: veth0-br@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 76:68:d0:f0:ee:19 brd ff:ff:ff:ff:ff:ff
280: veth0@veth0-br: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 36:ba:6c:ca:c4:91 brd ff:ff:ff:ff:ff:ff
281: veth1-br@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 52:ae:58:eb:bd:5e brd ff:ff:ff:ff:ff:ff
282: veth1@veth1-br: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether e2:32:6c:77:41:2a brd ff:ff:ff:ff:ff:ff
建立完成後觀察一下,可以看到目前有兩對 veth:
279: veth0-br@veth0 <----> 280: veth0@veth0-br
281: veth1-br@veth1 <----> 282: veth1@veth1-br
ubuntu@ip-xxx:~$ sudo ip link set veth0 netns ns1
ubuntu@ip-xxx:~$ sudo ip link set veth0-br master docker1
ubuntu@ip-xxx:~$ sudo ip link set veth0-br up
ubuntu@ip-xxx:~$ sudo ip link set veth1 netns ns2
ubuntu@ip-xxx:~$ sudo ip link set veth1-br master docker1
ubuntu@ip-xxx:~$ sudo ip link set veth1-br up
ubuntu@ip-xxx:~$ sudo ip link list
1: lo: ...略
2: ens5: ...略
4: docker0: ...略
278: docker1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default qlen 1000
link/ether 52:ae:58:eb:bd:5e brd ff:ff:ff:ff:ff:ff
279: veth0-br@if280: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue master docker1 state LOWERLAYERDOWN mode DEFAULT group default qlen 1000
link/ether 76:68:d0:f0:ee:19 brd ff:ff:ff:ff:ff:ff link-netns ns1
281: veth1-br@if282: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue master docker1 state LOWERLAYERDOWN mode DEFAULT group default qlen 1000
link/ether 52:ae:58:eb:bd:5e brd ff:ff:ff:ff:ff:ff link-netns ns2
可以看到 280: veth0@veth0-br
跟 282: veth1@veth1-br1
因為分別被放進 ns1 跟 ns2 中,所以在目前的 net namespace 中看不到了。此外,也可以觀察到 279: veth0-br@veth0
這邊多了一個 master docker1,281: veth1-br@veth1
亦然。
ubuntu@ip-xxx:~$ sudo ip netns exec ns1 ip addr add 172.18.0.2/24 dev veth0
ubuntu@ip-xxx:~$ sudo ip netns exec ns1 ip link set veth0 up
ubuntu@ip-xxx:~$ sudo ip netns exec ns1 ip addr
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
280: veth0@if279: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 36:ba:6c:ca:c4:91 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.18.0.2/24 scope global veth0
valid_lft forever preferred_lft forever
inet6 fe80::34ba:6cff:feca:c491/64 scope link
valid_lft forever preferred_lft forever
ubuntu@ip-xxx:~$ sudo ip netns exec ns2 ip addr add 172.18.0.3/24 dev veth1
ubuntu@ip-xxx:~$ sudo ip netns exec ns2 ip link set veth1 up
ubuntu@ip-xxx:~$ sudo ip netns exec ns2 ip addr
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
282: veth1@if281: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether e2:32:6c:77:41:2a brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.18.0.3/24 scope global veth1
valid_lft forever preferred_lft forever
inet6 fe80::e032:6cff:fe77:412a/64 scope link
valid_lft forever preferred_lft forever
直的放,讓大家比對一下:
ubuntu@ip-xxx:~$ sudo ip netns exec ns1 ping 172.18.0.3
PING 172.18.0.3 (172.18.0.3) 56(84) bytes of data.
然後你會發現 ping 不通!!!這是為什麼呢?
雖然我們最後沒有成功地完成連線,但到這邊應該更有感覺 docker bridge 的做法了,甚至我們用 brctl show
這個指令查看 host 中目前有哪些 bridge 時,是可以看到 docker0
跟我們自己的 docker1
並列在一起的。至於為什麼這樣無法連通,以及兩個 net namespace 之間可以互相溝通,可不代表能跟外界溝通,剩下的這些要怎麼做到呢?就讓我們明天繼續看下去~