InfoQ 專訪微軟谷歌專家:Kubernetes IPv4/IPv6 雙協議棧

infoq 發佈 2022-02-22T19:10:44+00:00

隨著 2021 年 12 月Kubernetes 1.23的發布,雙協議棧已在轉為GA版本中提供。例如,在運行在小規模 IPv4 地址空間上的用戶,可選擇在集群的某個 Node 子集上啟用雙協議棧,而其餘 Node 運行在可提供更大可用地址空間的 IPv6 地址族上。

雙協議棧(Dual Stack),即同時提供對 IPv4/IPv6 地址的支持。隨著 2021 年 12 月Kubernetes 1.23的發布,雙協議棧已在轉為GA版本中提供。


該項目歷時多年,涉及幾乎全部 Kubernetes 組件,詳見「Kubernetes增強提案(KEP,Kubernetes Enhancement Proposal)KEP-563」。


為此,InfoQ 擇機訪談了微軟的Khaled (Kal) Henidak和谷歌的Tim Hockin。正是 Kal 和 Tim 通過與 SIG-NETWORK 社區的合作,設計並實現了雙協議棧。本次訪談中,兩位專家介紹了雙協議棧項目的方方面面,包括項目動機、技術細節、漫長的歷程和路線圖,以及雙協議棧對 Kubernetes 各組件的影響,進而談及在 Kubernetes 雲服務提供商中引發的連鎖反應。


InfoQ:Kubernetes 提供對 IPv6 和雙協議棧的支持,有何意義?


Khaled (Kal) Henidak:回答這個問題,必須簡要回顧一下項目的發展歷程。Kubernetes 自面世之初,就提出了為運行於其上的每個工作負載實例 (即 Pod) 分配唯一 IP 地址的理念。該理念在當時也並不新穎,這已是虛擬機環境中的標準操作實踐,但對於 Kubernetes 這樣的環境仍具創新性。由此,我們實現了 IP 層的可尋址工作負載、通過 Service API 的發現、精心設計的 Ingress 控制、網絡安全策略等多個用例。


與此同時,物聯網、邊緣計算和僅運行於 IPv6 之上的 5G 等多個業界領域正得到高速發展。這樣的迅速發展進一步消耗了剩餘的少數 IPv4 地址。對於正考慮使用 IPv6 以避免上述問題的組織,或只是希望用 IPv6 來提高性能的組織,難免置身於充滿挑戰的境地。因為組織的 IPv6 集群和工作負載,難以連接到幾乎只能在 IPv4 上運行的現有系統。在當時,唯一可用的解決方案是一些地址轉換類方法,但這些解決方案將會引入性能損失和操作複雜性。


在 IPv4/IPv6 雙協議棧網絡上運行 Kubernetes,可在不增加複雜性和損失性能的情況下,支持工作負載本地訪問 IPv4 和 IPv6 端點。集群操作人員還可在提供外部端點時,根據自身需求選擇以任一順序提供其中一種地址族(Address Family),或是兩種均提供。Kubernetes 並未對運行的網絡做出任何強假設。例如,在運行在小規模 IPv4 地址空間上的用戶,可選擇在集群的某個 Node 子集上啟用雙協議棧,而其餘 Node 運行在可提供更大可用地址空間的 IPv6 地址族上。


在我看來,未來大部分的工作負載將轉到僅有 IPv6 的網絡上,集群也將僅運行在 IPv6 網絡上。但在此之前,雙協議棧將保持新舊兩個世界之間的聯繫。


Tim Hockin:簡而言之,Kubernetes 現在可同時使用 IPv4 和 IPv6,Pod 和 Service 可各取所需。

展開來說,我們擴展了大量的 API 去支持多 IP 地址,而不僅僅是單個地址,包括 Pod、Service、Node 等。我們更新了一系列的組件去使用這些擴展的 API,包括 apiserver、controller-manager、kube-proxy、kubelet 等。這樣用戶可以配置自身集群去向 Pod 和 Service 提供 IPv4 和 IPv6 地址。為最大程度上達到透明和低風險,我們已盡力而為。對於並不需要雙協議棧的用戶,則完全不會受到影響。但是如果用戶確實需要雙協議棧,那麼也易於啟用。對於用戶現有的 Pod 和 Service,目前尚不能自動轉換,但用戶自行實現也很簡單。如果用戶的控制器只能理解單協議棧,那麼一切將會繼續如常工作。


