2020 還沒來得及品味就即將過去一個季度,願剩下的時光不被辜負。進入正題,docker container是單進程模式,可以解決一些單一的問題,在現實中,咱們經常須要多個進程放在一個「盒子」裏、或者多個節點共同完成通訊過程,接下來,說下這個過程的網絡通訊是如何實現的?
css
[root@localhost ~]# docker network lsNETWORK ID NAME DRIVER SCOPEc250329fad3c bridge bridge localc7c3d1f77969 compose_extnetwork bridge local199b85fbf2fa host host localb488be9da3d6 none null local
共享主機網絡模式 - hostjava
host指的是共享主機的網絡和端口,可是破壞了 container 的隔離性;node
無網絡模式 - nonenginx
其中無網絡模式是指加入此模式下的容器都不能通訊,比較雞肋;web
自定義docker
自定義主要用於實現DNS解析和服務發現,特殊場景下定製使用;bash
默認網絡模式 - bridge微信
網橋是 docker 默認網絡模式,也是平時用的最多的一種,這裏主要對 docker 的 bridge 模式作詳細講解。網絡
-
docker啓動後創建名爲docker0的虛擬網橋。 -
容器啓動時在主機上建立一對虛擬網卡veth pair設備。這一對虛擬設備完成一組數據完整流通的鏈路,數據從一個設備進入,從另外一個設備出來。容器中重命名爲eth0,宿主機上的以veth*顯示並插在docker0網橋上。能夠經過以下命令查看,docker0上插了 veth42f3f11 和 vethe8589bd 兩張虛擬設備,見(a)圖。
[root@localhost ~]# brctl showbridge name bridge id STP enabled interfacesbr-c7c3d1f77969 8000.02429160f0dd no docker0 8000.02420a13dd3a no veth42f3f11 vethe8589bd

(a)
(b)
架構
bash-4.4# routeKernel IP routing tableDestination Gateway Genmask Flags Metric Ref Use Ifacedefault 172.17.0.1 0.0.0.0 UG 0 0 0 eth0172.17.0.0 * 255.255.0.0 U 0 0 0 eth0bash-4.4#
若是訪問外部網絡,也很是簡單,數據包先通過docker0網卡,根據宿主機路由規則鏈接到eth0網卡,轉發到外部網絡。見(c)圖所示。
(c)
docker 在默認網絡設置狀況下,節點A 的docker0 跟節點B 的docker0 沒有任何關聯,網絡也是不通的,這就致使不能知足咱們跨節點通訊要求。Kubernetes 的 Pod 又是經過何種方式實現的呢?
三、pod 通訊機制
若是要說明 pod 的通訊機制,要從一個鏡像提及,在 kubectl 安裝kubernetes 的時候必定會看到 k8s.gcr.io/pause 這個鏡像,不知道有沒有疑問,這個究竟是幹嗎的?其它幾個鏡像顧名思義,可是這個【暫停】是什麼?沒錯,他就是用來 hold 一個 Pod 內部多個 Container 網絡通訊。
[root@k8s-client1 ~]# docker ps |grep sp-nginxe34adacf9be1 0a81924719d1 "/usr/local/nginx/b…" 3 seconds ago Up 2 seconds k8s_sp_nginx-deployment-84b5d9cb66-hkfp6_default_5c27af26-6b7e-11ea-8d03-70fd45ac3f1f_0f245174b9a51 0a81924719d1 "/usr/local/nginx/b…" 5 seconds ago Up 4 seconds k8s_sp_nginx-deployment-84b5d9cb66-zfbhr_default_5c281ef0-6b7e-11ea-8d03-70fd45ac3f1f_0
如上所示,你能夠看到在建立 nginx pod 過程當中,不只建立了一個nginx 容器,並附帶了一個 pause 容器,並且 pause 容器是在 nginx容器以前建立的,這個被暫停的容器把全部的容器收納到一塊兒,一個基礎容器,惟一目的就是保存全部的命名空間。容器中 pod 共享同一個 IP 地址。故同一個 Pod 中 Container 能夠作到直接經過 localhost 直接通訊,那麼同一個節點多個 Pod 之間如何通訊的呢?
(d)
pause 容器啓動以前,會爲容器建立虛擬一對 ethernet 接口,一個保留在宿主機 vethxxx(插在網橋上),一個保留在容器網絡命名空間內,並重命名爲eth0。兩個虛擬接口的兩端,從一端進入,另外一端出來。任何 Pod 鏈接到該網橋的 Pod 均可以收發數據。如(d)圖所示。
四、跨 node pod 通訊
跨節點 Pod 通訊,至關於建立一個整個集羣公用的【 網橋 】而後把集羣中全部的 Pod 鏈接起來,就能夠通訊了。
(e)
(f)
五、總結
本文由淺到深的講解了 docker 網絡模式實現以及 Kubernetes Pod 跨節點之間通訊原理和實現方式。簡單介紹了dockers、Kubernetes網絡通訊方式,其內部經過網卡、迴環設備、路由表、iptables等實現,若是你是個喜歡深究的人,能夠研究下組網過程。
推薦
原創不易,隨手關注或者」在看「,誠摯感謝!
本文分享自微信公衆號 - 雲原生技術愛好者社區(programmer_java)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。