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

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)

分享創造快樂