歡迎光臨
每天分享高質量文章

Kube-OVN 的設計思路和實現原理

Kube-OVN 是靈雀雲最新開源的一個 Kubernetes 網路專案,該專案將 OpenStack 社群內成熟的網路方案引入了 Kubernetes。本次分享主要介紹 Kube-OVN 的實現原理以及其中的設計原則,可以幫助大家更好的理解這個專案併在實際中進行使用。
關於 OVN 和 OVS 的介紹可以參考之前的分享《基於 OVN 的 Kubernetes 網路架構解析》這裡就不再重覆了。目前 Kube-OVN 已經在 GitHub 開源 https://github.com/alauda/kube-ovn,也歡迎大家 star 做貢獻。

 

為什麼又要做一個網路外掛

 

像靈雀雲這種小公司,一般是能用現成的方案就絕對不自己動手,之所以要自己動手來做,還是有很多現實的原因。
  1. 首先最主要的是現有的開源方案很難滿足我們客戶的需求,例如子網劃分,IP固定,QoS,VLAN 隔離,流量映象等等這種在傳統網路裡很常見的功能在絕大部分的開源網路方案裡都是缺失的。造成的結果是真正落地的時候我們會發現沒有一個開源網路方案能用,只能不斷的和網路部、系統部、應用部各個部門扯皮,割捨掉原有的一些網路功能來上容器。我們希望能透過技術的手段豐富現有的容器網路能力,來幫助客戶更順利的落地容器。

  2. 就是從我們自身維護容器雲的角度來看,容器平臺網路相關的問題是最難排查的。一個網路不通的問題可能會涉及 Pod 網路、CNI、Service、Iptables、IPVS、Ingress、DNS、NetworkPolicy、Loadbalancer 等等多個元件,流量的分散導致故障十分難以排查,並且需要運維人員掌握很多元件的原理。我們希望能夠把網路流量的資料面進行統一,不要再分散到各個元件上,降低維護方面的複雜度。

  3. 經過調研我們認為 OVN/OVS 這套網路元件功能上比較齊全,畢竟能夠實現 OpenStack 的所有網路功能,那麼對 Kubernetes 的網路來說能力其實是大幅上限溢位的,可以實現很多高階功能。此外 OVS 已經是經久考驗的虛擬交換機,穩定性是很有保證的,效能方面也有各種 DPDK 和硬體加速方案來託底,真正到要效能的時候我們有應對的方案。此外我們瞭解到的一些公有容器雲廠商內部其實也是用的 OVN 來做容器網路,我們也不算第一個烈士。

綜合這些因素我們決定自己開發一個基於 OVN 的網路方案,也就是 Kube-OVN 。一方面能夠很好滿足客戶和我們自己的需求,另一方面開源出來也能幫助社群一同進步。

 

Kube-OVN 的設計原則和思路

 

  1. 平移 OpenStack 網路的概念和功能到 Kubernetes。OpenStack 的網路已經發展了很多年,很多設計和概念也基本成了 SDN 的標準。我們希望能透過 OVN 不僅僅是引入一些高階功能,還能引入一些比較成熟的網路概念,像 VPC、Subnet、多租戶、FIP、SecurityGroup 等等,從整體上增強 Kubernetes 網路的能力。

  2. 統一網路的資料平面,我們希望把 Kubernetes 作為網路的控制平面,所有資料平面的功能都能透過 OVN 來實現,包括 Service、DNS、NetworkPolicy 都透過 OVN 來實現,簡化之後的維護工作。

  3. 盡可能改寫其他開源網路方案的功能。對我們來說也不希望同時支援多個網路外掛,每個客戶都不一樣,這樣對我們成本也很高。我們自己希望有這麼一個跟水桶機一樣的網路方案要的功能都改寫了,還能有些特色,這樣是最好的。

  4. 盡可能的易於安裝使用。OVN、OVS 這套東西本身的安裝和使用都還是比較複雜,門檻比較高我們希望能進行簡化,降低使用者使用的門檻。方便交付,也方便更好的推廣。

 