鑑於目前已提供對雙協議棧的支持,一些工作將得到簡化。例如,IPv4 限定為 32 位,即提供 40 億個 IP 地址。「私有」IPv4 地址範圍僅支持數百萬個 IP,但通常基於 CIDR 的路由意味著需要整塊地分配地址空間。IPv6 具有 128 位,即可提供萬億兆個 IP 地址,這降低了預分配大塊地址空間的風險,有望簡化 Kubernetes 在 Flat IP 網絡模式下的使用。


InfoQ: 為便於非網絡專業人士理解,你們能更多地介紹一些技術實現細節嗎?


Henidak:這要從 Pod 開始介紹。在 Kubernetes 中,Pod 表示為一個 API 對象,其中有一個狀態欄位描述分配給該 Pod 的網絡 IP 地址。該 IP 由 kubelet 通過 Node 上的「容器運行時接口」(CRI,Container Runtime Interface)讀取並訪問。CRI 本身通過調用「容器網絡接口」(CNI,Container Network Interface)設置網絡,CNI 是一個負責設置網絡的獨立組件,包括 Pod 的雙協議棧。我們擴展了該 API 欄位,使其可以接受雙協議棧地址,可以是單個 IP 地址,或是來自不同 IP 地址族的兩個 IP 地址,順序不限。這樣就可以修改各種組件,讓它們說「嘿,這個 Pod 是雙協議棧的」。


此後,我們以同樣的方式擴展了 Service API,讓用戶可以表示 Service 對象的雙協議棧屬性。用戶可以按任一順序選擇任何單個 IP 或地址族、雙協議棧 IP 或地址族,或只是「如可用則設為雙協議棧」。進而 api-server 可根據用戶的需求和期望順序,為 Service 對象預留或分配 IP。


下一步,我們轉向負責查找符合 Service 規範的端點的控制器(Endpoint Controller)。我們實現了全新的、性能更好的端點分片(Endpoint-Slice)控制器。這些組件設計用於識別 Service 的 IP 地址族規範,相應地在各 Pod 中找到對應的 Service。


最後,我們轉向 kube-proxy。kube-proxy 運行在每個 Node 上,負責將 Service IP 轉換為負載均衡的 Pod IP。這裡同樣也必須轉換為雙協議棧。例如,如果用戶已將 kube-proxy 配置為在 Linux 設備上使用 iptables,那麼 kube-proxy 將同時使 IPv4 和 IPv6 的 iptables,以確保規則能匹配用戶所設置的規格。


Hockin:雖然 IPv6 並非「新鮮事物」,但尚未成為網絡的全局默認設置。隨著 IPv6 在全球的日益普及,「雙協議棧」網絡這一概念起到了一種橋樑作用。雙協議棧模式支持各工作負載同時訪問已有的 IPv4 地址和新的 IPv6 地址。例如,許多網站仍然不支持 IPv6,所以有時需使用 IPv6,有時需使用 IPv4。


不幸的是,Kubernetes 是基於 Pod 和 Service 等只有一 IP 地址這樣一個普遍存在的想法構建的。因此這項工作的部分艱苦之處在於,需要找出所有這些地方並更新,實現以安全、兼容的方式支持多 IP 地址。對於這樣的網絡密集型系統,需要處理很多地方,甚至是大量不易接觸到的邊緣用例。

例如,過去 Kubernetes Service 只具有單個 IP 地址。要添加雙協議棧,我們必須考慮是擴展為兩個地址更好,還是告訴用戶去創建兩個不同的 Service,每種 IP 類型一個 Service。這兩種方法各有利弊。


InfoQ: 可以說 KEP-563 涉及到所有的 Kubernetes 組件。你們如何評價該 KEP?介紹一下這樣的大範圍變更帶來了哪些挑戰。


