淺談 k8s ingress controller 選型


大家好,先簡單自我介紹下,我叫厲輝,來自騰訊雲。業余時間比較喜歡開源,現在是Apache APISIX PPMC。今天我來簡單給大家介紹下 K8S Ingress 控制器的選型經驗,今天我講的這些內容需要大家對 K8S 有一定的了解,下面是我的分享。

名詞解釋

閱讀本文需要熟悉以下基本概念:

  • 集群:是指容器運行所需雲資源的集合,包含了若干台雲服務器、負載均衡器等雲資源。

  • 實例(Pod):由相關的一個或多個容器構成一個實例,這些容器共享相同的存儲和網絡空間。

  • 工作負載(Node):Kubernetes 資源對象,用於管理 Pod 副本的創建、調度以及整個生命周期的自動控制。

  • 服務(Service):由多個相同配置的實例(Pod)和訪問這些實例(Pod)的規則組成的微服務。

  • Ingress:Ingress 是用於將外部 HTTP(S)流量路由到服務(Service)的規則集合。

K8S 訪問現狀

在 K8S 中,服務跟 Pod IP 主要供服務在集群內訪問使用,對於集群外的應用是不可見的。怎么解決這個問題呢?為了讓外部的應用能夠訪問 K8S 集群中的服務,通常解決辦法是 NodePort 和 LoadBalancer。

這兩種方案其實有各自的缺點,NodePort 的缺點是一個端口只能掛載一個 Service,而且為了更高的可用性,需要額外搭建一個負載均衡。LoadBalancer 的缺點則是每個服務都必須要有一個自己的 IP,不論是內網 IP 或者外網 IP。更多情況下,為了保證 LoadBalancer 的能力,一般需要依賴於雲服務商。

在K8S的實踐、部署中,為了解決像 Pod 遷移、Node Pod 端口、域名動態分配,或者是 Pod 后台地址動態更新這種問題,就產生了 ingress 解決方案。

Ingress 選型

Nginx ingress 的缺點

Ingress 是 K8S 中非常重要的外網流量入口,前面又拍雲的總監也講到了 K8S 默認的 Nginx ingress。這個 ingress 是 K8S 所推薦的默認的 ingress。為了跟后面的 Nginx 提供的商業版 ingress 作為區分,我就叫它叫 K8S ingress。K8S ingress,顧名思義基於 Nginx 的平台,Nginx 現在是世界上最流行的 Nginx HTTP Sever,相信在座各位都對 Nginx 比較熟悉,這是一個優點。第二個優點則是 Nginx ingress 接入 K8S 集群所需配置非常少,而且有很多文檔來指引你如何使用這個 ingress。這對於大部分剛接觸 K8S 的人或者創業公司來說,Nginx ingress 確實是一個非常好的選擇。

但是當 Nginx ingress 在一些大環境上使用時,就會有非常多的問題。第一個,Nginx ingress它用了一些 OpenResty 的特性,但最終配置加載還是依賴於原有的 Nginx config reload。當路由配置非常大的時候,Nginx reload 會耗時非常久,可以達到幾秒甚至十幾秒,這種 reload 會很嚴重的影響業務,甚至造成業務中斷,這是第一個問題。

第二個問題是 Nginx ingress 的插件開發非常困難,如果你覺得 Nginx ingress 本身插件夠用,那還是可以用的。但如果想用一些定制化的插件,比如像阿里雲的IM鑒權,或者是騰訊雲的 KM 鑒權都需要進行額外的開發。Nginx ingress 開發插件非常痛苦,額外開發就非常麻煩,所以 Nginx ingress 的插件能力和可擴展性是比較差的。

Ingress 選型原則

既然發現了 Nginx ingress 有很多問題,那是不是考慮選擇開源的更好用的 ingress,市場上說比 K8S ingress 好用的起碼有十幾家。如何從這么多 ingress 中選擇適合自己的,這讓人感到困擾。