Kube-OVN 的整體架構和功能實現
先看一下元件的架構,Kube-OVN 自身的安裝 yaml 裡包含了 OVN 和 OVS 的安裝和配置,Kube-OVN 自身的邏輯主要集中在圖中藍色的部分 kube-ovn-controller,kube-ovn-cni 和 kube-ovn-cniserver。其中最主要的邏輯在 kube-ovn-controller 可以看成是一個 Kubernetes 資源的控制器,它會 watch Kubernetes 內所有和網路相關的資源變化,例如 Pod、Node、Namespace、Service、Endpoint 和 NetworkPolicy。每當資源發生變化 kube-ovn-controller 會計算預期的狀態,並將網路對應的變化翻譯成 OVN 北向資料庫的資源物件。同時 kube-ovn-controller 會將配置具體網路的資訊,例如分配的 IP、Mac、閘道器等資訊再以 Annotation 的方式回寫到 Kubernetes 的資源裡,方便後續的處理。
kube-ovn-cni 本身是很薄的一層,主要工作是適配 CNI 的協議和 Kubelet 對接,將標準的 cni add/del 命令傳送到每臺機器上的 kube-ovn-cniserver 進行後續處理。而 kube-ovn-cniserver 會根據傳入的引數反查 Kubernetes 中資源對應的 Annotation,操作每臺機器上的 OVS 以及容器網路。
舉一個建立 Pod 的例子,Pod 下發到 apiserver 後 kube-ovn-controller 會 watch 的新生成了一個 Pod,然後呼叫 ovn-nb 的介面去建立一個虛擬交換機介面,成功後將 OVN 分配的 IP、Mac、GW 等資訊反寫到這個 Pod 的 Annotation 中。接下來 kubelet 建立 Pod 時會呼叫 kube-ovn-cni,kube-ovn-cni 將資訊傳遞給 kube-ovn-cniserver。CNIServer 會反查 Pod 的 Annotation 獲得具體的 IP 和 Mac 資訊來配置本地的 OVS 和容器網絡卡,完成整個工作流。其他的 Service、NetworkPolicy 的流程也是和這個類似的。

 

Kube-OVN 實現的網路模型
Flannel 和很多網路的實現上都是一個 Node 一個子網,我們發現這種子網模型很不靈活,而且也很難擴充套件。因此在 Kube-OVN 裡我們採用了一個 Namespace 一個子網的模型,子網是可以跨節點的這樣比較符合使用者的預期和管理。每個子網對應著 OVN 裡的一個虛擬交換機,LB、DNS 和 ACL 等流量規則現在也是應用在虛擬交換機上,這樣方便我們之後做更細粒度的許可權控制,例如實現 VPC,多租戶這樣的功能。
所有的虛擬交換機目前會接在一個全域性的虛擬路由器上,這樣可以保證預設的容器網路互通,未來要做隔離也可以很方便的在路由層面進行控制。此外還有一個特殊的 Node 子網,會在每個宿主機上新增一塊 OVS 的網絡卡,這個網路主要是把 Node 接入容器網路,使得主機和容器之間網路可以互通。需要註意的是這裡的虛擬交換機和虛擬路由器都是邏輯上的,實現中是透過流表分佈在所有的節點上的,因此並不存在單點的問題。
閘道器負責訪問叢集外部的網路,目前有兩種實現,一種是分散式的,每臺主機都可以作為執行在自己上面的 Ood 的出網節點。另一種是集中式的,可以一個 Namespace 配置一個閘道器節點,作為當前 Namespace 裡的 Pod 出網所使用的閘道器,這種方式所有出網流量用的都是特定的 IP nat 出去的,方便外部的審計和防火牆控制。當然閘道器節點也可以不做 nat 這樣就可以把容器 IP 直接暴露給外網,達到內外網路的直連。

 

Kube-OVN 功能實現

 

