為什麼 APISIX Ingress 是比 Ingress NGINX 更好的選擇?

Apache_APISIX發表於2023-01-17
作者容鑫,API7.ai 雲原生技術工程師,Apache APISIX Committer。

本文將會對比兩個比較流行的 Ingress controller 實現,希望能對讀者進行 Ingress controller 選型中有所幫助。

Ingress NGINX 是 Kubernetes 社群實現的 Ingress controller,在社群中被廣泛使用。Apache APISIX Ingress 則是 Apache 軟體基金會下的開源專案,使用 APISIX 作為資料面的 Kubernetes Ingress controller。

Ingress NGINX vs APISIX Ingress

功能對比

下列表格中,對比了 Ingress NGINX 和 APISIX Ingress 基本功能,包括協議支援、鑑權方式、上游探針/策略、負載均衡策略、Kubenertes 整合等。以下表格資料取自 learnk8s.io

Product/Project Ingress NGINXApache APISIX Ingress
1. General info
Based onnginxnginx
2. Protocols
HTTP/HTTPS✔️✔️
HTTP2✔️✔️
gRPC✔️✔️
TCPPartial✔️
TCP+TLS✖︎✔️
UDPPartial✔️
Websockets✔️✔️
Proxy Protocol✔️✔️
QUIC/HTTP3PreviewPreview
3. Clients
Rate limiting (L7)✔️✔️
WAF✔️Partial
Timeouts✔️✔️
Safe-list/Block-list✔️✔️
Authentication✔️✔️
Authorisation✖︎✔️
4. Traffic routing
Host✔️✔️
Path✔️✔️
Headers✔️✔️
Querystring✔️✔️
Method✔️✔️
ClientIP✔️✔️
5. Upstream probes/resiliency
Healthchecks✖︎✔️
Retries✔️✔️
Circuit Breaker✖︎✔️
6.Load balancer strategies
Round robin✔️✔️
Sticky sessions✔️✔️
Least connections✖︎✔️
Ring hash✔️✔️
Custom load balancing✖︎✔️
7. Authentication
Basic auth✔️✔️
External Auth✔️✔️
Client certificate - mTLS✔️✔️
OAuth✔️✔️
OpenID✖︎✔️
JWT✖︎✔️
LDAP✖︎✔️
HMAC✖︎✔️
8. Observability
Logging✔️✔️
Metrics✔️✔️
Tracing✔️✔️
9. Kubernetes Integration
StateKubernetesKubernetes
CRD✖︎✔️
ScopeClusterwide
namespace
namespace
Support for the Gateway API✖︎Preview
Integrates with service meshes✔️✔️
10. Traffic shaping
Canary✔️✔️
Session Affinity✔️✔️
Traffic Mirroring✔️✔️
11. Other
Hot reloading✔️✔️
LetsEncrypt Integration✔️✔️
Wildcard certificate support✔️✔️
Configure hot reloadingPreview✔️
Service Discovery✔️

功能差異

透過下圖,可以粗略看到 APISIX Ingress 內建的功能和特性相比 Ingress NGINX 更加豐富,其中包括服務發現、協議支援、認證鑑權等等。

功能差異

服務發現

在微服務架構中,應用被拆分為很多微服務,無論是微服務故障,還是對應用服務進行擴縮容,都需要儘快的通知到呼叫方,以免呼叫失敗。因此,在微服務架構中,服務註冊和發現機制就顯得很重要了,通常這會透過註冊中心來完成。

Service DiscoveryIngress NGINXApache APISIX Ingress
Kubernetes✔️✔️
DNS✔️
nacos✔️
exureka✔️
consul_kv✔️

協議支援

兩者都對 HTTP/HTTPS 協議提供完整支援,APISIX Ingress 在協議支援上更豐富一些,能夠的使用 TLS 來加密 TCP 流量,還支援 MQTTDubboKafka 等協議進行代理。

服務治理能力

健康檢查

在後端節點故障或者遷移時,不可避免會出現節點不可用的情況。如果大量請求訪問到了這些不可用的節點時,將會造成流量損失,導致業務中斷。因此,需要對節點進行健康檢查,透過探針的形式探測後端節點的可用性,將請求代理到健康的節點,從而減少或避免流量損失。

健康檢查的能力在 Ingress NGINX 中尚未支援,而 APISIX Ingress 提供了該能力,其中包括:

  • 主動健康檢查:確保後端服務中的 Pod 處於可用的狀態。在應用服務進行滾動更新時,會牽扯大量的節點進行更新,不健康的節點將會被負載均衡器忽略,開啟健康檢查能夠有效的挑選出可用的 Pod,避免流量損失。
  • 被動健康檢查:被動的方式無需發起額外的探針,每個請求就是探針,若一個健康節點連續 N 個請求都被判定為失敗(取決於如何配置),則該節點將被標記為不健康。由於無法提前感知節點的狀態,可能會有一定量的失敗請求,在滾動更新時這種情況會相對常見,可以透過服務降級來避免失敗的請求量。

