這是非雲環境中Kubernetes的配置和運行的第七篇文章,本文將聚焦於如何理解Pod間的通信機制,闡釋flannel的技術細節,及其在Kubernetes集羣網絡中的作用。
集羣網絡
“組網是kubernetes的核心,準確理解組網的工作機制非常有挑戰。”
引用自: https://kubernetes.io/docs/concepts/cluster-administration/networking/
在闡釋flannel及其如何適用於Kubernetes之前,理解集羣的網絡特性是非常重要的。
本文主要聚焦於如何理解Pod間的通信機制。
Kubernetes網絡模型遵循一些基本假設。 官方文檔中指出,Kubernetes網絡模型需要:
- 所有Pod均具有與其它Pod通信的能力,無需做NAT。
- 節點(即運行Kubernetes集羣的機器。節點可以是實際物理機,也可以是虛擬機,或是任何可運行Kubernetes的環境。)也可與其它所有Pod通信,無需做NAT。
- 每個Pod能看到自己的IP,其它Pod也能看到同一IP。
Kubernetes網絡模型
每個kubernetes節點(無論主節點還是工作節點)均是一臺具有網絡命名空間(netns)的Linux主機。節點提供網絡接口爲主要接口,可以是虛擬機,也可以是裸金屬主機。網絡接口在上圖中顯示爲eth0。
細看上圖,我們可以看到每個Pod還具有自己的eth網絡接口。這表明每個Pod具有自己的網絡配置,即IP地址、路由等。這也表明着每個Pod具有自己的netns。這樣,netns通過網絡接口相互隔離。
打個比方。假設你和一位同事去拉斯維加斯參加一次會議。企業資助你們參與此會,因此你們住在同一酒店(即Kubernetes節點)。酒店的每個房間(即Pod)裝了客房電話(即網絡接口)。
你使用客房電話與住在酒店之外的家人聯繫。當然,沒有免費的服務,酒店會對使用客房電話打出酒店收費。爲實現此,所有呼出電話通過一箇中心(即eth0)。中心註冊呼出電話,然後將呼叫轉到酒店外。客房電話和中心間的鏈接,比喻了虛擬網絡接口(veth)在網絡中的功能。
“veth是一個虛擬以太網設備。其可擔當netns間的通道,創建與不同netns中物理網絡設備間的橋接,但也可用於獨立網絡設備。
veth設備通常成對創建並互聯。”
引用自: http://man7.org/linux/man-pages/man4/veth.4.html
現在,你和同事希望在離開會議或喫晚飯等時候相互知道。你們考慮節約開支,因此決定使用酒店客房電話而非手機相互聯繫。在酒店辦理入住手續時,前臺告知你們可以通過輸入“#<房間號>”,實現房間相互呼叫。酒店提供一個內部中心實現這種通信。該中心類似於上圖中cni0所扮演的角色,擔當允許Pod間通信的橋樑。
這家酒店可能有多棟樓,你的同事入住的是二號樓。不過,酒店前臺解釋說根本沒有問題。與其它樓的房間通信,只需要在房間號之前添加樓號,即“#<樓號><房間號>”。 內部中心(即cni)將知曉該地址不在本樓的內部,將呼叫重定向到中心(即eth0),進而重定向到另一棟樓(即另一個Kubernetes節點)的中心(類似於 eth0)。呼叫將依次傳遞到各棟樓自身的內部中心,最終定位到目標房間。更多技術說明,可查看本文“跨主機路由通信”一節。
在Kubernetes中,上述所有配置和管理是通過CNI(容器網絡接口,Container Networking Interface)插件實現的。
什麼是CNI?
CNI是“容器網絡接口”(Container Networking Interface)的縮寫,實現 按規範良好定義接口的外部軟件模塊,爲Kubernetes執行網絡功能操作提供支持。
“每個CNI插件必須實現爲可被rkt或Kubernetes等容器管理系統調用執行的可執行文件。”
“CNI插件負責將網絡接口插入到容器的netns(例如,veth的某一端),並在主機上做必要的更改(例如,將veth的另一端連接到網橋)。然後,CNI插件對接口分配IP,並通過調用相應的IPAM插件,設置與IP地址管理一致的路由。”
引用自 https://github.com/containernetworking/cni/blob/master/SPEC.md#cni-plugin
Kubernetes流量路由
爲闡釋流量在Pod間的路由情況,本文詳細介紹兩類場景。
同一主機的流量路由
Pod 4和Pod 6之間通信的步驟如下:
- 網絡包通過eth4網絡接口離開Pod 4的netns,通過虛擬網絡接口veth4到達root netns。
- 網絡包離開veth4,到達cni0,並查找Pod 6的地址。
- 網絡包離開cni0,重定向到veth6。
- 網絡包通過veth6離開根netns,通過網絡接口eth6到達Pod 6的netns。
跨主機路由通信
Pod 1到Pod 6的通信步驟如下:
- 網絡包通過網絡接口eth1離開Pod 1,通過虛擬網絡接口veth1到達root netns。
- 網絡包離開veth1,到達cni0,查找Pod 6的地址。
- 網絡包離開cni0,重定向到eth0。
- 網絡包從Master 1離開eth0,到達網關。
- 網絡包離開網關,通過工作節點1的網絡接口eth0到達root netns。
- 網絡包離開eth0,到達cni0,並查找Pod 6的地址。
- 網絡包離開cni0,重定向到虛擬網絡接口veth6。
- 網絡包通過虛擬地址接口veth6離開root netns。
“flannel是一種配置第三層網絡結構的簡單易用方式,該層網絡專門針對Kubernetes設計。
flannel在每個主機上以稱爲flanneld的單個微小二進制程序運行代理,並負責從更大的預配置地址空間中對每個主機分配租用子網。Flannel直接使用Kubernetes API或etcd存儲網絡配置。配置包括所分配的子網及所有的輔助數據,例如主機的公共IP等。flannel支持使用多種後端機制轉發數據包,例如VXLAN、各種雲集成機制等。”
引用自: https://github.com/coreos/flannel
後端(Backends)
“Flannel可配合多種後端使用。後端一旦設定,在運行時不能更改。
VXLAN是推薦的後端配置。對於希望提高性能的有經驗用戶,在架構支持(通常不適用雲環境)的情況下可使用host-gw。UDP通常只推薦用於調試目的,或是對於不支持VXLAN的非常舊的內核。”
引用自: https://github.com/coreos/flannel/blob/master/Documentation/backends.md
本教程解決方案中使用的VXLAN模式,下面介紹其主要內部機制。
Flannel網絡空間
在默認情況下,flannel在劃分更小子網時使用CIDR 10.244.0.0/16,其中每個節點使用10.244.X.0/24網絡掩碼,Pod的IP將位於分配給指定節點的子網內。
換句話說,這意味着每個節點可以具有254個活躍Pod。每個Pod在分配給節點的子網中佔用不同的IP。
上述配置規範是在kube-flannel.yml規格文件中聲明的,網絡在net-conf.json中定義,如下例所示:
kind: ConfigMap
apiVersion: v1
metadata:
name: kube-flannel-cfg
namespace: kube-system
labels:
tier: node
app: flannel
data:
cni-conf.json: |
{
"name": "cbr0",
"plugins": [
{
"type": "flannel",
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
}
}
]
}
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
下面鏈接給出了flannel的官方定義: coreos/flannel
flannel是一種容器網絡架構,設計用於Kubernetes。
veth:虛擬以太網設備
“veth是一種虛擬以太網設備。veth可作爲netns間的隧道,創建橋接另一個netns中物理網絡設備,也可作爲獨立的網絡設備使用。”
引用自: http://man7.org/linux/man-pages/man4/veth.4.html
cni0:網橋設備
cni0是一種Linux網橋設備。所有veth設備將連接到該網橋,使得所有位於同一節點的Pod間可相互通信。參見上文給出的Kubernetes網絡模型和酒店的比喻。
VXLAN設備(即flannel.)
“VXLAN(虛擬可擴展LAN,Virtual Extensible LAN)是一種 網絡虛擬化技術,用於解決大規模 雲計算部署中 可擴展性問題。VXLAN使用類 VLAN封裝技術,將 OSI中 第二層的 以太坊幀封裝到 第四層的 UDP報文中。VXLAN默認使用 IANA指定的4789端口作爲UDP端口。VXLAN終端也被稱爲VXLAN通道終端(VETP),它是VXLAN通道的終點,支持虛擬或物理的 交換端口。
引用自: https://en.wikipedia.org/wiki/Virtual_Extensible_LAN
VXLAN接口(即上圖中的flannel.1)的主要功能是確保Pod及其網絡間的通信經由Overlay二層網絡,這是Kubernetes網絡的前提之一。如前所述,每個節點具有一個子網,每個Pod的IP位於該子網中。
組網就是讓各VXLAN如同連接在同一網絡中工作。即 每個VXLAN網絡自成體系,但“處於”同一網絡域內。
在上面的酒店比喻中,VXLAN是連接各棟樓的(物理)電話線,允許你所在樓(節點1)的客房(Pod 1)可與你同事所在的另一棟樓客房(Pod 4)通話。
flanneld
flanneld 是一個駐留內存進程,負責維持節點間路由及路由所在Pod的信息最新。
在上面的酒店比喻中,flanneld就是一名負責維護客房可用情況的酒店員工。例如,酒店新建了一棟樓,提供了新的客房;或是某棟樓正在裝修維護,其中客房不可用。
原文鏈接:
Kubernetes Journey — Up and running out of the cloud — flannel