首頁>技術>

需要注意的是,目前的最新版本是 v2.0.2,截止該版本,要實現上面的灰度釋出、流量複製這些高階功能,只能通過 File Provider 來實現,所以我們不能直接使用前面的 KubernetesCRD Provider 了。

灰度釋出我們有時候也會稱為金絲雀釋出(Canary),主要就是讓一部分測試的服務也參與到線上去,經過測試觀察看是否符號上線要求。

canary deployment

比如現在我們有兩個名為 appv1 和 appv2 的 Nginx 服務,我們希望通過 Traefik 來控制我們的流量,將 3⁄4 的流量路由到 appv1,1/4 的流量路由到 appv2 去,這個時候就可以利用 Traefik2.0 中提供的帶權重的輪詢(WRR)來實現該功能,首先在 Kubernetes 叢集中部署上面的兩個服務。

appv1 服務的資源清單如下所示:(appv1.yaml)

apiVersion: apps/v1kind: Deploymentmetadata: name: appv1 namespace: kube-systemspec: selector: matchLabels: app: appv1 template: metadata: labels: use: test app: appv1 spec: containers: - name: nginx image: nginx ports: - containerPort: 80 name: portv1---apiVersion: v1kind: Servicemetadata: name: appv1 namespace: kube-systemspec: selector: app: appv1 ports: - name: http port: 80 targetPort: portv1

appv2 服務的資源清單如下所示:(appv2.yaml)

apiVersion: apps/v1kind: Deploymentmetadata: name: appv2 namespace: kube-systemspec: selector: matchLabels: app: appv2 template: metadata: labels: use: test app: appv2 spec: containers: - name: nginx image: nginx ports: - containerPort: 80 name: portv2---apiVersion: v1kind: Servicemetadata: name: appv2 namespace: kube-systemspec: selector: app: appv2 ports: - name: http port: 80 targetPort: portv2

直接建立上面兩個服務:

$ kubectl apply -f appv1.yaml$ kubectl apply -f appv2.yaml# 通過下面的命令可以檢視服務是否執行成功$ kubectl get pods -l use=test -n kube-systemNAME READY STATUS RESTARTS AGEappv1-684f8cbc7-b9zm9 1/1 Running 0 2m27sappv2-645d7666b5-qjrjs 1/1 Running 0 37s

由於 WRR 這個功能目前只支援 File Provider,所以我們需要開啟該 Provider 才能使用,這裡需要注意的是由於需要開啟 File Provider,所以我們需要提供一個檔案用於該 Provider 的配置,我們這裡是用在 Kubernetes 叢集中的,所以可以通過一個 ConfigMap 物件,將配置檔案內容掛載到 Traefik 的 Pod 中去,如下所示,我們通過將一個名為 traefik-dynamic-conf 的 ConfigMap 物件掛載到了 /config 目錄下面去,然後通過 --providers.file.filename引數指定配置檔案開啟 File Provider,另外新增 - --providers.file.watch=true 引數可以讓 Traefik 動態更新配置:

...... volumes: - name: config configMap: name: traefik-dynamic-conf containers: - image: traefik:v2.0.2 name: traefik-ingress-lb volumeMounts: - name: config mountPath: /config ports: - name: web containerPort: 80 hostPort: 80 - name: admin containerPort: 8080 hostPort: 8080 args: - --entrypoints.web.Address=:80 - --api.insecure=true - --providers.file.watch=true - --providers.file.filename=/config/traefik-dynamic.toml - --api - --api.debug=true - --api.dashboard=true - --accesslog

完整的 YAML 檔案可以前往 https://github.com/cnych/kubeapp/tree/master/traefik2/canary 獲取。

上面是開啟 File Provider 的配置,接下來需要建立對應的 ConfigMap 物件,首先建立一個名為 traefik-dynamic.toml 的檔案,內容如下所示:

[http] [http.routers] [http.routers.Router0] entryPoints = ["web"] service = "app" rule = "Host(`nginx.qikqiak.com`)" [http.services] [http.services.app] [[http.services.app.weighted.services]] name = "appv1" weight = 3 [[http.services.app.weighted.services]] name = "appv2" weight = 1 [http.services.appv1] [http.services.appv1.loadBalancer] [[http.services.appv1.loadBalancer.servers]] url = "http://appv1/" [http.services.appv2] [http.services.appv2.loadBalancer] [[http.services.appv2.loadBalancer.servers]] url = "http://appv2/"

上面這個配置檔案就是我們需要配置的灰度釋出的規則,建立一個名為 Router0 的路由,在 web 這個入口點上面監聽 Host=nginx.qikqiak.com 這樣的請求,將請求路由給名為 app 的服務,而該服務則將請求路由給了 appv1 這個服務,權重為 3,另外一部分請求路由給了 appv2 這個服務,權重為 1,也就是有 3⁄4 的請求會被路由到 http://appv1/ 這個真實的服務上,這個地址也就是我們 Kubernetes 叢集中的 appv1 這個 Service 物件的 FQDN 地址,當然我們也可以用全路徑(http://appv1.kube-system.svc.cluster.local:80)表示,因為都在 kube-system 這個名稱空間下面,所以直接用服務名也是可以的,同樣的另外的 1⁄4 請求會被路由到 http://appv2/ 這個真實的服務上。

現在通過上面的配置檔案來建立對應的 ConfigMap 物件:

$ kubectl create configmap traefik-dynamic-conf --from-file=traefik-dynamic.toml -n kube-system

建立完成後,再更新 Traefik2.0,就可以將配置檔案通過 ConfigMap 掛載到 Traefik Pod 的 /config/traefik-dynamic.toml 路徑下面去了。

然後將域名 nginx.qikqiak.com 解析到 Traefik 所在的 Pod,這個時候我們開啟兩個終端,分別去觀察 appv1 和 appv2 兩個應用的日誌。

在瀏覽器中連續訪問 nginx.qikqiak.com 4 次,我們可以觀察到 appv1 這應用會收到 3 次請求,而 appv2 這個應用只收到 1 次請求,符合上面我們的 3:1 的權重配置。

traefik2 wrr demo

不知道是否是 Traefik 的 BUG,同時將 KubernetesCRD Provider 和 File Provider 開啟的時候,識別不了 File Provider 中的配置,該問題還有待驗證。

最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Airtest-UI,自動化集大成者