
Kubernetes網(wǎng)絡(luò)
提供多種選項幫助實現(xiàn)網(wǎng)絡(luò)連接,k8s本身不關(guān)心如何實現(xiàn)它,但需滿足三個基本要求:
無需NAT(network address translation),所有容器可相互訪問,無論在哪個節(jié)點上
所有節(jié)點可與所有容器通信
容器看自己的IP應(yīng)與其他容器看到的一致
Docker網(wǎng)絡(luò)
三種容器網(wǎng)絡(luò)模型:bridge、none、host
Docker創(chuàng)建并附加虛擬以太網(wǎng)設(shè)備(也稱veth),并為每個容器分配網(wǎng)絡(luò)命名空間
網(wǎng)絡(luò)命名空間Network namespace是linux中的一項功能,邏輯上是網(wǎng)絡(luò)棧的副本,擁有自己的路由表、arp(address resolution protocal 地址解析協(xié)議)表、網(wǎng)絡(luò)設(shè)備
veth成對出現(xiàn),一個在網(wǎng)絡(luò)命名空間中,一個在網(wǎng)橋上,當流量進入主機網(wǎng)絡(luò),它被路由到網(wǎng)橋,數(shù)據(jù)包被發(fā)送到對應(yīng)veth,并進入容器內(nèi)的命名空間

容器間通信
k8s中的pod都有自己真實的IP地址,pod中的容器共享網(wǎng)絡(luò)命名空間,視彼此為localhost
默認情況,由network container實現(xiàn),該容器充當pod中每個容器流量轉(zhuǎn)發(fā)的橋梁
Pod間通信
無論Pod在哪個節(jié)點上,其他Pod都應(yīng)該可以通過PodIP進行訪問
同一節(jié)點內(nèi)Pod間通信
默認情況,同一節(jié)點內(nèi)Pod間通信會經(jīng)過網(wǎng)橋
示例:有兩個Pod,都有自己的網(wǎng)絡(luò)命名空間,數(shù)據(jù)包通過Pod1命名空間傳遞到相應(yīng)的veth pair vethXXXX,然后進入網(wǎng)橋,網(wǎng)橋廣播目標IP地址以幫助數(shù)據(jù)包找到路徑,vethYYYY進行響應(yīng),數(shù)據(jù)包到達Pod2

跨節(jié)點Pod間通信
k8s通過容器網(wǎng)絡(luò)接口(container network interface,CNI)實現(xiàn)通信
實現(xiàn)方式如L2、L3、Overlay
Overlay數(shù)據(jù)包封裝,在數(shù)據(jù)包離開數(shù)據(jù)源之前封裝,在目的端解封,導(dǎo)致overlay會增加網(wǎng)絡(luò)延遲和復(fù)雜性

Pod與服務(wù)間通信
k8s始終是動態(tài)變化的,Pod一直在創(chuàng)建和刪除
k8s通過標簽選擇器選擇一組Pod,通常通過服務(wù)來訪問而不是直接訪問某個Pod
Endpoint對象也會隨著服務(wù)的創(chuàng)建而產(chǎn)生,記錄了服務(wù)后端的PodIP
k8s使用kube-proxy通過iptables來完成流量從一個Pod到服務(wù)后端的Pod

外部與服務(wù)通信
k8s支持外部流程訪問,兩個API對象實現(xiàn)該目標:
Service:外部網(wǎng)絡(luò)負載均衡或者NodePort(L4)
Ingress:HTTP(s)負載均衡(L7)
示例:
兩個服務(wù),服務(wù)A有3個Pod,a、b、c,服務(wù)B有一個Pod d
流程從LoadBalancer進入,數(shù)據(jù)包被發(fā)送到其中一個節(jié)點(多數(shù)LoadBalancer不知道Pod或容器存在,只知道有后端節(jié)點),如果節(jié)點通過健康檢查就可以加入到負載均衡后端
若要訪問服務(wù)B,LoadBalancer就會將數(shù)據(jù)包發(fā)送到另一個節(jié)點上
數(shù)據(jù)流示例:
1 LoadBalancer選擇一個節(jié)點轉(zhuǎn)發(fā)數(shù)據(jù)包,GCE中,通過源IP和端口、目的IP和端口,以及協(xié)議的散列選擇實例,AWS中,基于round-robin輪詢算法
2 路由目標被更改為Pod d(DNAT),將數(shù)據(jù)包轉(zhuǎn)發(fā)到另一個節(jié)點,類似于跨節(jié)點的Pod間通信
3 通過Service到Pod的通信,數(shù)據(jù)包到達Pod d并得到響應(yīng)
4 Pod到Service通信也由iptables管理
5 數(shù)據(jù)包將被轉(zhuǎn)發(fā)到原始節(jié)點
6 源和目的將un-DNAT回負載均衡(Loadbalancer)和客戶端,數(shù)據(jù)包原路返回
k8s 1.7中,Service中有外部流量策略(externalTraffic-Policy)的新屬性,設(shè)置為local,流量進入節(jié)點后,k8s在改節(jié)點上路由

Ingress
Pod和Service都有自己的IP,但通常不是提供給外部互聯(lián)網(wǎng)的接口
雖然配置了含節(jié)點IP的服務(wù),但是節(jié)點IP中的端口不能在服務(wù)間重復(fù),確定用哪種服務(wù)管理哪個端口很麻煩,節(jié)點啟啟停停,不適合為外部服務(wù)提供靜態(tài)節(jié)點IP
Ingress定義了一組允許入站連接訪問k8s集群服務(wù)的規(guī)則,在七層將流量引入機器,每個節(jié)點都分配服務(wù)端口進行流量轉(zhuǎn)發(fā),允許使用URL路徑路由到不同服務(wù)
如下圖,定義規(guī)則發(fā)布到API服務(wù)器,流量進入時,Ingress控制器匹配Ingress規(guī)則并進行路由,Ingress通過不同的URL將外部流量路由到不同k8s端點

網(wǎng)絡(luò)策略
NetworkPolicy,Pod的軟件防火墻,默認下,Pod可以互相通信
網(wǎng)絡(luò)策略應(yīng)用于Pod的隔離,通過命名空間選擇器和Pod選擇器,定義誰可以訪問哪個端口,這些策略在命名空間中是疊加的
默認拒絕所有,標簽不匹配的Pod都將被拒絕