Ingress 最終是基於 HTTP 網關的,市面上 HTTP 網關主要有這么幾種。比如 Nginx、Golang 原生的以及新崛起的 Envoy 這些網關。但是每個開發人員所擅長的技術棧不同,例如我對 Nginx 比較熟悉,但有些人對 HAproxy 更加熟悉,或者有些人對新興的 Envoy 這個網關更加熟悉。因為每個人熟悉的底層網關不一樣,所以適合的 ingress 也會不一樣。

那么問題來了,我們如何選擇一個更加好用的 ingress 呢?或者縮小點范圍,熟悉 Nginx 或 OpenResty 的開發人員,應該選擇哪一個 ingress 呢?

下面來介紹一下我對 ingress 控制器選型的一些經驗。

基本特點

圖中的這些我覺得是基本功能,這些功能必須要有。如果連這些功能都沒有,那完全可以直接pass。

  • 必須開源的,不開源的無法使用

  • K8S 中 Pod 變化非常頻繁,服務發現非常重要

  • 現在 HTTPS 已經很普及了,TLS 或者 SSL 的能力也非常重要,比如證書管理的功能

  • 支持 WebSocket 等常見協議,在某些情況下,可能還需要支持 HTTP2 、QUIC 等

基礎軟件

前面有提到,每個人擅長的技術平台不一樣,所以選擇自己更加熟悉的 HTTP 網關也顯得至關重要。比如 Nginx、HAProxy、Envoy 或者是 Golang 原生網關。因為你熟悉它的原理,在使用中可以更快落地。

在生產環境上,高性能是一個很重要的點,但比之更重要的是高可用。這意味着你選擇的網關,它的可用性、穩定性一定要非常強,只有這樣,服務才能穩定。

功能需求

拋開上述兩點,就是公司業務對網關的特殊需求。你選擇一個開源產品,最好肯定是開箱能用的。比如你需要 GRPC 協議轉換的能力,那當然希望選的網關直接支持這個功能。而肯定不希望去選擇還需要開發的網關。這里簡單列一下影響選擇的點:

  • 協議上是否支持 HTTP2、HTTP3;

  • 負載均衡算法上,最基本的WRR,或者是一致性哈希這種負載均衡算法是否足夠,還是需要更加復雜的類似EWMA負載均衡算法。

鑒權限流上,簡單的鑒權是否足夠,還是說需要更進階的鑒權方式,或者要集成,或者很方便的能開發像阿里雲、騰訊雲的 IM 鑒權。前面我們有提到K8S ingress主要有這么些缺點,比如說 Nginx reload 的問題,插件擴展能力比較弱。其實它的后端節點調整權重的能力也不太好。

選擇 APISIX 作為 Ingress controller

這里就要推薦一下 APISIX,它有非常強大的路由能力,插件能力也非常靈活。雖然它在功能上比 Kong 會少很多,但是 APISIX 很好的路由能力、靈活的插件能力,以及本身的高性能,能夠彌補在 ingress 選型上的一些缺點。如果你們是基於 Nginx 或 Openresty 的開發人員,又對現在的 ingress 不滿意,我推薦你們去使用 APISIX 作為 ingress。

如何將 APISIX 作為 ingress 呢?我們先要做出一個區分,ingress 是 K8S 名稱的定義或者規則定義,ingress controller 是將 K8S 集群狀態同步到網關的一個組件。但 APISIX 本身只是 API 網關,怎么把 APISIX 實現成 ingress controller 呢?我們先來簡要了解一下如何實現 ingress。

實現 ingress,本質上就是兩點。第一點,需要將 K8S 集群中的配置,或者 K8S 集群中的狀態同步到 APISIX 集群。第二點,需要將 APISIX中 的一些概念,比如像服務、upstream 等概念定義為 K8S 中的 CRD。實現了第二部分的話,通過 K8S ingress 的配置,很快的去產生 APISIX,通過 APISIX ingress controller 就會產生 APISIX 相關的配置。我們當前為了快速的將 APISIX 落地為能夠支持 K8S 的 ingress 。我們創建了一個開源項目,叫 ingress controller。

