Kubernetes 中的金絲雀部署 #1:Gitlab CI

我們將使用Gitlab CI和手動GitOps在Kubernetes中實作和使用Canary部署

Kubernetes 中的金絲雀部署 #1:Gitlab CI

本系列文章:

我們將透過 GitOps 手動執行 Canary 部署並建立/修改主要 Kubernetes 資源。 這篇文章主要是為了介紹 Kubernetes Canary 中的部署工作方式,因為有更有效的自動化方法,我們將在下面的文章中考慮這些方法。


Kubernetes 中的金絲雀部署 #1:Gitlab CI

https://www.norberteder.com/canary-deployment/

金絲雀部署

使用金絲雀策略,更新首先僅應用於一部分使用者。 透過監控、日誌資料、手動測試或其他回饋管道,在發布給所有使用者之前對版本進行測試。

Kubernetes 部署(滾動更新)

Kubernetes 部署的預設策略是捲動更新,即使用新版本的映像啟動一定數量的 pod。 如果建立時沒有出現問題,則具有舊版映像的 Pod 將被終止,並並行建立新的 Pod。

Git 操作

我們在本例中使用 GitOps 是因為:

  • 使用 Git 作為單一事實來源
  • 我們使用 Git Operations 進行建置和部署(除了 git tag/merge 之外不需要任何命令)

例子

讓我們採取一種良好的做法 - 擁有一個用於應用程式程式碼的儲存庫和一個用於基礎設施的儲存庫。

應用程式儲存庫

這是一個非常簡單的 Python+Flask API,以 JSON 形式回傳回應。 我們將透過 GitlabCI 建置套件並將結果推送到 Gitlab 註冊表。 在註冊表中我們有兩個不同的發行版本:

  • wuestkamp/k8s-deployment-example-app:v1
  • wuestkamp/k8s-deployment-example-app:v2

它們之間的唯一區別是傳回的 JSON 檔案的變化。 我們使用此應用程式盡可能輕鬆地視覺化我們正在與哪個版本進行通訊。

基礎設施儲存庫

在這個蘿蔔中,我們將透過 GitlabCI 部署到 Kubernetes, .gitlab-ci.yml 如下所示:

image: traherom/kustomize-docker

before_script:
   - printenv
   - kubectl version

stages:
 - deploy

deploy test:
   stage: deploy
   before_script:
     - echo $KUBECONFIG
   script:
     - kubectl get all
     - kubectl apply -f i/k8s

   only:
     - master

要自己運行它,您需要一個集群,您可以使用 Gcloud:

gcloud container clusters create canary --num-nodes 3 --zone europe-west3-b

gcloud compute firewall-rules create incoming-80 --allow tcp:80

你需要分叉 https://gitlab.com/wuestkamp/k8s-deployment-example-canary-infrastructure 並創建一個變數 KUBECONFIG 在 GitlabCI 中,其中將包含存取配置 kubectl 到您的集群。

您可以閱讀有關如何取得叢集 (Gcloud) 憑證的信息 就在這裡.

基礎設施 YAML

在基礎設施儲存庫中,我們有服務:

apiVersion: v1
kind: Service
metadata:
 labels:
   id: app
 name: app
spec:
 ports:
 - port: 80
   protocol: TCP
   targetPort: 5000
 selector:
   id: app
 type: LoadBalancer

並部署在 deploy.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
 name: app
spec:
 replicas: 10
 selector:
   matchLabels:
     id: app
     type: main
 template:
   metadata:
     labels:
       id: app
       type: main
   spec:
     containers:
     - image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v1
       name: app
       resources:
         limits:
           cpu: 100m
           memory: 100Mi

另一個部署在 deploy-canary.yaml:

kind: Deployment
metadata:
 name: app-canary
spec:
 replicas: 0
 selector:
   matchLabels:
     id: app
     type: canary
 template:
   metadata:
     labels:
       id: app
       type: canary
   spec:
     containers:
     - image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v2
       name: app
       resources:
         limits:
           cpu: 100m
           memory: 100Mi

請注意,app-deploy 尚未定義任何副本。

執行初始部署

要開始初始部署,您可以在 master 分支上手動啟動 GitlabCI 管道。 在那之後 kubectl 應輸出以下內容:

Kubernetes 中的金絲雀部署 #1:Gitlab CI

我們看 app 部署有 10 個副本,app-canary 有 0 個副本。還有一個 LoadBalancer,我們可以透過它來存取 curl 透過外部IP:

while true; do curl -s 35.198.149.232 | grep label; sleep 0.1; done

Kubernetes 中的金絲雀部署 #1:Gitlab CI

我們看到我們的測試應用程式僅返回“v1”。

執行金絲雀部署

步驟1:為部分用戶發布新版本

我們在deploy-canary.yaml檔案和新版本鏡像中將副本數設為1:

kind: Deployment
metadata:
 name: app-canary
spec:
 replicas: 1
 selector:
   matchLabels:
     id: app
     type: canary
 template:
   metadata:
     labels:
       id: app
       type: canary
   spec:
     containers:
     - image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v2
       name: app
       resources:
         limits:
           cpu: 100m
           memory: 100Mi

在文件中 deploy.yaml 我們將副本數量更改為 9:

kind: Deployment
metadata:
 name: app
spec:
 replicas: 9
 selector:
   matchLabels:
     id: app
...

我們將這些變更推送到將啟動部署的儲存庫(透過 GitlabCI)並查看結果:

Kubernetes 中的金絲雀部署 #1:Gitlab CI

我們的服務將指向這兩個部署,因為兩者都有應用程式選擇器。 由於 Kubernetes 的預設隨機化,我們應該看到約 10% 的請求有不同的回應:

Kubernetes 中的金絲雀部署 #1:Gitlab CI

我們的應用程式(GitOps,取自 Git 作為單一事實來源)的當前狀態是存在兩個具有活動副本的部署,每個版本一個。

大約 10% 的用戶熟悉新版本並無意中測試它。 現在是檢查日誌和監控資料中是否有錯誤以發現問題的時候了。

步驟2:向所有使用者發布新版本

我們認為一切都很順利,現在我們需要向所有用戶推出新版本。 為此,我們只需更新 deploy.yaml 安裝新版本的鏡像,副本數等於 10。 deploy-canary.yaml 我們將副本數設定回0。部署後,結果如下:

Kubernetes 中的金絲雀部署 #1:Gitlab CI

總結

對我來說,以這種方式手動執行部署有助於了解使用 k8s 配置它是多麼容易。 由於 Kubernetes 允許您透過 API 更新所有內容,因此這些步驟可以透過腳本自動化。

需要實現的另一件事是測試人員入口點(LoadBalancer 或透過 Ingress),透過它只能存取新版本。 可用於手動瀏覽。

在以後的文章中,我們將查看其他自動化解決方案,這些解決方案實現了我們所做的大部分工作。

也請閱讀我們部落格上的其他文章:

來源: www.habr.com

添加評論