K8S 容器之間通訊方式

概述

首先k8s里面容器是存在于pod里面的,所以容器之間通訊,一般分為三種類型:

1. pod內(nèi)部容器之間

2. pod 與 pod 容器之間

3. pod 訪問service服務(wù)


pod內(nèi)部容器之間

這種情況下容器通訊比較簡單,因為k8s pod內(nèi)部容器是共享網(wǎng)絡(luò)空間的,所以容器直接可以使用localhost訪問其他容器。

k8s在啟動容器的時候會先啟動一個pause容器,這個容器就是實現(xiàn)這個功能的。

pod 與 pod 容器之間

這種類型又可以分為兩種情況:

1. 兩個pod在一臺主機上面

2. 兩個pod分布在不同主機之上

針對第一種情況,就比較簡單了,就是docker默認(rèn)的docker網(wǎng)橋互連容器。

第二種情況需要更為復(fù)雜的網(wǎng)絡(luò)模型了,k8s官方推薦的是使用flannel組建一個大二層扁平網(wǎng)絡(luò),pod的ip分配由flannel統(tǒng)一分配,通訊過程也是走flannel的網(wǎng)橋。

docker --daemon --bip=172.17.18.1/24?

注意其中的“--bip=172.17.18.1/24”這個參數(shù),它限制了所在節(jié)點容器獲得的IP范圍。

每個node上面都會創(chuàng)建一個flannel0虛擬網(wǎng)卡,用于跨node之間通訊。所以容器直接可以直接使用pod id進行通訊。

跨節(jié)點通訊時,發(fā)送端數(shù)據(jù)會從docker0路由到flannel0虛擬網(wǎng)卡,接收端數(shù)據(jù)會從flannel0路由到docker0,這是因為flannel會添加一個路由

發(fā)送端:

route -n

172.17.0.0 ? ?0.0.0.0 ? ?255.255.0.0 ? ? ?U ?0 ?0 ?0 ? flannel0

172.17.13.0 ?0.0.0.0? ? 255.255.255.0? U? 0? 0? 0 ? docker0

接收端:

172.18.0.0? ? 0.0.0.0? ? 255.255.0.0? ? ? U? 0? 0? 0? flannel0

172.17.12.0 ?0.0.0.0? ? 255.255.255.0? U? 0? 0? 0 ? docker0

例如現(xiàn)在有一個數(shù)據(jù)包要從IP為172.17.13.2的容器發(fā)到IP為172.17.12.2的容器。根據(jù)數(shù)據(jù)發(fā)送節(jié)點的路由表,它只與172.17.0.0/16匹配這條記錄匹配,因此數(shù)據(jù)從docker0出來以后就被投遞到了flannel0。同理在目標(biāo)節(jié)點,由于投遞的地址是一個容器,因此目的地址一定會落在docker0對于的172.17.12.0/24這個記錄上,自然的被投遞到了docker0網(wǎng)卡。

flannel的原理是將網(wǎng)絡(luò)包封裝在udp里面,所以發(fā)送端和接收端需要裝包和解包,對性能有一定的影響。

k8s也支持其他的網(wǎng)絡(luò)模型,比較有名的還有calico,不過我并沒有使用過。


pod 訪問service服務(wù)

這里涉及到k8s里面一個重要的概念service。它是一個服務(wù)的抽象,通過label(k8s會根據(jù)service和pod直接的關(guān)系創(chuàng)建endpoint,可以通過kubectl get ep查看)關(guān)聯(lián)到后端的pod容器。

Service分配的ip叫cluster ip是一個虛擬ip(相對固定,除非刪除service),這個ip只能在k8s集群內(nèi)部使用,如果service需要對外提供,只能使用Nodeport方式映射到主機上,使用主機的ip和端口對外提供服務(wù)。(另外還可以使用LoadBalance方式,但這種方式是在gce這樣的云環(huán)境里面使用的 )。

節(jié)點上面有個kube-proxy進程,這個進程從master apiserver獲取信息,感知service和endpoint的創(chuàng)建,然后做兩個事:

1. 為每個service 在集群中每個節(jié)點上面創(chuàng)建一個隨機端口,任何該端口上面的連接會代理到相應(yīng)的pod

2. 集群中每個節(jié)點安裝iptables規(guī)則,用于clusterip + port路由到上一步定義的隨機端口上面,所以集群中每個node上面都有service的轉(zhuǎn)發(fā)規(guī)則:

KUBE-PORTALS-CONTAINER 從容器中通過service cluster ip和端口訪問service的請求

KUBE-PORTALS-HOST 從主機中通過service cluster ip和端口訪問service的請求

KUBE-NODEPORT-CONTAINER 從容器中通過service nodeport端口訪問service的請求

KUBE-NODEPORT-HOST 從主機中通過service nodeport端口訪問service的請求。

見下面測試環(huán)境的內(nèi)容:

-A KUBE-NODEPORT-CONTAINER -p tcp -m comment --comment "smart/ccdb:port1521" ?-m tcp --dport 50171 -j REDIRECT --to-ports 52244

-A KUBE-NODEPORT-HOST -p tcp -m comment --comment "smart/ccdb:port1521" -m tcp --dport 50171 -j DNAT --to-destination 10.45.25.227:52244

-A KUBE-PORTALS-CONTAINER -d 10.254.120.169/32 -p tcp -m comment --comment "smart/ccdb:port1521" -m tcp --dport 1521 -j REDIRECT --to-ports 52244

-A KUBE-PORTALS-HOST -d 10.254.120.169/32 -p tcp -m comment --comment "smart/ccdb:port1521" -m tcp --dport 1521 -j DNAT --to-destination 10.45.25.227:52244

52244就是kube-proxy針對service “"smart/ccdb:port1521"” 在節(jié)點上面監(jiān)聽的端口。


參考:

1.?http://www.open-open.com/news/view/1aa473a

2. 《kubernetes權(quán)威指南》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容