復習docker三種網絡
docker在安裝后會默認生成三種網絡,none、bridge及host。
[root@k8s-master ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
089c60c71261 bridge bridge local
cc6b4177daf6 host host local
4d8e46882a41 none null local
none網絡
顧名思義,就是掛載這個網絡下的容器僅有lo網絡,沒有其他網卡,也就不能與外界通信,適合對安全性要求較高且不需要聯網的容器。
[root@k8s-master ~]# docker run -it --network=none busybox
/ # ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
host網絡
連接到host網絡的容器會共享宿主機的網絡棧,容器內的網絡配置與宿主機一致
[root@k8s-master ~]# docker run -it --network=host busybox
/ # ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq qlen 1000
link/ether 00:0c:29:cf:da:70 brd ff:ff:ff:ff:ff:ff
...
直接使用host網絡好處就是性能,如果容器對網絡有較高要求可以直接使用host網絡。但是:使用host網絡也會犧牲靈活性,host已經使用的端口容器中將無法使用。
bridge網絡
默認網絡,運行容器時如果不指定網絡類型就會使用bridge網絡
當前docker0網卡上沒有任何網絡設備
[root@k8s-master ~]# bridge link show dev docker0 | grep docker0
[root@k8s-master ~]#
在運行一個busybox容器后再次查看會發現一個新的網絡接口vetha8b45fa@if30掛載到了docker0,這個就是busybox的虛擬網卡
[root@k8s-master ~]# docker run -itd --name busybox busybox
99dfbb8efef7be8f7c5e85d7d8f7860c26c269e003c8ba36a93d0c5d2f1f0a89
[root@k8s-master ~]# bridge link show | grep docker0
31: vetha8b45fa@if30: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master docker0 state forwarding priority 32 cost 2
但是查看busybox的網絡配置卻沒有找到這個vetha8b45fa@if30設備
[root@k8s-master ~]# docker exec -it busybox ip l
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
30: eth0@if31: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
這里的eth0與vetha8b45fa@if30就是一對veth pair設備。可以把veth設備看做是一對網卡,一塊網卡(eth0)在容器內,另一塊(vetha8b45fa@if30)掛載在docker0上。目的就是把容器的eth0掛到docker0上。
查看容器的網關,這個網關就是docker0的ip地址
[root@k8s-master ~]# docker exec -it busybox ip route
default via 172.17.0.1 dev eth0
[root@k8s-master ~]# docker network inspect bridge | jq '.[0].IPAM.Config[0].Gateway'
"172.17.0.1"
Veth詳解
如上面的介紹,Veth設備的作用主要用來連接兩個網絡命名空間,如同一對網卡中間連着一條網線。既然是一對網卡,那么其中一塊網卡稱作另一塊的peer。在Veth設備的一端發送數據會直接發送到另一端。
Veth設備的操作
創建Veth設備對veth0-veth1
[root@k8s-master ~]# ip link add veth0 type veth peer name veth1
創建完成后使用ip link show
查看新建出來的veth設備信息
[root@k8s-master ~]# ip link show
...
32: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 86:d5:ad:c4:43:27 brd ff:ff:ff:ff:ff:ff
33: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether da:a4:fc:43:09:d9 brd ff:ff:ff:ff:ff:ff
從命名來看就可以看出veth設備的特殊關系了,你中有我,我中有你。目前創建的veth pair都在同一網絡空間下,還不算是真正的veth設備。接下來就是創建新的網絡命名空間,並且把其中的一塊網卡甩到到另一網絡空間。
創建新的命名空間ns2
[root@k8s-master ~]# ip netns add ns2
[root@k8s-master ~]# ip netns list
ns2
將veth1置入ns2網絡空間中再查看本機中的網卡
[root@k8s-master ~]# ip link set veth1 netns ns2
[root@k8s-master ~]# ip link show
...
33: veth0@if32: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether da:a4:fc:43:09:d9 brd ff:ff:ff:ff:ff:ff link-netns ns2
進入ns2名稱空間查看網卡
[root@k8s-master ~]# ip netns exec ns2 ip link show
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
32: veth1@if33: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 86:d5:ad:c4:43:27 brd ff:ff:ff:ff:ff:ff link-netnsid 0
現在我們就使用veth pair連接本空間與ns2空間,但目前還不能直接通信,必須為兩塊網卡配置各自的ip地址並啟動
[root@k8s-master ~]# ip netns exec ns2 ip addr add 10.1.1.2/24 dev veth1
[root@k8s-master ~]# ip addr add 10.1.1.1/24 dev veth0
[root@k8s-master ~]# ip netns exec ns2 ip link set dev veth1 up
[root@k8s-master ~]# ip link set veth0 up
現在兩個網絡空間就能直接通信了
[root@k8s-master ~]# ping 10.1.1.2
PING 10.1.1.2 (10.1.1.2) 56(84) bytes of data.
64 bytes from 10.1.1.2: icmp_seq=1 ttl=64 time=0.146 ms
64 bytes from 10.1.1.2: icmp_seq=2 ttl=64 time=0.115 ms
^C
--- 10.1.1.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 54ms
rtt min/avg/max/mdev = 0.115/0.130/0.146/0.019 ms
[root@k8s-master ~]# ip netns exec ns2 ping 10.1.1.1
PING 10.1.1.1 (10.1.1.1) 56(84) bytes of data.
64 bytes from 10.1.1.1: icmp_seq=1 ttl=64 time=0.101 ms
64 bytes from 10.1.1.1: icmp_seq=2 ttl=64 time=0.131 ms
^C
--- 10.1.1.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 19ms
rtt min/avg/max/mdev = 0.101/0.116/0.131/0.015 ms
總結:docker就是這樣使用veth pair設備連接宿主機網絡與容器網絡。理解veth設備的工作原理對於理解bridge網絡起到至關重要的作用。