首先是子網,子網是 Kube-OVN 中最為重要的一個概念,涉及到之後的 IP 分配,ACL 以及未來的 VPC 等功能。實現上每個子網對應 OVN 中的一個虛擬交換機,對應 Kubernetes 中的一個 Namespace,我們可以透過給 Namespace 加 Annotation 的方式來配置一個虛擬交換機。子網裡可以配置基礎的 CIDR,Gateway,保留 IP 段,以及一些基本的 ACL,這些都可以用 OVN 自身提供的能力。
然後是 IP 分配。Kube-OVN 現在支援隨機分配和固定 IP 分配。隨機分配比較簡單,可以使用 OVN 提供的 dynamic addresses 能力,自動分配一個當前子網內不衝突的 IP/Mac。固定 IP 我們採用了一個額外的 annoation ip_pool,Pod 在啟動時 controller 會跳過 OVN 的自動分配根據 ip_pool 內的 IP 選擇一個未被佔用的地址分配給 Pod。對於 Deployment Pod 啟停會產生 IP 的釋放和再分配的過程。錶面上看 Deployment 下麵的幾個 Pod 一直用固定的 IP,但實際上是一個動態變化,最中表現出來使用固定 IP 的過程。
之後是 QoS,透過 QoS 可以控制容器的 Ingress 和 Egress 頻寬,我們可以透過 Pod 的 Annotation 來動態控制容器頻寬。實現上我們最早計劃使用 OVN 的 QoS 能力,但是實際使用時發現 OVN 的 QoS 這塊存在問題,無法控制同主機內的流量,因此最終使用的是 OVS 自身的 ingress_policing_rate 和 Port QoS 來實現頻寬控制。
閘道器這裡 OVN 本身提供了閘道器的能力,但是對網路有額外的需求需要用到一塊單獨的網絡卡做 Overlay 網路的 offload,使用上有些限制因此我們並沒有採用。我們最終的實現是使用了 OVN 中的策略路由,將訪問外網的流量路由到特定節點,再透過 Iptable 做 Masq 自己實現了一套從閘道器出網的邏輯。這種方案的好處是對網路沒有額外的需求,我們在公有雲上都可以使用這種閘道器樣式。當然在具體落地時也可以根據場景替換成效能較好的 OVN Gateway 方式。
流量映象。對容器流量進行抓包是件很繁瑣的事情,好在 OVS 本身有流量映象的功能,Kube-OVN 會在每臺主機上建立一塊 mirror0 的網絡卡,並設定映象規則,將該主機上所有的容器流量複製一份到 mirror0 網絡卡。這樣我們只需要 tcpdump -i mirror0 就可以捕獲到這臺主機上所有的容器網路流量了。方便之後的應用層面的監控和審計。
還有一些其他的功能。例如用 OVN 的 LB 代替 kube-proxy,用 ACL 來實現 NetworkPolicy 還有 OVN 的高可用等等,感興趣的可以爬一下 Kube-OVN 的 release note 看看還有什麼隱藏功能。
這些看上去功能都比較複雜,但實際使用還是比較簡單的在對應的資源上打 Annotation 就可以了。此外即使不做任何配置,Kube-OVN 會帶一個預設的子網,預設的分散式閘道器,以及內建的 Service 和 NetworkPolicy 實現,完全可以當一個增強版本的 Flannel 來用。

 

近期工作和未來發展

 

  1. IPv6 的支援,這是我們客戶方面比較急迫的一個需求,由於工信部的 IPv6 推廣計劃,對 IPv6 的需求也越來越多,同時借這個機會我們會對 Kube-OVN 現有的子網進行重新的設計,可能會抽象出一個 CRD 來做更複雜的控制。

  2. 監控 /tracing 工具的整合。傳統網路工程有很多不錯的網路檢測工具例如 IPFIX、sFlow 和 NetFlow,我們未來會將這些工具加進來豐富網路的功能。此外借助流量映象的能力我們也可以做一些應用層的流量分析和監控。

  3. 效能最佳化和 DPDK 的支援,主要是為了消除客戶對 OVS 效能的擔心。我們和社群內的一些人進行過交流,在使用 DPDK 後即使是小包也可以打滿萬兆網絡卡,因此效能方面還是很有前途的。

