CD 被認為是一種企業軟件實踐,是既定 CI 原則自然演變的結果。 然而,CD 仍然很少見,這可能是由於管理的複雜性以及擔心部署失敗會影響系統可用性。
以下是在 Google Kubernetes Engine (GKE) 上設置和使用 Flagger 的分步指南。
設置 Kubernetes 集群
您首先使用 Istio 附加組件創建一個 GKE 集群(如果您沒有 GCP 帳戶,您可以註冊
登錄 Google Cloud,創建項目,並為其啟用計費。 安裝命令行實用程序 gcloud init
.
設置默認項目、計算區域和區域(替換 PROJECT_ID
為您的項目):
gcloud config set project PROJECT_ID
gcloud config set compute/region us-central1
gcloud config set compute/zone us-central1-a
啟用 GKE 服務並使用 HPA 和 Istio 附加組件創建集群:
gcloud services enable container.googleapis.com
K8S_VERSION=$(gcloud beta container get-server-config --format=json | jq -r '.validMasterVersions[0]')
gcloud beta container clusters create istio
--cluster-version=${K8S_VERSION}
--zone=us-central1-a
--num-nodes=2
--machine-type=n1-standard-2
--disk-size=30
--enable-autorepair
--no-enable-cloud-logging
--no-enable-cloud-monitoring
--addons=HorizontalPodAutoscaling,Istio
--istio-config=auth=MTLS_PERMISSIVE
上面的命令將創建一個包含兩個虛擬機的默認節點池 n1-standard-2
(vCPU:2,RAM 7,5 GB,磁盤:30 GB)。 理想情況下,您應該將 Istio 組件與您的工作負載隔離開來,但是沒有簡單的方法可以在專用節點池中運行 Istio Pod。 Istio 清單被認為是只讀的,GKE 將撤消任何更改,例如鍊接到節點或從 pod 分離。
設置憑據 kubectl
:
gcloud container clusters get-credentials istio
創建集群管理員角色綁定:
kubectl create clusterrolebinding "cluster-admin-$(whoami)"
--clusterrole=cluster-admin
--user="$(gcloud config get-value core/account)"
安裝命令行工具
brew install kubernetes-helm
Homebrew 2.0 現在也可用於
為 Tiller 創建服務賬戶和集群角色綁定:
kubectl -n kube-system create sa tiller &&
kubectl create clusterrolebinding tiller-cluster-rule
--clusterrole=cluster-admin
--serviceaccount=kube-system:tiller
在命名空間中展開 Tiller kube-system
:
helm init --service-account tiller
您應該考慮在 Helm 和 Tiller 之間使用 SSL。 有關保護 Helm 安裝的更多信息,請參閱
確認設置:
kubectl -n istio-system get svc
幾秒鐘後,GCP 應該為該服務分配一個外部 IP 地址 istio-ingressgateway
.
配置 Istio 入口網關
使用名稱創建靜態 IP 地址 istio-gateway
使用 Istio 網關的 IP 地址:
export GATEWAY_IP=$(kubectl -n istio-system get svc/istio-ingressgateway -ojson | jq -r .status.loadBalancer.ingress[0].ip)
gcloud compute addresses create istio-gateway --addresses ${GATEWAY_IP} --region us-central1
現在您需要一個 Internet 域並訪問您的 DNS 註冊商。 添加兩條A記錄(替換 example.com
到您的域):
istio.example.com A ${GATEWAY_IP}
*.istio.example.com A ${GATEWAY_IP}
驗證 DNS 通配符是否正常工作:
watch host test.istio.example.com
創建一個通用 Istio 網關以通過 HTTP 在服務網格外部提供服務:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: public-gateway
namespace: istio-system
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
將上述資源保存為 public-gateway.yaml 然後應用它:
kubectl apply -f ./public-gateway.yaml
任何生產系統都不應在沒有 SSL 的情況下在 Internet 上提供服務。 要使用證書管理器、CloudDNS 和 Let's Encrypt 保護 Istio 入口網關,請閱讀
標記器安裝
GKE Istio 附加組件不包含清理 Istio 遙測服務的 Prometheus 實例。 因為 Flagger 使用 Istio HTTP 指標來執行金絲雀分析,所以您需要部署以下 Prometheus 配置,類似於官方 Istio Helm 架構附帶的配置。
REPO=https://raw.githubusercontent.com/stefanprodan/flagger/master
kubectl apply -f ${REPO}/artifacts/gke/istio-prometheus.yaml
添加 Flagger Helm 存儲庫:
helm repo add flagger [https://flagger.app](https://flagger.app/)
將 Flagger 擴展到命名空間 istio-system
通過啟用 Slack 通知:
helm upgrade -i flagger flagger/flagger
--namespace=istio-system
--set metricsServer=http://prometheus.istio-system:9090
--set slack.url=https://hooks.slack.com/services/YOUR-WEBHOOK-ID
--set slack.channel=general
--set slack.user=flagger
您可以在任何命名空間中安裝 Flagger,只要它可以與端口 9090 上的 Istio Prometheus 服務通信即可。
Flagger 有一個用於金絲雀分析的 Grafana 儀表板。 在命名空間中安裝 Grafana istio-system
:
helm upgrade -i flagger-grafana flagger/grafana
--namespace=istio-system
--set url=http://prometheus.istio-system:9090
--set user=admin
--set password=change-me
通過創建虛擬服務(替換 example.com
到您的域):
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: grafana
namespace: istio-system
spec:
hosts:
- "grafana.istio.example.com"
gateways:
- public-gateway.istio-system.svc.cluster.local
http:
- route:
- destination:
host: flagger-grafana
將上面的資源保存為grafana-virtual-service.yaml 然後應用:
kubectl apply -f ./grafana-virtual-service.yaml
當移動到 http://grafana.istio.example.com
在瀏覽器中,您應該被定向到 Grafana 登錄頁面。
使用 Flagger 部署 Web 應用程序
Flagger 部署 Kubernetes 並可選擇自動橫向擴展 (HPA),然後創建一系列對象(Kubernetes 部署、ClusterIP 服務和 Istio 虛擬服務)。 這些對象將應用程序暴露給服務網格並控制金絲雀分析和進度。
創建啟用 Istio Sidecar 注入的測試命名空間:
REPO=https://raw.githubusercontent.com/stefanprodan/flagger/master
kubectl apply -f ${REPO}/artifacts/namespaces/test.yaml
創建 deployment 和 pod 自動擴容工具:
kubectl apply -f ${REPO}/artifacts/canaries/deployment.yaml
kubectl apply -f ${REPO}/artifacts/canaries/hpa.yaml
部署測試負載服務以在金絲雀分析期間生成流量:
helm upgrade -i flagger-loadtester flagger/loadtester
--namepace=test
創建自定義金絲雀資源(替換 example.com
到您的域):
apiVersion: flagger.app/v1alpha3
kind: Canary
metadata:
name: podinfo
namespace: test
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: podinfo
progressDeadlineSeconds: 60
autoscalerRef:
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
name: podinfo
service:
port: 9898
gateways:
- public-gateway.istio-system.svc.cluster.local
hosts:
- app.istio.example.com
canaryAnalysis:
interval: 30s
threshold: 10
maxWeight: 50
stepWeight: 5
metrics:
- name: istio_requests_total
threshold: 99
interval: 30s
- name: istio_request_duration_seconds_bucket
threshold: 500
interval: 30s
webhooks:
- name: load-test
url: http://flagger-loadtester.test/
timeout: 5s
metadata:
cmd: "hey -z 1m -q 10 -c 2 http://podinfo.test:9898/"
將上述資源保存為 podinfo-canary.yaml 然後應用它:
kubectl apply -f ./podinfo-canary.yaml
上述分析如果成功,將運行五分鐘,每半分鐘檢查一次 HTTP 指標。 您可以使用以下公式確定驗證和推廣金絲雀部署所需的最短時間: interval * (maxWeight / stepWeight)
. 記錄了 Canary CRD 字段
幾秒鐘後,Flagger 將創建金絲雀對象:
# applied
deployment.apps/podinfo
horizontalpodautoscaler.autoscaling/podinfo
canary.flagger.app/podinfo
# generated
deployment.apps/podinfo-primary
horizontalpodautoscaler.autoscaling/podinfo-primary
service/podinfo
service/podinfo-canary
service/podinfo-primary
virtualservice.networking.istio.io/podinfo
打開瀏覽器並轉到 app.istio.example.com
, 你應該看到版本號
自動金絲雀分析和推廣
Flagger 實現了一個控制循環,逐漸將流量轉移到金絲雀,同時測量關鍵性能指標,例如 HTTP 請求成功率、平均請求持續時間和 pod 健康狀況。 根據KPI分析,推進或中斷金絲雀,並將分析結果發佈到Slack。
當以下對象之一發生更改時,會觸發金絲雀部署:
- 部署 PodSpec(容器鏡像、命令、端口、環境等)
- ConfigMap 掛載為卷或映射到環境變量
- 秘密作為卷安裝或轉換為環境變量
更新容器鏡像時運行 canary deploy:
kubectl -n test set image deployment/podinfo
podinfod=quay.io/stefanprodan/podinfo:1.4.1
Flagger 檢測到部署版本已更改並開始解析它:
kubectl -n test describe canary/podinfo
Events:
New revision detected podinfo.test
Scaling up podinfo.test
Waiting for podinfo.test rollout to finish: 0 of 1 updated replicas are available
Advance podinfo.test canary weight 5
Advance podinfo.test canary weight 10
Advance podinfo.test canary weight 15
Advance podinfo.test canary weight 20
Advance podinfo.test canary weight 25
Advance podinfo.test canary weight 30
Advance podinfo.test canary weight 35
Advance podinfo.test canary weight 40
Advance podinfo.test canary weight 45
Advance podinfo.test canary weight 50
Copying podinfo.test template spec to podinfo-primary.test
Waiting for podinfo-primary.test rollout to finish: 1 of 2 updated replicas are available
Promotion completed! Scaling down podinfo.test
在分析期間,可以使用 Grafana 跟踪金絲雀結果:
請注意,如果在金絲雀分析期間將新更改應用於部署,則 Flagger 將重新啟動分析階段。
列出集群中的所有金絲雀:
watch kubectl get canaries --all-namespaces
NAMESPACE NAME STATUS WEIGHT LASTTRANSITIONTIME
test podinfo Progressing 15 2019-01-16T14:05:07Z
prod frontend Succeeded 0 2019-01-15T16:15:07Z
prod backend Failed 0 2019-01-14T17:05:07Z
如果您啟用了 Slack 通知,您將收到以下消息:
自動回滾
在 Canary 分析期間,您可以生成合成 HTTP 500 錯誤和高響應延遲,以查看 Flagger 是否會停止部署。
創建一個測試 pod 並在其中執行以下操作:
kubectl -n test run tester
--image=quay.io/stefanprodan/podinfo:1.2.1
-- ./podinfo --port=9898
kubectl -n test exec -it tester-xx-xx sh
生成 HTTP 500 錯誤:
watch curl http://podinfo-canary:9898/status/500
延遲生成:
watch curl http://podinfo-canary:9898/delay/1
當失敗的檢查次數達到閾值時,流量被路由回主通道,金絲雀縮放為零,部署被標記為失敗。
Canary 錯誤和延遲峰值被記錄為 Kubernetes 事件,並由 Flagger 以 JSON 格式記錄:
kubectl -n istio-system logs deployment/flagger -f | jq .msg
Starting canary deployment for podinfo.test
Advance podinfo.test canary weight 5
Advance podinfo.test canary weight 10
Advance podinfo.test canary weight 15
Halt podinfo.test advancement success rate 69.17% < 99%
Halt podinfo.test advancement success rate 61.39% < 99%
Halt podinfo.test advancement success rate 55.06% < 99%
Halt podinfo.test advancement success rate 47.00% < 99%
Halt podinfo.test advancement success rate 37.00% < 99%
Halt podinfo.test advancement request duration 1.515s > 500ms
Halt podinfo.test advancement request duration 1.600s > 500ms
Halt podinfo.test advancement request duration 1.915s > 500ms
Halt podinfo.test advancement request duration 2.050s > 500ms
Halt podinfo.test advancement request duration 2.515s > 500ms
Rolling back podinfo.test failed checks threshold reached 10
Canary failed! Scaling down podinfo.test
如果您啟用了 Slack 通知,當超過截止日期或達到分析中失敗檢查的最大數量時,您將收到一條消息:
總之
除了 Kubernetes 之外,運行像 Istio 這樣的服務網格將提供自動指標、日誌和協議,但工作負載部署仍然依賴於外部工具。 Flagger 旨在通過添加 Istio 功能來改變這一點
Flagger 與任何 Kubernetes CI/CD 解決方案兼容,並且可以輕鬆擴展金絲雀分析
支持旗手
如果您有改進 Flagger 的建議,請在 GitHub 上提交問題或 PR
謝謝
來源: www.habr.com