點擊上方藍字● 關注Linux公社
來自:https://cvvz.github.io/post/container-network/容器網絡環境隔離怎麼理解?容器的網絡環境是隔離的,這個隔離就體現在不共用內核網絡協議棧,即不共用網絡協議棧要用到的數據和設備了:
傳輸層:端口號
網絡層:路由表、iptables規則
數據鏈路層:網卡設備、arp緩存表
如果在容器中執行iptables、ifconfig、arp和route命令看到的肯定是不同的iptables規則、網絡設備、arp緩存表和路由表。
網橋和veth pair同一個宿主機的容器之間通信是通過二層網絡進行通信的。物理機如果想通過二層網絡通信,那麼必須要有兩樣東西,一個是網線,一個是交換機。
在Linux系統中,扮演虛擬交換機角色的,叫做網橋;扮演網線角色的,叫做veth pair。
以Docker為例,在bridge模式下:
Docker Daemon第一次啟動時會創建docker0網橋;
在創建容器時,會創建一個veth pair,即veth設備對。
veth pair有兩個端點:
一端在宿主機中,可以看成是宿主機的一塊虛擬網卡,但被關聯到docker0網橋上;
另一端,則藉助net namespace技術,變成了容器中的eth0網卡。
veth pair之所以可以被看成「網線」,是因為它的特殊之處在於,只要有一端收到了數據包,同樣的數據包也會在另一端出現。不受namespace的約束。
網橋:Linux的網橋提供了在同一個機器上各種網絡設備之間互相轉發數據的設備。普通的交換機對於接收到的報文,要麼轉發,要麼丟棄,網橋除了具備普通交換機的功能以外,它還可以調用內核協議棧,處理髮送給本機的報文。
同宿主機中的容器通信過程同一台宿主機中的兩個容器(容器A -> 容器B)建立通信的過程如下(容器B的ip地址為172.17.0.3):
容器A中的內核網絡協議棧對網絡層進行處理時,去查路由表:
1$ route2Kernel IP routing table3Destination Gateway Genmask Flags Metric Ref Use Iface4default 172.17.0.1 0.0.0.0 UG 0 0 0 eth05172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
發現路由表中容器B的網絡地址和第二條規則匹配。這條路由規則的網關(Gateway)是0.0.0.0,這就意味着這是一條直連規則,即:凡是匹配到這條規則的 IP 包,應該經過 eth0 網卡,通過二層網絡直接發往目的主機。
容器A於是查詢本地的arp緩存表,如果沒有找到目的MAC地址,則發一條arp廣播,通過容器的eth0網卡發送出去。
veth pair的另一端收到這個arp消息,把它轉發給docker0網橋。
這個另一端是宿主機的一塊虛擬網卡,本來是應該可以調用網絡協議棧來處理收到的數據包的,但是它被和docker0網橋綁定了,所以它的功能被降級為交換機的一個端口,只能無腦把數據包發給網橋去處理。
docker0網橋扮演二層交換機的角色,把arp請求廣播出去,收到容器B返回的MAC地址後,再通過原鏈路把MAC地址返回給容器A。
容器A使用目的MAC地址和源MAC地址封裝鏈路層頭部,將消息通過eth0網卡發送出去。
docker0網橋收到數據包,直接根據目的MAC地址將其轉發給容器B。
整個過程可以用下面這張圖概括:
Pod中的容器網絡創建一個Pod前,首先要創建infra容器,這個infra容器就通過veth設備連接到網橋,接着創建其他容器,其他容器加入infra容器的net namespace,這樣,就能做到和infra容器之間以localhost的方式通信,因為同一個namespace中的進程,共享內核數據和網絡設備。 長按或掃描下面的二維碼關注 Linux公社 關注 Linux公社,添加「 星標 」 每天 獲取 技術乾貨,讓我們一起成長 合作聯繫: root@linuxidc.net