項目的架構大概是這樣。左邊是 K8S 的集群,這里可以導入一些 yaml 文件,對 K8S 進行配置上的變更。右邊則是 APISIX 集群,以及它的控制面和數據面。在這里,APISIX Ingress 充當這兩個 K8S 集群以及 APISIX 集群之間的連接者。它主要是監聽 K8S 集群中節點的變化,去將集群中的狀態同步到 APISIX 集群。另外,K8S 倡導所有組件都要高可用,所以 APISIX Ingress 設計之初,也考慮到它的高可用。我們通過雙節點或多節點的模式,來實現 APISIX ingress controller 的高可用。

各種 Ingress 橫向對比

相對於市面上流行的 ingress 控制器,我們簡單對比來看看 APISIX ingress 有什么優缺點。上圖是外國開發人員針對 K8S ingress 選型做的一張表格。我在原來表格的基礎上,結合自己的理解,將 APISIX ingress 的功能加入了進來。我們可以看到,最左邊的是APISIX,后邊就是 K8S ingress 和 Kong Ingress,后面的 Traefik,就是基於 Golang 的 ingress。HAproxy 是比較常見的,過去是比較流行的負載均衡器。Istio 和 Ambassador 是國外非常流行的兩個ingress。

我們可以簡單聊一下這些 ingress。首先說下 APISIX ingress,APISIX ingress 的優點前面也說到了,它有非常強大的路由能力,性能非常強,也有非常靈活的插件拓展能力。APISIX 剛開源沒幾個月,就已經有非常多的功能。但是它的缺點也非常明顯,APISIX 有非常多的功能,但是缺少落地案例,沒有文章去教大家如何將這些功能都給用起來。

第二個就是我前面吐槽了很多的 K8S ingress,也是那個 K8S 推薦的 Nginx Ingress。它的主要優點前面也說了,簡單、易接入。但缺點就非常明顯,Nginx reload根本就沒有解決,插件是很多的,但插件擴展能力是非常弱的。

我們再說第三個,Nginx ingress主要優點是在於它對 TCP 和 UDP 協議的完全支持,但是其他的,比如像鑒權方式,或者流量調度,這個功能都是非常缺失的。

Kong 本身是一個 API 網關,他也算是開創了先河,將 API 網關引入到 K8S 中當 ingress。另外對於邊緣網關,大家還是有很多需求的,比如說像鑒權、限流、灰度部署等能力。Kong 在這些方面做的非常好。另外 Kong ingress 還有一個非常大的優點,他提供了一些 API、服務的定義,去抽象成 K8S 的 CRD,所以可以很方便地通過 K8S ingress 配置,去同步到 Kong 的集群。雖然 Kong 有很多優點,但 Kong 也有一個非常大的缺點,那就是部署特別困難,另外他的高可用,與 APISIX 相比也是相形見絀。

Traefik 是基於 Golang 的 ingress,它本身是一個微服務網關,但是在 ingress 的場景應用比較多。他的主要平台是基於 Golang,自身支持的協議也非常多,總體來說是沒有什么缺點。如果大家熟悉 Golang 的話,也推薦一用。

HAproxy,是一個久負盛名的負載均衡器。它主要優點是有非常強大的負載均衡能力,其他方面並不占優勢。

Istio ingress 和 Ambassador ingress 都是基於最近非常流行的 envoy。說實話,我覺得這兩個 ingress 沒有什么缺點,可能唯一的缺點是他們基於 envoy 平台,大家對這個平台都不是很熟悉,上手門檻會比較高。

騰訊雲 CLB ingress

前面主要說了開源中的一些 ingress,現在再來說一下 ingress 在騰訊雲的落地情況。前面提到的,像 K8S APISIX,或者是 ingress,他們都是開源的。K8S 跟 ingress,它們都是相互對應的。要聊騰訊雲中的 ingress,自然要先去了解騰訊雲中的 K8S 是什么。所以我先簡要介紹一下騰訊雲的 TKE,也就是騰訊雲的 K8S 平台,然后再是騰訊雲 ingress 的落地情況,它是集成了 CLB 來完成了 ingress 的功能。