Henidak:要回答這個問題,通常是純粹從構建、測試和發布的角度,但在此我想闡述一些略有不同的事情。一旦意識到變更並非憑空產生的,就會明白挑戰是前所未有的。隨著變更的應用在持續推進,系統的其它部分也相應地推進和發生變化。例如,在我們致力於改進 Service API 時,Endpoint Slice 控制器也在一併改進,這意味著我們必須同步對齊和修改 Kubernetes 其他部分代碼。這需要協調多個推進中的 PR 和多位代碼庫維護人員。很高興看到各位維護人員密切合作,確保了各項功能的協調和正確性。


另一個挑戰是「全新 API 方法」的理念,在我看來值得銘記。Kubernetes 對 API 及其指南具有嚴格的維護規範,以確保各版本間的一致性和前後向兼容性,最終為使用 CLI 和 API 的用戶提供經過改進的、一致的整體用戶體驗。在修改 API 時,我們需要對欄位做「多值化」(plural-ize)。例如,Pod IP 是一個單值欄位,需要更改為一個多值欄位,表示該 Pod 現在可以有 IPv4 和 IPv6 IP,與此同時保持對舊集群的後向兼容性,尤其是偏態集群,即集群的某部分是雙協議棧的,而其他部分不是。這在 Kubernetes API 設計中是一個未知領域,我們必須測試各種方法,並對指南做相應的更新。更具挑戰性的考慮是,Service API 不僅引入了欄位多值問題,而且還引入了相互依賴的欄位,其中任何欄位都可以驅動其餘依賴欄位的值。這是另一個我們必須開拓的未知領域。


Hockin:KEP-563 是這個項目歷史上規模最大、影響最廣的提案之一。我們不想一頭扎進去就直接開始編碼,因此我們考慮必須儘可能做好前期工作。啟動時相對簡單,但隨著我們討論了所有涉及地址處理的地方,事情開始變得越來越複雜。僅編制需更新之處的清單,就花費了大家很長的時間。

但更新清單的規模太長了,一時難以消化,我們不得不把將其分成數個階段。我們曾認為已達到事無巨細了,但實際開發證明我們仍然有所紕漏。歷經多次細節疊代,才達到我們可以稱之為「Alpha」的版本。


一旦交付,我們才意識到在很多細節上仍未達到目標,進而我們又做了更多次疊代。我很高興所有維護人員願意如此,去額外付出時間。在我看來,結果好於預期。


InfoQ: 對於與傳統 IPv4 應用的後向兼容性,在引入雙協議棧後,開發人員和架構師可能會遇到哪些無法預知的問題?採用雙協議棧可能遇到什麼阻礙?


Henidak:兼容性很難盡善盡美。尤其是面對幾乎難以窮盡的 Kubernetes 配置變體,我們不可能對預期的兼容性問題給出一個全面的聲明。


我想從被動和主動兩個角度看問題,其責任分別由用戶和維護人員社區承擔。從主動方面看,我認為我們在設計和測試方面做得很好,尤其是測試。我記得在整個測試過程中,經常說的一句話就是「測試直至擔心轉為無聊」。在推出穩定版之前,我們一直在密切關注雙協議棧在雲、Kubernetes Kind、kubeadm 等整個生態中的表現,確認是否會存在任何問題。即使已經準備好推出整個發布周期的穩定版,我們還刻意將其維持在 Beta 階段,以便給每個維護人員更多的時間進行測試和驗證。在社區響應上,我們密切關注報告的動議和問題,與那些已部署雙協議棧的用戶保持經常性聯繫。所有這些,並不僅僅是為了兼容性問題,還為了簡化變更,處理任何可能存在的問題。


我對 API 兼容性充滿信心。現有集群升級到雙協議棧,應該是一個無縫的過程。讓我擔心的是「回退」。當用戶將集群升級到雙協議棧,實際上是為 Service API 分配了更大的地址空間,即將 IPv6 CIDR 添加到現有的 Service IPv4 CIDR,也可選擇包含 Pod CIDR,具體取決於集群網絡的配置方式。如果用戶決定回退到單協議棧,那麼必須將此作為「Pod 和 Service CIDR 變更」來處理。這個已經應用到集群的複雜變更,通常需要集群用戶手動操作。


Hockin:如果我們的工作做得到位,就應該不會導致任何後向兼容性問題。以往一切能工作的,應該都會繼續工作。在用戶沒有特別要求雙協議棧的情況下,即便 Pod 被分配了雙協議棧地址,Service API 也會默認為單協議棧。


