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 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。詳見:https://github.com/kubesphere/kubesphere/blob/v3.2.0/build/ks-controller-manager/Dockerfile#L34
- Gateway 是在 KubeSphere 中定制的 Helm Chart,裡面主要就操作了 Nginx CR 資源。詳見:https://github.com/kubesphere/kubesphere/blob/v3.2.0/config/gateway/templates/nginx-ingress.yaml
- 發起請求建立或更新 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