上圖是當前騰訊雲的 TKE 平台的整體縱覽,主要由用戶接入層、核心功能,和整合產品三方面組成,整合產品將 Iaas 層和 PaaS 層進行了一些整合。

TKE 的全稱是 Tencent Kubernetes Engine,是⼀個⾼度可擴展的⾼性能容器管理服務。最核心的是 TKE 解決了多租戶的問題,K8S 本身是單租戶的,怎么在騰訊雲上變成多租戶的場景呢?我們花了很長的時間去改造它。其次,在 K8S 節點內,解決了其他一些問題。我們采用了騰訊雲的 VPC 的方案,解決了 Service 和 Pod 之間的通信問題。另外,內部網絡集成了 vpc 的能力,對外網絡集成 CLB 的負載均衡能力,硬盤存儲上集成 CBS 的存儲能力等等,最終實現了騰訊雲 K8S 的公有雲版。當前 TKE 在騰訊雲上差不多有 200 萬的狀態吧。

CLB 是怎么樣的?上圖是騰訊雲 CLB ingress 的整體架構圖。因為我想從高性能、高可用的角度來講我們的 ingress 集群,所以把 K8S 這塊做了簡化,只留了用戶操作,API Server 以及控制器這些。

TKE 需要將 ingress 集成,只需將原有負載均衡的概念,去抽象成 K8S 中一些 CRD 的源語,然后就可以進行映射。比如創建 ingress 或者節點進行調度的時候,我們都可以通過調用 CLB 的接口去更新狀態,完成整個 ingress 鏈路。

接下來就聊一下騰訊雲 CLB 的高性能與高可用。因為后台服務最關注的也是這兩點。

高性能

高性能網關主要說兩部分,一是數據面,二是控制面。我們先說數據面,數據面這邊的話,我們做的七層 CLB 主要是基於 Nginx。為了保證高性能,第一步就是要對 Nginx 進行優化。第二步優化是負載均衡,負載均衡最重要的就是 HTTPS 的能力,HTTPS 其實是非常消耗 CPU的。開源界里,HTTPS 的的優化空間非常大。舉個例子,就比如開源 Nginx,我記不大清是八核還是四核,可以很輕松的達到10萬 KBS。但是一旦用了 HTTPS 后,可能連 1 萬 KBS 都達不到。所以 HTTPS 是有很大優化空間的。我們在做七層高性能時,花了很多時間去優化這塊。怎么優化呢?百度搜一下 Nginx 常見的優化,結果里出現的,基本上都能優化,當然我們還做了另外一些細節上的優化。

第二部分是協議層上的優化,主要是對 HTTPS 協議本身的優化,這包含很多,包括加密協議、open ssl 庫等,我們都做了一些優化。另外還有 HTTP2 協議的優化,HTTP2 是默認開啟 TLS 加密的,所以也繞不過 HTTPS 協議的優化。

第二方面,我們做了很多控制面的的優化。前面已經提了很多次,只要用 Nginx,肯定避免不了 Nginx reload 的問題。只有幾條路由時,可能沒有問題。但是當有幾千條、幾十萬條路由配置時,如果用 Nginx reload 至少要花十幾秒,這對業務中斷影響非常嚴重,完全不能接受。那該怎么辦呢?我們作為一個雲廠商,客戶不僅僅在 upsteam這 塊,在后台節點的變化也非常快,而且客戶是共享集群,非常多的客戶可能都在操作規則,例如操作 Nginx Server。所以我們又做了動態 Server 的優化。在完成 upstream 和動態 Server 這兩個優化后,對於 99.9% 的規則,基本上都可以通過 Nginx 動態 Server 以及 Nginx 動態 upstream 來解決配置加載、變更,而不需要再去經歷 Nginx reload,這是我們控制面的優化。

高可用

高可用也分兩方面,一是控制集群,也就是控制面的高可用,二是數據面的高可用。我們先來說數據面的高可用。

