Apache APISIX Ingress Controller 中的流量切分


流量切分(traffic split)是指將流量按照定義好的規則和比例分攤到多個後端服務,像常見的 API 網關產品(例如 Apache APISIX Traefik )、服務網格 Sidecar Proxy(例如 Envoy linkerd2-proxy ),都提供了流量切分的功能,以此來實現細粒度的 金絲雀發佈 藍綠部署 等功能 。( 文末附鏈接

作爲 Kubernetes 集羣流量入口, Ingress Controller 自然也需要支持流量切分的功能,在後端應用需要發佈時,能夠提供逐步切流,回滾的能力,降低應用發佈帶來的風險。本文先後介紹了 Ingress Nginx Kong Ingress Controller 中提供的流量切分功能(有時也稱爲金絲雀發佈),之後介紹了流量切分在 Apache APISIX Ingress Controller 中的實現。


(注:爲了描述方便,下文用術語 “灰度應用” 表示命中金絲雀發佈規則後對應的後端應用和術語“穩定應用”表示金絲雀發佈規則未命中時對應的後端應用。例如,在下圖中,灰度應用是 “foo-canary”,穩定應用是 “foo”。)


Ingress Nginx

Ingress Nginx 提供了 金絲雀 發佈的功能,我們可以爲 Ingress 資源添加 nginx.ingress.kubernetes.io/canary: "true" 註解來啓用該功能,Ingress Nginx 支持使用以下幾個註解來自定義金絲雀發佈的規則。
 
  • nginx.ingress.kubernetes.io/canary-by-header

通過某個請求頭的值來判斷流量應該被轉發到灰度應用(值爲 always)還是穩定應用(值爲 never)。

  • nginx.ingress.kubernetes.io/canary-by-header-value

該註解擴展了 nginx.ingress.kubernetes.io/canary-by-header,通過判斷指定請求頭的值是否與該註解的值匹配,來決定流量的去向(匹配則轉發到灰度應用,否則轉發到穩定應用)。

  • nginx.ingress.kubernetes.io/canary-by-header-pattern

該註解和 nginx.ingress.kubernetes.io/canary-by-header 類似,只是匹配採用了 PCRE 兼容的正則表達式。

  • nginx.ingress.kubernetes.io/canary-by-cookie

通過 Cookie 中某個字段的值來判斷流量應該被轉發到灰度應用(值爲 always)還是穩定應用(值爲 never)。

  • nginx.ingress.kubernetes.io/canary-weight

爲灰度應用設定一個大小位於 [0, 100] 的權重,流量將按照權重在灰度應用和穩定應用之間分配。權重爲 0 則所有流量都會被轉發到穩定應用;權重爲 100 則所有流量都會被轉發到灰度應用。

下圖的例子將攜帶 User-Agent 頭部匹配 “.*Mozilla.*” 模版,URI path 前綴爲 /get 的請求轉發到灰度應用 foo-canary。


Kong

Kong 提供了金絲雀發佈的 插件 ,並且通過 KongPlugin 這個 CRD 資源將該功能暴露到了 Kong Ingress Controller 中。管理員/用戶首先需要創建一個 KongPlugin 對象,填入金絲雀發佈的規則,然後在目標 Kubernetes Service 中加入註解 konghq.com/plugins 並賦予該對象的名稱;亦或是創建一個 KongClusterPlugin 對象,進而使得該插件在集羣內生效。


上述例子將 foo-canary 這個服務標記爲灰度應用,併爲其建立了一條金絲雀發佈規則,要求 30% 的流量轉發到該應用。


Apache APISIX

Apache APISIX 提供的 traffic-split 插件支持配置自定義規則進行流量切分。Apache APISIX Ingress Controller 在此基礎之上,結合 ApisixRoute 靈活的路由規則配置,將流量切分實現爲了 ApisixRoute 中的第一類功能(無須通過註解定義)。


基於權重

基於權重的流量切分 可以通過爲單條路由規則配置多個 Kubernetes Service 後端來實現,如:

上述示例將 ⅔ 的滿足 Host 爲 foo.org,URI path 前綴爲 /get 的請求轉發到了 foo-canary 這個 service,剩下 ⅓ 的請求將被路由到 foo。

在實際應用中,可以爲灰度應用設定較小的權重,進行小規模的驗證,確認沒有問題後修改 ApisixRoute 資源,逐步放大其權重,最終將流量全部轉發到該灰度應用,完成發佈。

基於規則

ApisixRoute 資源允許用戶添加路由匹配表達式 - Exprs 字段,來自定義路由匹配;此外,單個 ApisixRoute 資源允許插入多條路由規則,因此基於規則的流量切分被 Apache APISIX Ingress Controller 以一種無縫的方式集成。

上述示例,將滿足 Host 爲 foo.org,URI path 前綴爲 /get 的請求,分爲兩部分

  • id 參數是 3, 13, 23, 33 其中之一,這部分請求將命中路由規則 rule2,從而被轉發到 foo-canary 這一服務;
  • 其他請求將命中路由規則 rule1,從而被轉發到 foo 這一服務。


總結

Ingress Nginx 支持基於權重和基於 Header 規則的金絲雀發佈,但是需要通過 annotations 的方式進行配置,語義不強;而 Kong 的方案僅支持基於權重進行金絲雀發佈,某些場景下無法滿足使用需求,且需要多處配置;Apache APISIX Ingress Controller 則較好地同時支持了兩種使用場景,並且其提供的路由規則靈活多變,配置簡單且易於理解。

關於作者

張超(GitHub ID:tokers),深圳支流科技有限公司系統工程師,Apache APISIX PMC,OpenResty貢獻者,開源愛好者,目前專注在雲原生、服務網格等領域。


深圳支流科技有限公司(api7.ai)是一家以開源社區爲依託,專注於驅動企業數字化轉型的公司,同時也是TARS基金會初始會員之一,致力於與TARS基金會一起爲微服務生態建設貢獻力量。



附文中鏈接:

Apache APISIX:

http://apisix.apache.org


Traefik:

https://traefik.io/


Envoy: 

https://envoyproxy.io/


linkerd2-proxy: 

https://github.com/linkerd/linkerd2-proxy


金絲雀發佈:

(1)https://blog.getambassador.io/cloud-native-patterns-canary-release-1cb8f82d371a

(2)https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#canary


藍綠部署:

https://martinfowler.com/bliki/BlueGreenDeployment.html


Kubernetes:

https://kubernetes.io/


Ingress Controller: 

https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/


Ingress Nginx: 

https://kubernetes.github.io/ingress-nginx/


Kong Ingress Controller: 

https://github.com/Kong/kubernetes-ingress-controller


Apache APISIX Ingress Controller: 

https://github.com/apache/apisix-ingress-controller


Ingress: 

https://kubernetes.io/docs/concepts/services-networking/ingress/


PCRE: 

https://www.pcre.org/


Kong金絲雀插件:

https://docs.konghq.com/hub/kong-inc/canary/0.32-x.html


KongPlugin: 

https://docs.konghq.com/kubernetes-ingress-controller/1.1.x/references/custom-resources/


Kubernetes Service: 

https://kubernetes.io/docs/concepts/services-networking/service/


KongClusterPlugin: 

https://docs.konghq.com/kubernetes-ingress-controller/1.1.x/guides/using-kongclusterplugin-resource/


traffic-split: 

http://apisix.apache.org/docs/apisix/plugins/traffic-split


ApisixRoute: 

http://apisix.apache.org/docs/ingress-controller/concepts/apisix_route


Exprs:

https://github.com/apache/apisix-ingress-controller/blob/master/docs/en/latest/concepts/apisix_route.md#advanced-route-features




TARS基金會是Linux基金會下的非營利性、微服務基金會,致力於建設一個強大而靈活的微服務生態系統。無論你在哪個行業,無論你使用什麼技術棧,這裏能助你快速實現你的創意。





點“在看”讓TARS小姐姐變好看

本文分享自微信公衆號 - TARS星球(TarsCloud)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

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