KubeSphere 網關的設計與實現(解讀)
作者:泓舟子,KubeSphere 後端研發工程師,雲原生愛好者,現專注於雲原生微服務方向。
KubeSphere 中為什麼需要網關?
如果需要將 K8s 集羣內的服務暴露到外部訪問有那些方式呢?可以通過將 Service 設置成 NodePort 方式暴露出去或者通過 Ingress 方式。另外使用 Ingress 方式可以實現將請求分發到一個或多個 Service,可以同一個 IP 地址下暴露多個服務等優勢。
但是對於 Ingress 方式而言,在 K8s 中只是內置了 Ingress CRD(可以創建 Ingress 資源),沒有內置 Ingress Controller,必須部署了 Ingress Controller 才能為 Ingress 資源提供外部訪問集羣內部服務的能力。而 KubeSphere 中的網關就是 Ingress Controller 。
網關的設計
KubeSphere v3.2 對網關進行了重構,在保留了原有網關功能的基礎上增加了以下幾點新功能:
- 啟用集羣和項目級別的網關:可以根據業務上的需求靈活選擇不同粒度的網關。
- 增減網關副本數:靈活調整副本數達到更高的可用性。
- 靈活配置 Ingress Controller 配置選項。
- 可指定網關應用負載安裝的位置:可選擇將網關應用負載安裝的位置指定某固定命名空間或分別讓其位於各自項目命名空間下。結合 KubeSphere 中的權限管理,若讓資源位於各個項目命名空間下,擁有該項目權限的用户也能查看到網關資源。
- 網關日誌:集中查詢網關日誌,將分佈在各個副本的網關日誌集中起來查詢。
- 網關監控指標:監控網關中的一些指標,包括請求總量/成功率/延遲 等指標。
網關的實現
目前 K8s 支持和維護 AWS 、 GCE 和 Nginx Ingress 控制器,KubeSphere 使用 Ingress Nginx Controller 作為默認的網關實現,沒有做任何代碼修改。
各個功能點的實現思路
- 集羣和項目級別的網關:這個通過傳入參數覆蓋默認的 Helm Chart Values 來實現並在代碼邏輯裏控制,如果啟用了集羣網關就不能啟用項目網關了;若啟用了項目網關又啟用了集羣網關,那麼通過兩個網關入口都可以訪問,只是這樣會有兩個 Ingress Controller 同時 Watch 相同的 Ingress 對象。
- 增減網關副本數&配置 Ingress Controller 配置選項:這個通過傳入參數覆蓋默認的 Helm Chart Values 來實現,實現過程用到的 Helm Operator 將在後面重點介紹。
- 可指定網關應用負載安裝的位置:可選擇將網關應用負載安裝的位置指定某固定命名空間或分別讓其位於各自項目命名空間下。這個在代碼邏輯中控制,並做成了配置項,默認將所有資源安裝在 kubesphere-controls-system 下。
- 網關日誌:使用到了 KubeSphere 中日誌組件,日誌組件會採集日誌數據然後存儲在 Elasticsearch 中,網關在查詢日誌過程就根據參數在 Elasticsearch 中查詢日誌。
- 網關監控指標:使用到了 KubeSphere 中監控組件,KubeSphere 內部配置了 Prometheus 相關的參數採集 Ingress 相關指標,查詢監控信息過程就根據監控組件中的 API 查詢相關數據。
下面重點介紹設計實現過程抽象出的 CRD 和如何巧妙地用 Helm Operator 集成。
抽象出 Gateway CRD 做適配
在設計上抽象了一個 Gateway CRD 來適配不同的 Ingress Controller,Gateway CRD 中包含設置 Ingress Controller 所需的公共屬性。KubeSphere API 和 UI 只與 Gateway CRD 交互。
# Gateway sample apiVersion: gateway.kubesphere.io/v1alpha1 kind: Gateway metadata: name: kubesphere-router-proj1 namespace: kubesphere-controls-system # all Gateway workload will be created in the kubesphere-controls-system namespace by default. However, it's configurable in kubesphere-config when calling KubeSphere API. spec: controller: # controlpanel replicas. For ingress Controler that has controlpanel and workers. *Reserved field. Changing on UI isn't supported yet. replicas: 1 # annotations of the controlpanel deployment. *Reserved field. Changing on UI isn't supported yet. annotations: {} # Watching scope, # enabled =true, watching for the project only. The user needs to specify the watching namespace. # enabled =false, Global gateway, watching for all namespaces. scope: enabled: false namespace: "" # defaults to .Release.Namespace # gateway configurations. only key-value pair supported currently. config: max-bucket: 1m # worker workload deployment configuration deployment: annotations: "servicemesh.kubesphere.io/enabled": "false" replicas: 1 # service: # Cloud LoadBalancer configurations for service annotations: "service.beta.kubernetes.io/qingcloud-load-balancer-eip-ids": "test-ip-id" # Service Type, only LoadBalancer and NodePort are supported type: LoadBalancer
集成 Nginx Ingress Controller
KubeSphere 使用 Nginx Ingress Controller 作為默認的網關實現。為了簡化部署步驟,我們集成了 Helm-operator-plugins 作為 Helm Operator 。
在 Helm Operator 中主要有以下關鍵點:
根據 watch.yaml 中配置的監聽指定 CRD 下的 CR 來創建或更新 Chart 資源。其中可以根據 CR spec 中的值覆蓋默認 Helm Chart 中的值,這是由 Helm Operator 中的機制決定的, 詳見官方説明 。
如下的含義是需要 Watch gateway.kubesphere.io/v1alpha1
的 Nginx CR,如果有變化就觸發 Reconcile ,根據 chart 中配置的地址創建或更新對應的資源。
- group: gateway.kubesphere.io version: v1alpha1 kind: Nginx chart: /var/helm-charts/ingress-nginx
在 KubeSphere 中的使用:
watchs.yaml 中就做了如下配置:
- group: gateway.kubesphere.io version: v1alpha1 kind: Nginx chart: /var/helm-charts/ingress-nginx - group: gateway.kubesphere.io version: v1alpha1 kind: Gateway chart: /var/helm-charts/gateway
其中對 chart 而言:
- Nginx 是用的官方的 Helm Chart,在打包 ks-controller-manager 時下載的官方 Helm Chart。詳見: http://github.com/kubesphere/kubesphere/blob/v3.2.0/build/ks-controller-manager/Dockerfile#L34
- Gateway 是在 KubeSphere 中定製的 Helm Chart,裏面主要就操作了 Nginx CR 資源。詳見: http://github.com/kubesphere/kubesphere/blob/v3.2.0/config/gateway/templates/nginx-ingress.yaml
整體而言:
Helm Operator Watch 了 Gateway 和 Nginx 2 個 CRD 的資源,當前端發起創建或更新網關時是對 Gateway CR 發起創建或更新操作:
- 發起請求創建或更新 Gateway CR ;
- 根據 watchs.yaml 配置的 Gateway, Helm Operator 監聽到有 Gateway CR 資源變化,將創建或更新 Nginx CR ;
- 根據 watchs.yaml 配置的 Nginx,Helm Operator 監聽到 Nginx CR 資源變化後就根據 Nginx CR 中的 spec 中的值來覆蓋默認 Helm Chart 中的值來創建或更新 Nginx Ingress Contoller。
配置項的設計
為了方便更改網關的一些參數設計瞭如下配置項:
gateway: watchesPath: /var/helm-charts/watches.yaml repository: kubesphere/nginx-ingress-controller tag: v1.1.0 namespace: kubesphere-controls-system
- watchesPath:指定 Helm Operator Watch 的配置文件,如果需要禁用 Helm Operator 就可以刪掉這個配置項。
- repository:指定 nginx-ingress-controller 的倉庫。
- tag:指定 nginx-ingress-controller 的 tag。
- namespace:指定網關應用負載安裝的位置位於指定的命名空間下,若刪掉這個配置項就會安裝在各個項目命名空間下。
使用過程注意事項
nginx.ingress.kubernetes.io/upstream-vhost: [service-name].[service-namespace].svc.cluster.local
參考:
- http://kubernetes.io/docs/concepts/services-networking/ingress-controllers/
- http://github.com/kubesphere/community/blob/master/sig-microservice/concepts-and-designs/KubeSphere-gateway-operator-design.md
- http://github.com/kubesphere/kubesphere
- http://sdk.operatorframework.io/docs/building-operators/helm/
- 設計模式之狀態模式
- 如何實現數據庫讀一致性
- 我是怎麼入行做風控的
- C 11精要:部分語言特性
- 吳恩達來信:人工智能領域的求職小 tips
- EasyCV帶你復現更好更快的自監督算法-FastConvMAE
- 某車聯網App 通訊協議加密分析(四) Trace Code
- 帶你瞭解CANN的目標檢測與識別一站式方案
- EasyNLP玩轉文本摘要(新聞標題)生成
- PostgreSQL邏輯複製解密
- 基於 CoreDNS 和 K8s 構建雲原生場景下的企業級 DNS
- 循環神經網絡(RNN)可是在語音識別、自然語言處理等其他領域中引起了變革!
- 技術分享| 分佈式系統中服務註冊發現組件的原理及比較
- 利用谷歌地圖採集外貿客户的電話和手機號碼
- 跟我學Python圖像處理丨關於圖像金字塔的圖像向下取樣和向上取樣
- 帶你掌握如何使用CANN 算子ST測試工具msopst
- 一招教你如何高效批量導入與更新數據
- 一步步搞懂MySQL元數據鎖(MDL)
- 你知道如何用 PHP 實現多進程嗎?
- KubeSphere 網關的設計與實現(解讀)