數據面的高可用,主要是如上圖的鏈路。四層網關與七層網關,七層網關與后端節點之間,其實他們都有專門的心跳探測,有熔斷機制、超時能力等來保證高可用。比如發現某些節點有問題時,我會去剔除該節點。但也會去定時的撥測,一旦該節點恢復狀態之后,會再將節點去加回來,這是第一方面,數據面的高可能主要通過心跳探測。

第二方面的話,也就是網關的跨可用區容災。我們也做了一個 7 層網關與 4 層網關的跨可用區容災比如當某一個機房的網關完全掛掉之后,我們依然可以提供一個高可用、高性能的服務。控制面的話這個主要是通過 master agent 集群化的模式來保證高可用。

騰訊雲未來的 Ingress——APISIX

說了 CLB ingress 的架構,看起來確實挺美好的,高可用,性能也非常好,那么它的缺點呢?其實它也是有一些缺點的。

第一,雖然前面說通過動態 upstream 和動態 Server 可以解決掉 99.9% 的配置變更問題,而不需要走 Nginx reload。但是本質上沒有解決配置變更的一些問題,尤其是在一些突發或者后端節點比較多的情況下出現問題。因為過去的后端節點最多也就幾十個,但是當 Docker 化時,后端節點很容易達到上千個甚至上萬個。這時很容易觸發動態 upstream 的域值,讓本來應該走動態 upsteam 的,最終去走了 Nginx reload,這會產生非常嚴重的性能問題。

第二,CLB ingress 所有的邏輯、附加功能都是基於 Nginx,比如像 ACL 限流等都是通過 Nginx 模塊來開發的。這樣的話,首先開發門檻會非常高,其次開發效率也比較低。

我們對負載均衡的要求並不高。比如對負載均衡的主要要求,一是七層網關性能一定要好,二是 HTTPS 協議的支持能力一定要好,三是支持更多協議。但是對於 K8S ingress 的要求就不滿足了,因為 K8S 有很多節點,我更希望有一個很好用的灰度能力。現在的 CLB,是滿足不了定制化的灰度發布需求。所以,通過 TKE 集成了 CLB 負載均衡的能力,當作一個 ingress,只是到了能用的級別,但並沒有完全的去貼合 K8S 平台的需要。

當前 CLB ingress 主要存在的問題就是這些。灰度能力比較弱,也很容易觸發 Nginx reload,從而影響業務,除了這兩點,還有就是隔離性非常差。CLB 的這種部署方式,依然還是很多客戶共用一組 ingress。客戶與客戶之間,其實是會互相影響的。而 K8S 的設計理念是希望客戶能夠獨占 ingress,不希望客戶與客戶之間的 ingress 會互相影響。我們想要解決上述的問題,恰巧遇見了 APISIX 這個項目。

APISIX 的優勢是性能好,這里就不贅述了。另外 APISIX 插件能力靈活,可以支持在更多位置去插入插件。並且,APISIX 是從雲原生角度去設計的,這意味着 APISIX 非常適合在容器中部署,不像過去的 CLB 在物理機上部署還好,但是在容器上部署,控制面架構就非常不適合。而 APISIX 的控制架構,我們可以非常輕松地選擇是讓客戶去共用一組 ingress,還是每個客戶有自己獨占的 ingress。APISIX 在這三個方面都做的非常好,最終我們打算去落地 APISIX ingress 去替代 TKE 平台中的 ingress。

最后總結一下,雖然主要是聊 ingress 選型。前面其實就講到了 ingress 的定位,如何去選擇 ingress,選型要考慮哪些問題。后面將 APISIX ingress 與當前開源的一些 ingress 做了橫向對比,讓大家了解各個 ingress 的優劣勢,方便后續選型時能夠快速選擇適合自己的 ingress。最后簡要介紹了我們騰訊雲的 CLB ingress,以及它當前存在的問題和下一步計划。

推薦閱讀

3 分鍾帶你深入了解 Cookie、Session、Token

又拍雲邵海楊:基於 OpenResty 的動態服務路由方案


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM