iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 29
0

Canary Deployments

當要使用一部分用戶測試生產中的新部署時,請使用 Canary 部署。因為透過 Canary 部署,可以將更改發布給一小部分用戶,以減輕新版本相關的風險。建立一個範例,該範例是從 googlecodelabs 取得。

$ cat deployments/hello-canary.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: hello-canary
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: hello
        track: canary
        # Use ver 1.0.0 so it matches version on service selector
        version: 1.0.0
    spec:
      containers:
        - name: hello
          image: kelseyhightower/hello:2.0.0
          ports:
            - name: http
              containerPort: 80
            - name: health
              containerPort: 81
...

使用 apply 佈署

$ kubectl create -f deployments/hello-canary.yaml

創建 canary 部署之後,應該有兩個部署,hello 和 hello-canary。使用 kubectl 進行驗證

$ kubectl get deployments
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
auth           1/1     1            1           10m
frontend       1/1     1            1           9m23s
hello          3/3     3            3           9m32s
hello-canary   1/1     1            1           36s

在 hello 服務上,selector 使用 app:hello 選擇器,該 selector 將與 prod 部署和 canary 部署中的 POD 匹配。但是,由於 Canary 部署的 POD 數量較少,因此對較少的用戶可見。

使用 curl 進行驗證

$ curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
$ curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
{"version":"1.0.0"}
$ curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
{"version":"1.0.0"}
$ curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
{"version":"2.0.0"}
$ curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
{"version":"1.0.0"}

運行幾次,應該看到 hello 1.0.0 為某些請求提供了服務,而 2.0.0 為一小部分約 1/4 提供了服務。原理如下圖

可以使用 sessionAffinity: ClientIP 方式讓請求端始終發送到相同版本的應用程式上

Blue-green deployments

滾動更新是理想的選擇,因為它能夠以最小的開銷、性能和最小的停機時間來緩慢的部署應用程序。在某些情況下,只有在完全部署新版本之後,修改負載均衡器以使其指向該新版本是有益的,在這種情況下,必須進行 Blue-green 部署。Kubernetes 透過創建兩個單獨的 Deployment 來實現這一目標。一種用於舊的 blue 版本,另一種用於新的 green 版本,將現有的 hello 部署用於 blue 版本。將透過充當路由器的 Service 來訪問部署,新的 green 版本啟動並運行後,將透過更新 Service 切換到使用該版本。

selector 將匹配現有的 blue 部署。但是它不匹配 green 部署,因為它將使用不同的版本。

kind: Service
apiVersion: v1
metadata:
  name: "hello"
spec:
  selector:
    app: "hello"
    version: 1.0.0
  ports:
    - protocol: "TCP"
      port: 80
      targetPort: 80

green 應用程式佈署

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: hello-green
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: hello
        track: stable
        version: 2.0.0
    spec:
      containers:
        - name: hello
          image: kelseyhightower/hello:2.0.0
          ports:
            - name: http
              containerPort: 80
            - name: health
              containerPort: 81
          resources:
            limits:
              cpu: 0.2
              memory: 10Mi
          livenessProbe:
            httpGet:
              path: /healthz
              port: 81
              scheme: HTTP
            initialDelaySeconds: 5
            periodSeconds: 15
            timeoutSeconds: 5
          readinessProbe:
            httpGet:
              path: /readiness
              port: 81
              scheme: HTTP
            initialDelaySeconds: 5
            timeoutSeconds: 1

因為 Service 關係,因此還是指向 blue。

$ curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
{"version":"1.0.0"}

更新 Service,透過 selector 讓它匹配 green

kind: Service
apiVersion: v1
metadata:
  name: hello
spec:
  selector:
    app: hello
    version: 2.0.0
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

驗證,變為 green 版本

$ curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
{"version":"2.0.0"}

最近在學英文因此寫文章的品質沒那麼好,請見諒。


上一篇
切換群集的 context
下一篇
結束了!!
系列文
我真的覺得認為 K8s 到底在火什麼30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言