如下是 APISIX Ingress 為 httpbin 服務配置健康檢查示例:

apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
name: httpbin
spec:
healthCheck:
passive:
unhealthy:
httpCodes:
- 500
httpFailures: 3
active:
type: http
httpPath: /healthz
healthy:
successes: 3
interval: 2s
httpCodes:
- 200

服務熔斷

流量高峰時,閘道器作為流量入口向後端服務發起呼叫,後端服務有可能會產生呼叫失敗(超時或者異常),失敗時不能讓請求堆積在閘道器上,需要快速失敗並返回回去,這就需要在閘道器上進行熔斷。

服務熔斷的功能在 Ingress NGINX 中尚未支援。在 APISIX Ingress 中則可以透過 api-breaker 熔斷外掛來實現。

具體使用配置示例如下:

apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpbin-route
spec:
http:
- name: rule1
match:
hosts:
- httpbin.org
paths:
- /status/*
backends:
- serviceName: httpbin
servicePort: 80
plugins:
- name: api-breaker
enable: true
config:
break_response_code: 502
unhealthy:
http_statuses:
- 505
failures: 2
healthy:
http_statuses:
- 200
successes: 2

外掛和鑑權方式

目前 Ingress NGINX 主要透過 AnnotationsConfigMap 等方式進行配置,支援的外掛功能比較有限。如果想要使用 JWT、HAMC 等鑑權方式,只能自行開發。

而 APISIX Ingress 得益於 APISIX 的豐富功能,原生支援 APISIX 內建的 80+ 外掛,能夠覆蓋大部分使用場景,還支援 JWT、HMAC、wolf-rbac 等多種鑑權方式。以下僅展示 APISIX Ingress 使用 HMAC 認證並在路由上的應用示例:

apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
name: hmac-value
spec:
authParameter:
hmacAuth:
value:
access_key: papa
secret_key: fatpa
algorithm: "hmac-sha256"
clock_skew: 0
 
---
 
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpbin-route
spec:
http:
- name: rule1
match:
hosts:
- httpbin.org
paths:
- /ip
backends:
- serviceName: httpbin
servicePort: 80
authentication:
enable: true
type: hmacAuth

Ingress NGINX 和 APISIX Ingress 的擴充套件方式

除了以上這些細節對比外,兩者對於額外功能的擴充套件也有所不同。當 Ingress controller 的基礎功能無法滿足企業使用者的需求時,只能透過擴充套件的方式進行定製開發。接下來將具體介紹 Ingress NGINX 和 APISIX Ingress 如何進行功能擴充套件。

Ingress NGINX 如何進行功能擴充套件

Ingress NGINX 在擴充套件方式上比較單一,只能透過嵌入 Lua 程式的方式來擴充套件功能。我們以 Ingress NGINX 外掛開發為例,大概需要以下步驟:

  1. 編寫 Lua 程式 example-plugin
  2. 將外掛安裝到 ingress-nginx pod 中的 /etc/nginx/lua/plugins/<your plugin name>/etc/nginx/lua/plugins/example-plugin
  3. 在 ConfigMap 中啟用 example-plugin 外掛,需要在安裝 Ingress NGINX 時引用此 ConfigMap 物件
apiVersion: v1
kind: ConfigMap
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
data:
plugins: "example-plugin"

APISIX Ingress 如何進行功能擴充套件

APISIX Ingress 提供了多種擴充套件方式,企業使用者可以根據自身情況自由選擇或組合,當前支援如下擴充方式:

  • 透過 Lua 進行外掛開發:這種方式相對簡單,並且幾乎沒有效能損耗;
  • 透過 plugin-runner 開發:這種模式下支援 Java/Python/Go 等語言進行開發,這可以方便使用者利用一些現有的業務邏輯,並且無需學習新語言;
  • 透過 WASM 進行外掛外掛:這種模式下,可以使用任何支援構建出 WASM 的語言進行外掛開發;

此外還可以透過 Serverless 外掛來直接編寫 Lua 程式碼,快速滿足業務需求。

為什麼 APISIX Ingress 選擇維護 CRD

目前 APISIX Ingress 支援三種宣告式配置:Ingress 、CRD 和 Gateway API。這裡主要對比 Ingress 和 CRD,Gateway API 將在後續展開。

Ingress 比較適合從 Ingress NGINX 遷移的企業使用者,其轉換成本較低。但缺點也較明顯,比如語義化能力弱、沒有細緻規範等,同時也只能透過 Annotations 方式擴充套件,且 Annotations 無法支撐複雜配置場景。相對的使用 CRD 主要有以下好處:

  • 更契合資料面的設計語義,更加簡單易用;
  • 一些重要配置能夠被複用,而不會存在冗餘龐大的單個配置;
  • 功能性和可擴充套件能力有了巨大提升;
  • 資料面 APISIX 有著活躍的社群,更新和釋出版本快,CRD 的方式能夠輕易支援資料面的更多能力;

Ingress NGXIN 的痛點:不支援配置熱載入

靜態配置帶來的問題

Ingress NGINX 主要基於 NGINX 配置檔案的方式,儘管使用 NGINX + Lua 來實現功能擴充套件,但沒有徹底解決靜態配置檔案的問題。在路由能力和載入模式上稍顯不足,並且存在一些明顯劣勢。

比如新增、修改任何新的規則時,需要重新載入 NGINX 配置。隨著越來越多的路由規則和證照,在觸發變更時,reload 操作將會更耗時,甚至需要幾秒到十幾秒的時間,對線上流量的影響將會非常大的,會導致流量短暫中斷、影響響應延遲、負載均衡質量(每次重新載入 NGINX 都會重置負載均衡狀態)等。

觸發 NGINX 重新載入的情況

以下這些情況,涵蓋了 Ingress controller 大量的使用場景:

  • 建立新的 Inresss 資源;
  • 將TLS 部分新增到現有 Ingress;
  • Ingress Annotations 的變化可能影響上游配置(例如 load-balance 註釋不需要重新載入);
  • 在 Ingress 中新增或刪除 path;
  • Ingress、Service、Secret 資源被刪除;
  • Secret 發生更新;

在上述場景下,具有頻繁部署應用程式的叢集環境中,會不斷觸發 Ingress、Secret 等資源的操作(建立、更新、刪除等),導致 NGINX 重新載入次數劇增,給生產環境帶來了極大的影響。

小結

Ingress NGINX 的架構決定了它必須生成 NGINX 配置然後透過 reload 方式完成配置更新,架構不調整是無法解決這些已知問題。比如路由的實現,APISIX Ingress 則不再依賴 NGINX 配置改為了純記憶體結構,透過熱更新方式實現動態路由,不再需要重啟 NGINX。

雲原生新一代閘道器規範 Gateway API

Gateway API 優勢

Gateway API 相比 Ingress 的功能性更強,旨在透過由許多供應商實現並具有廣泛行業支援的富有表現力、可擴充套件和麵向角色的介面來發展 Kubernetes 服務網路。當下 Gateway API 具有如下的優勢:

  • 面向角色:Gateway 是由一組 API 資源組成的。不同的 API 資源代表了使用與配置 Kubernetes 網路資源的不同角色;
  • 表現力強:Gateway API 的核心功能就包含諸如基於頭的匹配、流量加權以及其他在 Ingress 中只能透過各實現者自定義的非標準化 Annotations 等方式實現的功能;
  • 可擴充套件:Gateway API 允許不同資源在不同層級一同使用。這使得能夠對 API 結構進行更精細化的控制。

支援情況

Gateway API 作為一種擴充套件 Kubernetes 服務網路的標準,其 Gateway 資源能夠實現作為 Kubernetes API 來管理閘道器的生命週期,功能十分強大。目前許多 Ingress controller 都在積極支援它,包括 Istio、Kong、Traefik 等。在目前 Gateway API 實現情況中,很遺憾的是,Ingress NGXIN 尚未計劃支援 Gateway API 。而 APISIX Ingress 已經支援了 Gateway API 的大部分特性:包括 HTTPRoute、TCPRoute、TLSRoute、UDPRoute 等。

總結

經過 APISIX Ingress 與 Ingress NGINX 的完整對比,我們可以看到兩者基礎功能差異不大,也都具備擴充套件能力。但在微服務的架構中,APISIX Ingress 對服務治理和服務發現的支援更具優勢。

總體來看,兩款開源軟體均非常優秀,Ingress NGINX 主要特點是簡單、易接入,但缺點也十分明顯;APISIX Ingress 作為後來者解決了 NGINX 不支援熱載入的痛點,在擴充套件能力和功能上相比 Ingress NGINX 也具有很大的優勢。從專案發展角度而言,支援 Gateway API 和 CRD 能夠擴充套件和豐富 Ingress controller 基礎能力。

如果讀者正在進行 Ingress controller 選型,傾向於功能豐富和更強的擴充套件能力,推薦使用 APISIX Ingress 。如果只是剛接觸 Ingress controller,沒有更多的功能需求,Ingress NGINX 也是一個比較好的選擇。

相關文章