我們將使用Gitlab CI和手動GitOps在Kubernetes中實作和使用Canary部署
本系列文章:
- (本文)
使用 ArgoCI 進行金絲雀部署 - 使用 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 註冊表。 在註冊表中我們有兩個不同的發行版本:
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
你需要分叉 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
應輸出以下內容:
我們看 app
部署有 10 個副本,app-canary 有 0 個副本。還有一個 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),透過它只能存取新版本。 可用於手動瀏覽。
在以後的文章中,我們將查看其他自動化解決方案,這些解決方案實現了我們所做的大部分工作。
也請閱讀我們部落格上的其他文章:
從無授權的ClickHouse遷移到授權的ClickHouse導致了什麼? 為 Nginx 建立動態模組 更新 nxs-build-tools - 建置 deb 和 rpm 套件的助手 Hashicorp Consul Kubernetes 授權介紹 使用 Csync2 實用程式時我們必須面對的問題 Redmine 的 Telegram 機器人。 如何簡化自己和他人的生活
來源: www.habr.com