前面介紹了:Docker容器網絡-基礎篇html
前文說到容器網絡對Linux虛擬化技術的依賴,這一篇章咱們將一探究竟,看看Docker到底是怎麼作的。一般,Linux容器的網絡是被隔離在它本身的Network Namespace中,其中就包括:網卡(Network Interface)、迴環設備(Loopback Device)、路由表(Routing Table)和iptables規則。對於一個進程來講,這些要素,就構成了它發起和響應網絡請求的基本環境。docker
咱們在執行docker run -d --name xxx
以後,進入容器內部:bash
## docker ps 可查看全部docker ## 進入容器 docker exec -it 228ae947b20e /bin/bash
並執行 ifconfig:網絡
$ ifconfig eth0 Link encap:Ethernet HWaddr 22:A4:C8:79:DD:1A inet addr:192.168.65.28 Bcast:
咱們看到一張叫eth0的網卡,它正是一個Veth Pair設備在容器的這一端。app
咱們再經過 route 查看該容器的路由表:oop
$ route Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use If
咱們能夠看到這個eth0是這個容器的默認路由設備。咱們也能夠經過第二條路由規則,看到全部對 169.254.1.1/16 網段的請求都會交由eth0來處理。學習
而Veth Pair 設備的另外一端,則在宿主機上,咱們一樣也能夠經過查看宿主機的網絡設備來查看它:spa
$ ifconfig ...... eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.16.241.192 netmask 255.255.240.0 broadcast 172.16.255.255 ether 00:16:3e:0a:f3:75 txqueuelen 1000 (Ethernet) RX packets 3168620550 bytes 727592674740 (677.6 GiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 2937180637 bytes 8661914052727 (7.8 TiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ...... docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02:42:16:58:92:43 txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ...... vethd08be47: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 ether 16:37:8d:fe:36:eb txqueuelen 0 (Ethernet) RX packets 193 bytes 22658 (22.1 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 134 bytes 23655 (23.1 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ......
在宿主機上,容器對應的Veth Pair設備是一張虛擬網卡,咱們再用brctl show
命令查看網橋:設計
$ brctl show bridge name bridge id STP enabled interfaces docker0 8000.0242afb1a841 no vethd08be47
能夠清楚的看到Veth Pair的一端 vethd08be47 就插在 docker0 上。3d
我如今執行docker run 啓動兩個容器,就會發現docker0上插入兩個容器的 Veth Pair的一端。若是咱們在一個容器內部互相ping另一個容器的IP地址,是否是也能ping通?
$ brctl show bridge name bridge id STP enabled interfaces docker0 8000.0242afb1a841 no veth26cf2cc veth8762ad2
容器1:
$ docker exec -it f8014a4d34d0 /bin/bash $ ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:0
容器2:
$ docker exec -it 9a6f38076c04 /bin/bash $ ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:0
從一個容器ping另一個容器:
# -> 容器1內部 ping 容器2 $ ping 172.17.0.3 PING 172.17.0.3 (172.17.0.3): 56 data bytes 64 bytes from 172.17
咱們看到,在一個容器內部ping另一個容器的ip,是能夠ping通的。也就意味着,這兩個容器是能夠互相通訊的。
咱們不妨結合前文時所說的,理解下爲何一個容器能訪問另外一個容器?先簡單看如一幅圖:
當在容器1裏訪問容器2的地址,這個時候目的IP地址會匹配到容器1的第二條路由規則,這條路由規則的Gateway是0.0.0.0,意味着這是一條直連規則,也就是說凡是匹配到這個路由規則的請求,會直接經過eth0網卡,經過二層網絡發往目的主機。而要經過二層網絡到達容器2,就須要127.17.0.3對應的MAC地址。因此,容器1的網絡協議棧就須要經過eth0網卡來發送一個ARP廣播,經過IP找到MAC地址。
所謂ARP(Address Resolution Protocol),就是經過三層IP地址找到二層的MAC地址的協議。這裏說到的eth0,就是Veth Pair的一端,另外一端則插在了宿主機的docker0網橋上。eth0這樣的虛擬網卡插在docker0上,也就意味着eth0變成docker0網橋的「從設備」。從設備會降級成docker0設備的端口,而調用網絡協議棧處理數據包的資格所有交給docker0網橋。
因此,在收到ARP請求以後,docker0就會扮演二層交換機的角色,把ARP廣播發給其它插在docker0網橋的虛擬網卡上,這樣,127.17.0.3就會收到這個廣播,並把其MAC地址返回給容器1。有了這個MAC地址,容器1的eth0的網卡就能夠把數據包發送出去。這個數據包會通過Veth Pair在宿主機的另外一端veth26cf2cc,直接交給docker0。
docker0轉發的過程,就是繼續扮演二層交換機,docker0根據數據包的目標MAC地址,在CAM表查到對應的端口爲veth8762ad2,而後把數據包發往這個端口。而這個端口,就是容器2的Veth Pair在宿主機的另外一端,這樣,數據包就進入了容器2的Network Namespace,最終容器2將響應(Ping)返回給容器1。在真實的數據傳遞中,Linux內核Netfilter/Iptables也會參與其中,這裏再也不贅述。
CAM就是交換機經過MAC地址學習維護端口和MAC地址的對應表
這裏介紹的容器間的通訊方式就是docker中最多見的bridge模式,固然此外還有host模式、container模式、none模式等,對其它模式有興趣的能夠去閱讀相關資料。
好了,這裏不由問個問題,到目前爲止只是單主機內部的容器間通訊,那跨主機網絡呢?在Docker默認配置下,一臺宿主機的docker0網橋是沒法和其它宿主機連通的,它們之間沒有任何關聯,因此這些網橋上的容器,天然就沒辦法多主機之間互相通訊。可是不管怎麼變化,道理都是同樣的,若是咱們建立一個公共的網橋,是否是集羣中全部容器均可以經過這個公共網橋去鏈接?
固然在正常的狀況下,節點與節點的通訊每每能夠經過NAT的方式,可是,這個在互聯網發展的今天,在容器化環境下未必適用。例如在向註冊中心註冊實例的時候,確定會攜帶IP,在正常物理機內的應用固然沒有問題,可是容器化環境卻未必,容器內的IP極可能就是上文所說的172.17.0.2,多個節點都會存在這個IP,大機率這個IP是衝突的。
若是咱們想避免這個問題,就會攜帶宿主機的IP和映射的端口去註冊。可是這又帶來一個問題,即容器內的應用去意識到這是一個容器,而非物理機,當在容器內,應用須要去拿容器所在的物理機的IP,當在容器外,應用須要去拿當前物理機的IP。顯然,這並非一個很好的設計,這須要應用去配合配置。因此,基於此,咱們確定要尋找其餘的容器網絡解決方案。
在上圖這種容器網絡中,咱們須要在咱們已有的主機網絡上,經過軟件構建一個覆蓋在多個主機之上,且能把全部容器連通的虛擬網絡。這種就是Overlay Network(覆蓋網絡)。
關於這些具體的網絡解決方案,例如Flannel、Calico等,我會在後續篇幅繼續陳述。
_連接: https://www.cnblogs.com/sally...
做者Mr_Zack_