現在專案已經開源在 https://github.com/alauda/kube-ovn 歡迎大家來 star 給作者打打氣,也歡迎感興趣的個人,公司或者友商都能參與進來,大家一塊來完善這個專案。


Q&A;

 

Q:能說說元件 kube-ovn-cni 具體是做什麼的?OVN 本身不是已經是 OVS 的控制面了麼?
A:其實做的是容器網絡卡和 OVS 的對接,OVN 那邊生成了 port 的資訊,需要 kube-ovn-cni 把這個資訊同步到 OVS 和容器網絡卡。
Q:能講講 Kube-OVN 負載均衡和會話保持是怎麼做的嗎?已經支援哪些策略?
A:目前的負載均衡用的是 OVN 的 L2 Loadbalancer,這一塊的負載均衡還比較簡單隻支援 IP Hash。
Q:多租戶 /VPC 樣式下是否可以互相之間網段衝突,如何實現 livenessProbe?
A:這塊暫時還不支援,主要是 kubelet 是在主機的 network namespace 進行 probe,其實可以改 kubelete 程式碼進入到對應容器的 ns 再 probe 就可以了,但是這塊需要 upstream 來進行支援,自己魔改現在倒也是個方案。
Q:Kubernetes 的業務使用本身就是有侷限的,這種無限制擴大虛擬網路的做法,基於業務風險和成本來講,真的很勇敢,如果原有的 Kubernetes 生態被改掉了,怎麼保證開源的東西可以業務延續?
A:這個問題有點大,我們現在看到的趨勢還是 Kubernetes 不斷的發展,各個業務都在往 Kubernetes 走,我們做這個其實也希望能儘量和 Upstream 同步,並且之後可以去影響 Upstream。還有很多複雜的功能,比如 IPv4/IPv6 的雙棧,多租戶我們暫時也還沒開始,也是因為 Upstream 現在對這塊的支援還不好。
Q:和 https://github.com/ovn-org/ovn-kubernetes 的區別是什麼?
A:ovn-kubernetes 我們之前調研主要問題在於他們是和 Flannel 類似的一個節點一個子網的模型,再就是看他們的程式碼過程中發現控制平面存在著丟訊息的隱患。最後看到網路模型和控制平面都要改,工作量太大了我們就自己從頭來了。
Q:使用 Flow 負載均衡器的效能怎麼樣,是否適合上生產環境?
A:大部分的 Flow 效能問題都可以用 DPDK 來解決,我們之前問過一些公有雲的廠商效能方面是可以的,但是可能功能方面有些簡單。
Q:使用 OVS 對 Host 機器的效能壓迫有多大?
A:我們目前看來還好,OVS 本身帶 cache 的機制,主要還是業務對效能用的比較多一些。
Q:kube-ovn-controller 如果來不及寫入 podIP 這些資訊,CNI 外掛獲取不到分配的 IP 資訊,會不會導致 Pod 建立失敗,還有 ovn-cni 是能過什麼協議和 ovn-cni-server 進行協作的?
A:來不及寫入的情況下 CNIServer 會重試等待 annotation ready,如果超時的話會失敗等 kubelet 下次呼叫 CNI 的時候重新獲取資訊。CNI 和 CNIServer 現在是透過一個本機的 socket 走 http 協議進行通訊。
Q:DPDK 怎麼滿足需求?使用容器,可以用 DPDK 加速麼?
A:DPDK 主要做 OVS 的流表加速,社群由 ovs-dpdk 的 binding,容器相當於用的是 OVS 的網絡卡,這樣 DPDK 就可以加速容器的網路。
Q:在沒有硬體交換機的情況,這個網路外掛怎麼利用虛擬機器模擬交換機呢?
A:還是要有硬體交換機做物理上的網路連通的,虛擬交換機是在機器中用軟體的方式來模擬交換機的行為,這樣一臺機器上的多個容器或者虛擬機器就好像接在了一個物理交換機上。
已同步到看一看
贊(0)

分享創造快樂