天天看點

K8S從懵圈到熟練 – 叢集網絡詳解鳥瞰叢集網絡搭建總結

阿裡雲K8S叢集網絡目前有兩種方案,一種是flannel方案,另外一種是基于calico和彈性網卡eni的terway方案。Terway和flannel類似,不同的地方在于,terway支援Pod彈性網卡,以及NetworkPolicy功能。

今天這篇文章,我們以flannel為例,深入分析阿裡雲K8S叢集網絡的實作方法。我會從兩個角度去分析,一個是網絡的搭建過程,另外一個是基于網絡的通信。我們的讨論基于目前的1.12.6版本。

鳥瞰

總體上來說,阿裡雲K8S叢集網絡配置完成之後,如下圖,包括叢集CIDR,VPC路由表,節點網絡,節點的podCIDR,節點上的虛拟網橋cni0,連接配接Pod和網橋的veth等部分。

K8S從懵圈到熟練 – 叢集網絡詳解鳥瞰叢集網絡搭建總結

類似的圖,大家可能在很多文章中都看過,但是因為其中相關配置過于複雜,比較難了解。這裡我們可以把這些配置,分三種情況來了解:叢集配置,節點配置以及Pod配置。與這三種情況對應的,其實是對叢集網絡IP段的三次劃分:首先是叢集CIDR,接着為每個節點配置設定podCIDR(即叢集CIDR的子網段),最後在podCIDR裡為每個Pod配置設定自己的IP。

K8S從懵圈到熟練 – 叢集網絡詳解鳥瞰叢集網絡搭建總結

叢集網絡搭建

初始階段

叢集的建立,基于雲資源VPC和ECS,在建立完VPC和ECS之後,我們基本上可以得到如下圖的資源配置。我們得到一個VPC,這個VPC的網段是192.168.0.0/16,我們得到若幹ECS,他們從VPC網段裡配置設定到IP位址。

K8S從懵圈到熟練 – 叢集網絡詳解鳥瞰叢集網絡搭建總結

叢集階段

在以上出初始資源的基礎上,我們利用叢集建立控制台得到叢集CIDR。這個值會以參數的形式傳給叢集節點provision腳本,并被腳本傳給叢集節點配置工具kubeadm。kubeadm最後把這個參數寫入叢集控制器靜态Pod的yaml檔案kube-controller-manager.yaml。

K8S從懵圈到熟練 – 叢集網絡詳解鳥瞰叢集網絡搭建總結

叢集控制器有了這個參數,在節點kubelet注冊節點到叢集的時候,叢集控制器會為每個注冊節點,劃分一個子網出來,即為每個節點配置設定podCIDR。如上圖,Node B的子網是172.16.8.1/25,而Node A的子網是172.16.0.128/25。這個配置會記錄到叢集node的podCIDR資料項裡。

節點階段

經過以上叢集階段,K8S有了叢集CIDR,以及為每個節點劃分的podCIDR。在此基礎上,叢集會下發flanneld到每個階段上,進一步搭建節點上,可以給Pod使用的網絡架構。這裡主要有兩個操作,第一個是叢集通過Cloud Controller Manager給VPC配置路由表項。路由表項對每個節點有一條。每一條的意思是,如果VPC路由收到目的位址是某一個節點podCIDR的IP位址,那麼路由會把這個網絡包轉發到對應的ECS上。第二個是建立虛拟網橋cni0,以及與cni0相關的路由。這些配置的作用是,從階段外部進來的網絡包,如果目的IP是podCIDR,則會被節點轉發到cni0虛拟區域網路裡。

注意:實際實作上,cni0的建立,是在第一個使用Pod網絡的Pod被排程到節點上的時候,由下一節中flannal cni建立的,但是從邏輯上來說,cni0屬于節點網絡,不屬于Pod網絡,是以在此描述。

K8S從懵圈到熟練 – 叢集網絡詳解鳥瞰叢集網絡搭建總結

Pod階段

在前邊的三個階段,叢集實際上已經為Pod之間搭建了網絡通信的幹道。這個時候,如果叢集把一個Pod排程到節點上,kubelet會通過flannel cni為這個Pod本身建立網絡命名空間和veth裝置,然後,把其中一個veth裝置加入到cni0虛拟網橋裡,并為Pod内的veth裝置配置ip位址。這樣Pod就和網絡通信的幹道連接配接在了一起。這裡需要強調的是,前一節的flanneld和這一節的flannel cni完全是兩個元件。flanneld是一個daemonset下發到每個節點的pod,它的作用是搭建網絡(幹道),而flannel cni是節點建立的時候,通過kubernetes-cni這個rpm包安裝的cni插件,其被kubelet調用,用來為具體的pod建立網絡(分枝)。

了解這兩者的差別,有助于我們了解flanneld和flannel cni相關的配置檔案的用途。比如/run/flannel/subnet.env,是flanneld建立的,為flannel cni提供輸入的一個環境變量檔案;又比如/etc/cni/net.d/10-flannel.conf,也是flanneld pod(準确的說,是pod裡的腳本install-cni)從pod裡拷貝到節點目錄,給flannel cni使用的子網配置檔案。

K8S從懵圈到熟練 – 叢集網絡詳解鳥瞰叢集網絡搭建總結

通信

以上完成Pod網絡環境搭建。基于以上的網絡環境,Pod可以完成四種通信:本地通信,同節點Pod通信,跨節點Pod通信,以及Pod和Pod網絡之外的實體通信。

K8S從懵圈到熟練 – 叢集網絡詳解鳥瞰叢集網絡搭建總結

其中本地通信,說的是Pod内部,不同容器之前通信。因為Pod内網容器之間共享一個網絡協定棧,是以他們之間的通信,可以通過loopback裝置完成。

同節點Pod之間的通信,是cni0虛拟網橋内部的通信,這相當于一個二層區域網路内部裝置通信。

跨節點Pod通信略微複雜一點,但也很直覺,發送端資料包,通過cni0網橋的網關,流轉到節點上,然後經過節點eth0發送給VPC路由。這裡不會經過任何封包操作。當VPC路由收到資料包時,它通過查詢路由表,确認資料包目的地,并把資料包發送給對應的ECS節點。而進去節點之後,因為flanneld在節點上建立了真的cni0的路由,是以資料包會被發送到目的地的cni0區域網路,再到目的地Pod。

最後一種情況,Pod與非Pod網絡的實體通信,需要經過節點上iptables規則做snat,而此規則就是flanneld依據指令行--ip-masq選項做的配置。

總結

以上是阿裡雲K8S叢集網絡的搭建和通信原理。我們主要通過網絡搭建和通信兩個角度去分析K8S叢集網絡。其中網絡搭建包括初始階段,叢集階段,節點階段以及Pod階段,這麼分類有助于我們了解這些複雜的配置。而了解了各個配置,叢集通信原理就比較容易了解了。

繼續閱讀