宅家學習,如何進行Kubernetes Ingress控制器的技術選型?

導語:在Kubernetes的實踐、部署中,爲了解決 Pod 遷移、Node Pod 端口、域名動態分配等問題,需要開發人員選擇合適的 Ingress 解決方案。面對市場上衆多Ingress產品,開發者該如何分辨它們的優缺點?又該如何結合自身的技術棧選擇合適的技術方案呢?

名詞解釋

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

  • 集羣:是指容器運行所需雲資源的集合,包含了若干臺雲服務器、負載均衡器等雲資源。
  • 實例(Pod):由相關的一個或多個容器構成一個實例,這些容器共享相同的存儲和網絡空間。
  • 工作負載(Node):Kubernetes 資源對象,用於管理 Pod 副本的創建、調度以及整個生命週期的自動控制。
  • 服務(Service):由多個相同配置的實例(Pod)和訪問這些實例(Pod)的規則組成的微服務。
  • Ingress:Ingress 是用於將外部 HTTP(S)流量路由到服務(Service)的規則集合。

Kubernetes現狀

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-SwUl608G-1586938588443)(http://km.oa.com/files/photos/pictures//20200219//1582092075_26.png)]

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

這兩種方案其實各自都存在一些缺點:

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

在Kubernetes的實踐、部署中,爲了解決像 Pod 遷移、Node Pod 端口、域名動態分配,或者是 Pod 後臺地址動態更新這種問題,就產生了 Ingress 解決方案

Nginx Ingress 的缺點

Ingress 是Kubernetes中非常重要的外網流量入口。在Kubernetes中所推薦的默認值爲Nginx Ingress,爲了與後面Nginx 提供的商業版 Ingress 區分開來,我就稱它爲Kubernetes Ingress。

Kubernetes Ingress,顧名思義基於 Nginx 的平臺,Nginx 現在是世界上最流行的 Nginx HTTP Sever,相信大家都對 Nginx 也比較熟悉,這是一個優點。它還有一個優點是 Nginx Ingress 接入 Kubernetes 集羣所需的配置非常少,而且有很多文檔來指引你如何使用它。這對於大部分剛接觸 Kubernetes 的人或者創業公司來說,Nginx Ingress 的確是一個非常好的選擇。

但是當 Nginx Ingress 在一些大環境上使用時,就會出現很多問題:

  • 第一個問題:Nginx Ingress用了一些 OpenResty 的特性,但最終配置加載還是依賴於原有的 Nginx config reload。當路由配置非常大時,Nginx reload 會耗時很久,時間長達幾秒甚至十幾秒,這樣就會嚴重影響業務,甚至造成業務中斷。
  • 第二個問題:Nginx Ingress 的插件開發非常困難。如果你認爲 Nginx Ingress 本身插件不夠用,需要使用一些定製化插件,這個額外的開發任務對程序員來說是十分痛苦的。因爲Nginx Ingress自身的插件能力和可擴展性非常差。

Ingress選型經驗

既然發現了 Nginx Ingress 有很多問題,那是不是考慮選擇其他開源的、更好用的 Ingress?市場上比 Kubernetes Ingress 好用的Ingress起碼有十幾家,那麼如何從這麼多 Ingress 中選擇適合自己的呢?

Ingress 自身是基於 HTTP 網關的,市面上 HTTP 網關主要有這麼幾種:Nginx、Golang 原生的網關,以及新崛起的 Envoy 。但是每個開發人員所擅長的技術棧不同,所以適合的 Ingress 也會不一樣。

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

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

在這裏插入圖片描述

1.基本特點

首先我認爲Ingress 控制器應該具備以下基本功能,如果連這些功能都沒有,那完全可以直接pass。

  • 必須開源的,不開源的基本可以pass
  • Kubernetes 中Pod 變化非常頻繁,服務發現非常重要。
  • 現在 HTTPS 已經很普及了,TLS 或者 SSL 的能力也非常重要,比如證書管理的功能。
  • 支持 WebSocket 等常見協議,在某些情況下,可能還需要支持 HTTP2 、QUIC 等協議。

2.基礎軟件

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

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

3.功能需求

拋開上述兩點,就是公司業務對網關的特殊需求。你選擇一個開源產品,最好肯定是開箱能用的。比如你需要 GRPC 協議轉換的能力,那當然希望選的網關具備這樣的功能。這裏簡單列一下影響選擇的因素:

  • 協議:是否支持 HTTP2、HTTP3;
  • 負載均衡算法:最基本的WRR、一致性哈希負載均衡算法是否能夠滿足需求,還是需要更加複雜的類似EWMA負載均衡算法。
  • 鑑權限流:僅需要簡單的鑑權,或更進階的鑑權方式。又或者需要集成,能夠快速的開發出像騰訊雲 IM 的鑑權功能。Kubernetes Ingress除了前面我們提到的存在Nginx reload 耗時長、插件擴展能力差的問題,另外它還存在後端節點調整權重的能力不夠靈活的問題。

選擇Apache APISIX

相比Kubernetes Ingress,我個人更推薦 APISIX 作爲Ingress controller。雖然它在功能上比 Kong 會少很多,但是 APISIX 很好的路由能力、靈活的插件能力,以及本身的高性能,能夠彌補在 Ingress 選型上的一些缺點。對於基於 Nginx 或 Openresty 開發的程序員,如果對現在的 Ingress 不滿意,我推薦你們去使用 APISIX 作爲 Ingress。

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

實現 Ingress,本質上就只有兩部分內容:

  • 第一部分:需要將 Kubernetes 集羣中的配置、或 Kubernetes 集羣中的狀態同步到 APISIX 集羣。
  • 第二部分:需要將 APISIX中 的一些概念,比如像服務、upstream 等概念定義爲 Kubernetes 中的 CRD。

如果實現了第二部分,通過 Kubernetes Ingress 的配置,便可以很快的產生 APISIX。通過 APISIX Ingress controller 就可以產生 APISIX 相關的配置。當前爲了快速的將 APISIX 落地爲能夠支持 Kubernetes 的 Ingress ,我們創建了一個開源項目,叫 Ingress Controller。

在這裏插入圖片描述

上圖爲Ingress controller 項目的整體架構圖。左邊部分爲 Kubernetes 集羣,這裏可以導入一些 yaml 文件,對 Kubernetes 的配置進行變更。右邊部分則是 APISIX 集羣,以及它的控制面和數據面。從架構圖中可以看出,APISIX Ingress 充當了 Kubernetes 集羣以及 APISIX 集羣之間的連接者。它主要負責監聽 Kubernetes 集羣中節點的變化,將集羣中的狀態同步到 APISIX 集羣。另外,由於Kubernetes 倡導所有組件都要具備高可用的特性,所以在 APISIX Ingress 設計之初,我們通過雙節點或多節點的模式來保證 APISIX Ingress Controller 的保障高可用。

總結

在這裏插入圖片描述

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

  • APISIX Ingress:APISIX Ingress 的優點前面也提到了,它具有非常強大的路由能力、靈活的插件拓展能力,在性能上表現也非常優秀。同時,它的缺點也非常明顯,儘管APISIX開源後有非常多的功能,但是缺少落地案例,沒有相關的文檔指引大家如何使用這些功能。
  • Kubernetes Ingress:即 Kubernetes 推薦默認使用的 Nginx Ingress。它的主要優點爲簡單、易接入。缺點是Nginx reload耗時長的問題根本無法解決。另外,雖然可用插件很多,但插件擴展能力非常弱。
  • Nginx Ingress:主要優點是在於它完全支持 TCP 和 UDP 協議,但是缺失了鑑權方式、流量調度等其他功能。
  • Kong:其本身就是一個 API 網關,它也算是開創了先河,將 API 網關引入到 Kubernetes 中當Ingress。另外相對邊緣網關,Kong 在鑑權、限流、灰度部署等方面做得非常好。Kong Ingress 還有一個很大的優點:提供了一些 API、服務的定義,可以抽象成 Kubernetes 的 CRD,通過K8S Ingress 配置便可完成同步狀態至 Kong 集羣。缺點就是部署特別困難,另外在高可用方面,與 APISIX 相比也是相形見絀。
  • Traefik :基於 Golang 的 Ingress,它本身是一個微服務網關,在 Ingress 的場景應用比較多。他的主要平臺基於 Golang,自身支持的協議也非常多,總體來說是沒有什麼缺點。如果大家熟悉 Golang 的話,也推薦一用。
  • HAproxy:是一個久負盛名的負載均衡器。它主要優點是具有非常強大的負載均衡能力,其他方面並不佔優勢。
  • Istio Ingress 和 Ambassador Ingress 都是基於非常流行的 Envoy。說實話,我認爲這兩個 Ingress 沒有什麼缺點,可能唯一的缺點是他們基於 Envoy 平臺,如果大家對這個平臺都不是很熟悉,上手門檻會比較高。

綜上所述,大家在瞭解了各個 Ingress 的優劣勢後,可以結合自身情況快速選擇適合自己的 Ingress。

題外話

https://github.com/Miss-you/awesome-ingress

半夜睡不着,熬夜把之前整理的一張關於ingress功能對比的表格開源了。

這張表格其實是在2019年11-12月份我依據自己對一些用過的網關的經驗以及基於Comparing Ingress controllers for Kubernetes這篇文章整理的(因爲比如traefik/ambassador等網關,我也沒有足夠的時間來對從未接觸過的這些Ingress做功能以及性能等方面的評估。

另一方面,開源社區的Ingress他們的發展速度非常快,我相信半年後,我的表格可能就跟不上潮流了。

最後也是因爲當我發了這張圖後,有很多同事或者開源社區的朋友私下找我索要這張表格,足以說明我整理的內容的價值。

所以,爲了讓大家在選型Ingress的路上少走彎路,爲了該表格也能夠持續更新,我將這張表格開源出來了,希望大家會喜歡。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章