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

我們將使用 Gitlab CI 和手動 GitOps 在 Kubernetes 中實現和使用金絲雀部署

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 Registry。在註冊表中我們有兩個不同版本的發布:

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

它們之間唯一的區別是傳回的 JSON 檔案的變化。我們使用此應用程式盡可能輕鬆地直觀地了解我們正在討論的版本。

基礎設施儲存庫

在此 repo 中,我們將透過 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 尚未定義任何副本。

執行初始部署

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

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

我們看 app 部署有 10 個副本,而 app-canary 沒有副本。還有一個 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

為具有 DDoS 保護、VPS VDS 服務器的站點購買可靠的主機 🔥 購買具備 DDoS 防護的可靠網站寄存服務,包括 VPS 和 VDS 伺服器 | ProHoster