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

本系列文章:
- (本文)
- 使用 Istio 進行金絲雀部署
- 使用 Jenkins-X Istio Flagger 進行金絲雀部署
我們將透過 GitOps 手動執行 Canary 部署以及主要 Kubernetes 資源的建立/修改。 本文主要以介紹為目的。 與 Kubernetes Canary 部署的工作方式不同,因為有更有效的方法來實現自動化,我們將在以後的文章中介紹。

金絲雀部署
採用金絲雀策略,更新最初僅應用於一部分用戶。透過監控、日誌資料、手動測試或其他回饋管道,在將版本部署給所有使用者之前對其進行測試。
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:v1wuestkamp/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
你需要分叉 並創建一個變數 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 應該輸出以下內容:

我們看 app 部署有 10 個副本,而 app-canary 沒有副本。還有一個 LoadBalancer,我們可以透過它來訪問 curl 按外部 IP:
while true; do curl -s 35.198.149.232 | grep label; sleep 0.1; done

我們看到我們的測試應用程式只返回“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 中的預設隨機分佈,我們應該會看到約 10% 的請求有不同的回應:

我們的應用程式(GitOps,取自 Git 作為單一事實來源)的當前狀態是擁有兩個帶有活動副本的部署,每個版本一個。
約 10% 的用戶了解新版本並無意中測試它。現在是時候檢查您的日誌和監控資料中的錯誤以發現問題了。
第 2 步:向所有使用者發布新版本
我們認為一切進展順利,現在我們需要向所有用戶部署新版本。為此,我們只需更新 deploy.yaml 安裝新版本的映像,副本數量等於 10。 deploy-canary.yaml 我們將副本數設定回0,部署後結果如下:

總結
對我來說,以這種方式手動運行部署有助於我了解使用 k8s 進行設定有多輕鬆。由於 Kubernetes 允許您透過 API 更新所有內容,因此這些步驟可以透過腳本自動執行。
另一件需要實現的事情是測試器入口點(LoadBalancer 或透過 Ingress),只有透過該入口點才能存取新版本。可用於手動查看。
在未來的文章中,我們將研究實現我們所做的大部分工作的其他自動化解決方案。
也請閱讀我們部落格上的其他文章:
來源: www.habr.com
