Kubernetes 網路型別

安全劍客發表於2020-12-22
在 Kubernetes 的世界裡,IP 是以 Pod 為單位進行分配的。一個 Pod內部的所有容器共享一個網路堆疊(實際上就是一個網路名稱空間,包括它們的 IP地址、網路裝置、配置等都是共享的)。
Pod內容器之間的通訊:localhost

在同一個pod內由pause映象啟動的容器。所有執行於同一個Pod內的容器與同一主機上的多個程式類似,彼此之間可透過lo介面完成互動。

Kubernetes 網路型別Kubernetes 網路型別

同一node上的Pod之間的通訊:overlay network

同一個Node內的不同Pod之間可以直接採用對方Pod的IP地址通訊,而且不需要使用其他發現機制,例如DNS、Consul或者etcd。

Pod1和Pod2都是通訊veth:pair連線到同一個docker0網橋上,它們的IP地址IP1、IP2都是從docker0網段上動態獲取的,它們和網橋本身的IP3是同一個網段的。由於Pod1和Pod2處於同一區域網內,它們之間可以透過docker0作為路由量進行通訊。

Kubernetes 網路型別Kubernetes 網路型別

不同node上的Pod之間的通訊:iptables規則

在Kubernetes的網路世界中,Pod之間假設是透過訪問對方的Pod IP進行通訊的,而不同Node之間的通訊只能透過Node的物理網路卡進行,Pod的IP地址是由各Node上的docker0網橋動態分配的。我們想要實現跨Node的Pod之間的通訊,至少需要滿足下面三個條件:

知道Pod IP 和Node IP之間的對映關係,透過Node IP轉發到Pod IP;

在整個Kubernetes叢集中對Pod的IP分配不能出現衝突;

從Pod中發出的資料包不應該進行NAT地址轉換。

Kubernetes會記錄所有正在執行的Pod的IP分配資訊,並將這些資訊儲存到etcd中(作為Service的Endpoint),這樣我們就可以知道PodIP和Node IP之間的對映關係。

以Flannel為例,Flannel實現的容器的跨主機通訊透過如下過程實現:

每個主機上安裝並執行etcd和flannel;

在etcd中規劃配置所有主機的docker0子網範圍;

每個主機上的flanneld根據etcd中的配置,為本主機的docker0分配子網,保證所有主機上的docker0網段不重複,並將結果(即本主機上的docker0子網資訊和本主機IP的對應關係)存入etcd庫中,這樣etcd庫中就儲存了所有主機上的docker子網資訊和本主機IP的對應關係;

當需要與其他主機上的容器進行通訊時,查詢etcd資料庫,找到目的容器的子網所對應的outip(目的宿主機的IP);

將原始資料包封裝在VXLAN或UDP資料包中,IP層以outip為目的IP進行封裝;

由於目的IP是宿主機IP,因此路由是可達的;

VXLAN或UDP資料包到達目的宿主機解封裝,解出原始資料包,最終到達目的容器。

Kubernetes 網路型別Kubernetes 網路型別

Service與Pod間的通訊:iptables規則

叢集網路需要在啟動kube-apiserver時經由“—service-cluster-ip-range”選項進行指定,如10.96.0.0/12,而每個Service物件在此網路中均擁一個稱為Cluster-IP的固定地址。

管理員或使用者對Service物件的建立或更改操作由API Server儲存完成後觸發各節點上的kube-proxy,並根據代理模式的不同將其定義為相應節點上的iptables規則或ipvs規則,藉此完成從Service的Cluster-IP與Pod-IP之間的報文轉發

Kubernetes 網路型別Kubernetes 網路型別

叢集外部到Pod物件之間的通訊

將叢集外部的流量引入到Pod物件的方式有受限於Pod所在的工作節點範圍的節點埠(nodePort)和主機網路(hostNetwork)兩種,以及工作於叢集級別的NodePort或LoadBalancer型別的Service物件。

即便是四層代理的模式也要經由兩級轉發才能到達目標Pod資源:請求流量首先到達外部負載均衡器,由其排程至某個工作節點之上,而後再由工作節點的netfilter(kube-proxy)元件上的規則(iptables或ipvs)排程至某個目標Pod物件。

原文地址:

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31559985/viewspace-2744233/,如需轉載,請註明出處,否則將追究法律責任。

相關文章