如果用戶有任何問題,我們當然願意傾聽意見。


InfoQ: 你們能談一下對不同的公有雲 Kubernetes 服務和 CNI 提供商而言,雙協議棧實現將產生怎樣的級聯效應?


Henidak:當我們正努力在 Kubernetes 上實現雙協議棧時,公共雲提供商就已經開始針對傳統的 IaaS 工作負載提供雙協議棧支持。我相信,尤其是現在 Kubernetes 1.23 已發布,我們應該能首先看到雙協議棧集群以 DIY 集群的形式提供,之後是託管的集群服務。另一個我非常關注的問題,是非傳統因素對集群雙協議棧的影響。例如雲邊協同中,一些或者說大部分集群節點部署在邊端,而控制平面是雲託管的。由於公共 IPv4 地址空間受限,此類用例對雙協議棧具有強烈的需求。


Hockin: Kubernetes 支持雙協議棧,並不意味著所有的服務提供商和環境都要支持它。如果用戶想在雲環境中使用雙協議棧,那麼需要確保雲提供商確實提供了網絡級支持。如果用戶使用託管 Kubernetes 產品,那麼需要確保服務提供商支持雙協議棧。


Kubernetes 1.23 是雙協議棧的首個非 Beta 版本,我預計大部分服務提供商需要一定時間才能提供雙協議棧支持,進而將其作為受支持的產品提供。


InfoQ: 你們會繼續推進 IPv4 和 IPv6 地址混用嗎?請簡單介紹一下雙協議棧及相關生態系統的路線圖。


Henidak:是的。在 Kubernetes 雙協議棧的設計、實現和測試過程中,這是我們一直堅信的事情之一。不僅是地址的混合,而且還要確保 Kubernetes 不對 IP 地址族的排序做任何假設。例如,一些用戶更喜歡默認 IPv6 集群,但能在有需要時支持雙協議棧。其他用戶可能有不同的偏好。甚至 Service API 也支持「如可用則使用雙協議棧」。這樣,開發人員在發布 Kubernetes 操作符、圖表和其他類型規範時,能夠以任何他們認為合適的方式表達應用的網絡需求。


「路線圖」這一方式,是我特別認同的一種社區做法。路線圖來自所有參與者的共識,即我們正處於一個永無止境的過程中,總是有更多的事情要做。通常,我們對中長期目標有一個想法,但為應對不斷變化的要求或優先事項,我們在計劃和執行方面也非常靈活。雙協議棧支持是一個重要的里程碑,但它只是我們永無止境的過程中的一個里程碑。我預計近期會有更多的 CNI 提供商和 Ingress 控制器支持雙協議棧。我希望對雙協議棧的支持能擴展到雲、負載均衡器和裸機部署。


從長遠來看,我看到用戶越來越關注多網絡和多宿主 Kubernetes Pod,其中一個 Pod 可能連接到多個網絡的多個 NIC,一個 Pod 也能給出來自單個或多個 IP 地址族的多個地址。這將使網絡虛擬設備 (NVA,Network Virtual Appliance) 提供商等重要用例成為可能,並且也能在多集群或多網絡環境中很好的工作。


Hockin:澄清一下,這項工作並非是讓 IPv4 客戶端與 IPv6 伺服器一起使用,反之亦然。它允許用戶表達特定的工作負載可使用任一 IP 地址族訪問伺服器,具體取決於用戶的需求。它還可以讓 Kubernetes 用戶更完整地表達自身的需求。例如,如果用戶具有一個雙協議棧集群,但希望自己的服務只提供某一種 IP 地址族。雙協議棧支持用戶表達此需求,並確切選擇所使用的 IP 地址族,且得到系統其餘部分的認同。


這為某些類別的應用開啟了大門,特別是面向網絡的應用。在此之前,這類問題很難處理,需要深入架構底層。希望大多數用戶不會注意或關注雙協議棧的存在,但那些真正需要它的人會發現該功能可用,隨時可啟用。


Kubernetes 網絡特性的更多詳細信息,可訪問SIG-NETWORK社區,其中可查看雙協議棧實現的相關歷史。

關鍵字: