新聞中心
Argo Rollouts 實現(xiàn)藍綠/金絲雀發(fā)布
作者:k8s技術圈 2021-07-13 06:35:11
云計算 Argo Rollouts 是一個 Kubernetes Operator 實現(xiàn),它為 Kubernetes 提供更加高級的部署能力,如藍綠、金絲雀、金絲雀分析、實驗和漸進式交付功能,為云原生應用和服務實現(xiàn)自動化、基于 GitOps 的逐步交付。

在西充等地區(qū),都構建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產品創(chuàng)新能力,以專注、極致的服務理念,為客戶提供成都網站設計、做網站 網站設計制作按需開發(fā)網站,公司網站建設,企業(yè)網站建設,成都品牌網站建設,全網營銷推廣,外貿網站建設,西充網站建設費用合理。
Argo Rollouts 是一個 Kubernetes Operator 實現(xiàn),它為 Kubernetes 提供更加高級的部署能力,如藍綠、金絲雀、金絲雀分析、實驗和漸進式交付功能,為云原生應用和服務實現(xiàn)自動化、基于 GitOps 的逐步交付。
支持如下特性:
- 藍綠更新策略
- 金絲雀更新策略
- 更加細粒度、加權流量拆分
- 自動回滾
- 手動判斷
- 可定制的指標查詢和業(yè)務 KPI 分析
- Ingress 控制器集成:NGINX,ALB
- 服務網格集成:Istio,Linkerd,SMI
- Metrics 指標集成:Prometheus、Wavefront、Kayenta、Web、Kubernetes Jobs、Datadog、New Relic
實現(xiàn)原理
與 Deployment 對象類似,Argo Rollouts 控制器將管理 ReplicaSets 的創(chuàng)建、縮放和刪除,這些 ReplicaSet 由 Rollout 資源中的 spec.template 定義,使用與 Deployment 對象相同的 pod 模板。
當 spec.template 變更時,這會向 Argo Rollouts 控制器發(fā)出信號,表示將引入新的 ReplicaSet,控制器將使用 spec.strategy 字段內的策略來確定從舊 ReplicaSet 到新 ReplicaSet 的 rollout 將如何進行,一旦這個新的 ReplicaSet 被放大(可以選擇通過一個 Analysis),控制器會將其標記為穩(wěn)定。
如果在 spec.template 從穩(wěn)定的 ReplicaSet 過渡到新的 ReplicaSet 的過程中發(fā)生了另一次變更(即在發(fā)布過程中更改了應用程序版本),那么之前的新 ReplicaSet 將縮小,并且控制器將嘗試發(fā)布反映更新 spec.template 字段的 ReplicasSet。
相關概念
在繼續(xù)之前我們先來了解一些基本的概念。
Rollout(滾動)
Rollout 是一個 Kubernetes 的 CRD 資源,相當于 Kubernetes Deployment 對象,在需要更高級的部署或漸進式交付功能的情況下,它旨在取代 Deployment 對象,Rollout 提供了 Kubernetes Deployment 所不能提供的功能。
- 藍綠部署
- 金絲雀部署
- 與 Ingress 控制器和服務網格整合,實現(xiàn)高級流量路由
- 與用于藍綠和金絲雀分析的指標提供者集成
- 根據成功或失敗的指標,自動發(fā)布或回滾
漸進式交付
漸進式交付是以受控和漸進的方式發(fā)布產品更新的過程,從而降低發(fā)布的風險,通常將自動化和指標分析結合起來以驅動更新的自動升級或回滾。
漸進式交付通常被描述為持續(xù)交付的演變,將 CI/CD 中的速度優(yōu)勢擴展到部署過程。通過將新版本限制在一部分用戶,觀察和分析正確的行為,然后逐漸增加更多的流量,同時不斷驗證其正確性。
部署策略
雖然業(yè)界使用了一致的術語來描述各種部署策略,但這些策略的實現(xiàn)往往因工具而異,為了明確 Argo Rollouts 的行為方式,以下是 Argo Rollouts 提供的各種部署策略實施的描述。
- RollingUpdate(滾動更新):慢慢地用新版本替換舊版本,隨著新版本的出現(xiàn),舊版本會慢慢縮減,以保持應用程序的總數量。這是 Deployment 對象的默認策略。
- Recreate(重新創(chuàng)建):Recreate 會在啟動新版本之前刪除舊版本的應用程序,這可確保應用程序的兩個版本永遠不會同時運行,但在部署期間會出現(xiàn)停機時間。
- Blue-Green(藍綠):藍綠發(fā)布(有時稱為紅黑)指同時部署了新舊兩個版本的應用程序,在此期間,只有舊版本的應用程序會收到生產流量,這允許開發(fā)人員在將實時流量切換到新版本之前針對新版本進行測試。
- Canary(金絲雀):金絲雀發(fā)布指將一部分用戶暴露在新版本的應用程序中,而將其余流量提供給舊版本,一旦新版本被驗證是正確的,新版本可以逐漸取代舊版本。Ingress 控制器和服務網格,如 NGINX Ingress 和 Istio,可以使金絲雀的流量拆分模式比原生的更復雜(例如,實現(xiàn)非常細粒度的流量分割,或基于 HTTP 頭的分割)。
上面顯示了一個有兩個階段的金絲雀(10%和33%的流量進入新版本),通過使用 Argo Rollouts,我們可以根據實際的使用情況定義確切的階段數和流量百分比。
場景
- 用戶希望在新版本開始為生產環(huán)境提供服務之前對其進行最后一分鐘的功能測試,通過 BlueGreen 策略,Argo Rollouts 允許用戶指定預覽服務和活動服務,Rollout 將配置預覽服務以將流量發(fā)送到新版本,同時活動服務繼續(xù)接收生產流量。一旦達到要求,則可以將預覽服務提升為新的活動服務。
- 在新版本開始接收實時流量之前,需要預先執(zhí)行一套通用步驟,通過使用 BlueGreen 策略,用戶可以在不接收來自活動服務的流量的情況下啟動新版本,一旦這些步驟執(zhí)行完畢,就可以將流量切換到新版本了。
- 用戶希望在幾個小時內將一小部分生產流量提供給他們應用程序的新版本。之后,他們希望縮小新版本規(guī)模,并查看一些指標以確定新版本與舊版本相比是否具有性能問題,然后他們將決定是否為切換到新版本。使用金絲雀策略,rollout 可以用新版本擴大 ReplicaSet 的規(guī)模,以接收指定百分比的流量,等待指定的時間,然后將百分比設置回 0,然后等待用戶滿意后再發(fā)布,為所有的流量提供服務。
- 一個用戶想慢慢給新版增加生產流量,先給它一小部分的實時流量,然后等待一段時間再給新版本更多的流量,最終,新版本將接收所有生產流量。使用金絲雀策略,用戶指定他們希望新版本接收的百分比以及在百分比之間等待的時間。
- 用戶想要使用 Deployment 中的正常滾動更新策略,如果用戶使用沒有步驟的金絲雀策略,rollout 將使用 maxSurge 和最大不可用值來滾動到新版本。
架構
下面展示了由 Argo Rollouts 管理的 Deployment 的所有組件。
argo rollouts 架構
Rollout Controller
這是主控制器,用于監(jiān)視集群的事件并在 Rollout 類型的資源發(fā)生更改時做出反應??刂破鲗⒆x取 rollout 的所有詳細信息,并使集群處于 rollout 定義中描述的相同狀態(tài)。
請注意,Argo Rollouts 不會篡改或響應正常 Deployment 資源上發(fā)生的任何變更,這意味著你可以在一個使用其他方法部署應用的集群中安裝 Argo Rollouts。
Rollout 資源
Rollout 資源是 Argo Rollouts 引入和管理的一種自定義 Kubernetes 資源,它與原生的 Kubernetes Deployment 資源基本兼容,但有額外的字段來控制更加高級的部署方法,如金絲雀和藍/綠部署。
Argo Rollouts 控制器將只對 Rollout 資源中的變化做出反應,不會對正常的 Deployment 資源做任何事情,所以如果你想用 Argo Rollouts 管理你的 Deployment,你需要將你的 Deployment 遷移到Rollouts。
舊版和新版的 ReplicaSets
這些是標準的 Kubernetes ReplicaSet 資源的實例,Argo Rollouts 給它們添加了一些額外的元數據,以便跟蹤屬于應用程序的不同版本。
還要注意的是,參加 Rollout 的 ReplicaSet 完全由控制器自動管理,你不應該用外部工具來篡改它們。
Ingress/Service
用戶的流量進入集群后,被重定向到合適的版本,Argo Rollouts 使用標準的 Kubernetes Service 資源,但有一些額外的元數據。
Argo Rollouts 在網絡配置上非常靈活,首先,可以在 Rollout 期間使用不同的服務,這些服務僅適用于新版本、僅適用于舊版本或兩者都適用。特別是對于 Canary 部署,Argo Rollouts 支持多種服務網格和 Ingress 解決方案,用于按特定百分比拆分流量,而不是基于 Pod 數量進行簡單的配置。
Analysis 與 AnalysisRun
Analysis 是一種自定義 Kubernetes 資源,它將 Rollout 連接到指標提供程序,并為某些指標定義特定閾值,這些閾值將決定 Rollout 是否成功。對于每個 Analysis,你可以定義一個或多個指標查詢及其預期結果,如果指標查詢正常,則 Rollout 將繼續(xù)操作;如果指標顯示失敗,則自動回滾;如果指標無法提供成功/失敗的答案,則暫停發(fā)布。
Analysis 只是關于要查詢哪些指標的模板。附加到 Rollout 的實際結果是 AnalysisRun 自定義資源,你可以在特定 Rollout 上或在集群上全局定義 Analysis 以供多個 rollout 共享。
請注意,在 Rollout 中使用 Analysis 和指標是完全可選的,你可以通過 API 或 CLI 手動暫停和促進發(fā)布或使用其他外部方法(例如冒煙測試)。你不需要僅使用 Argo Rollouts 的 Metrics 解決方案,你還可以在 Rollout 中混合自動(即基于 Analysis)和手動步驟。
除了指標之外,你還可以通過運行 Kubernetes Job 或運行 webhook 來決定發(fā)布的成功與否。
Metric Providers
Argo Rollouts 包括幾個流行的指標提供者的原生集成,你可以在 Analysis 資源中使用,來自動提升或回滾發(fā)布。
CLI 和 UI(圖中未顯示)
還可以使用 Argo Rollouts CLI 或集成 UI 查看和管理 Rollout,兩者都是可選的。
安裝
直接使用下面的命令安裝 Argo Rollouts:
- ~ kubectl create namespace argo-rollouts
- ~ kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/download/v1.0.2/install.yaml
這里會創(chuàng)建一個名為 argo-rollouts 的命名空間,Argo Rollouts 控制器運行在下面。
- ~ kubectl get pods -n argo-rollouts
- NAME READY STATUS RESTARTS AGE
- argo-rollouts-6fdcf89f7c-7z2mh 1/1 Running 0 58s
此外,我們還可以安裝一個 kubectl 插件,對于命令行管理和可視化發(fā)布非常方便。
我們這里是 Mac 系統(tǒng),可以直接使用下面的命令進行安裝:
- ~ brew install argoproj/tap/kubectl-argo-rollouts
當然也可以手動進行安裝,使用 curl 安裝 Argo Rollouts kubectl 插件:
- ~ curl -LO https://github.com/argoproj/argo-rollouts/releases/download/v1.0.2/kubectl-argo-rollouts-darwin-amd64
然后賦予 kubectl-argo-rollouts 二進制文件可執(zhí)行權限:
- ~ chmod +x ./kubectl-argo-rollouts-darwin-amd64
將該二進制文件移動到你的 PATH 路徑下面去:
- ~ sudo mv ./kubectl-argo-rollouts-darwin-amd64 /usr/local/bin/kubectl-argo-rollouts
執(zhí)行下面的命令來驗證插件是否安裝成功:
- ~ kubectl argo rollouts version
- kubectl-argo-rollouts: v1.0.2+7a23fe5
- BuildDate: 2021-06-15T19:36:10Z
- GitCommit: 7a23fe5dbf78181248c48af8e5224246434e7f99
- GitTreeState: clean
- GoVersion: go1.16.3
- Compiler: gc
- Platform: darwin/amd64
使用
接下來我們通過幾個簡單的示例來說明 Rollout 的部署、升級、發(fā)布和中斷等操作,以此來展示 Rollouts 的各種功能。
1. 部署 Rollout
首先我們部署一個 Rollout 資源和一個針對該資源的 Kubernetes Service 對象,這里我們示例中的 Rollout 采用了金絲雀的更新策略,將 20% 的流量發(fā)送到金絲雀上,然后手動發(fā)布,最后在升級的剩余時間內逐漸自動增大流量,可以通過如下所示的 Rollout 來描述這個策略:
- # basic-rollout.yaml
- apiVersion: argoproj.io/v1alpha1
- kind: Rollout
- metadata:
- name: rollouts-demo
- spec:
- replicas: 5 # 定義5個副本
- strategy: # 定義升級策略
- canary: # 金絲雀發(fā)布
- steps: # 發(fā)布的節(jié)奏
- - setWeight: 20
- - pause: {} # 會一直暫停
- - setWeight: 40
- - pause: {duration: 10}
- - setWeight: 60
- - pause: {duration: 10}
- - setWeight: 80
- - pause: {duration: 10}
- revisionHistoryLimit: 2 # 下面部分其實是和 Deployment 兼容的
- selector:
- matchLabels:
- app: rollouts-demo
- template:
- metadata:
- labels:
- app: rollouts-demo
- spec:
- containers:
- - name: rollouts-demo
- image: argoproj/rollouts-demo:blue
- ports:
- - name: http
- containerPort: 8080
- protocol: TCP
- resources:
- requests:
- memory: 32Mi
- cpu: 5m
還包括一個如下所示的 Service 資源對象:
- # basic-service.yaml
- apiVersion: v1
- kind: Service
- metadata:
- name: rollouts-demo
- spec:
- ports:
- - port: 80
- targetPort: http
- protocol: TCP
- name: http
- selector:
- app: rollouts-demo
直接創(chuàng)建上面的兩個資源對象:
- ~ kubectl apply -f basic-rollout.yaml
- ~ kubectl apply -f basic-service.yaml
任何 Rollout 的初始創(chuàng)建都會立即將副本擴展到100%(跳過任何金絲雀升級步驟、分析等...),因為還沒有發(fā)生升級。
Argo Rollouts 的 kubectl 插件允許我們可視化 Rollout 以及相關資源對象,并展示實時狀態(tài)變化,要在部署過程中觀察 Rollout,可以通過運行插件的 get rollout --watch 命令,比如:
- ~ kubectl argo rollouts get rollout rollouts-demo --watch
2. 更新 Rollout
上面已經部署完成,接下來就需要執(zhí)行更新了,和 Deployment 類似,對 Pod 模板字段的任何變更都會導致新的版本(即 ReplicaSet)被部署,更新 Rollout 通常是修改容器鏡像的版本,然后執(zhí)行 kubectl apply ,為了方便,rollouts 插件還單獨提供了一個 set image 的命令,比如這里我們運行以下所示命令,用 yellow 版本的容器更新上面的 Rollout:
- ~ kubectl argo rollouts set image rollouts-demo \
- rollouts-demo=argoproj/rollouts-demo:yellow
在 rollout 更新期間,控制器將通過 Rollout 更新策略中定義的步驟進行。這個示例的 rollout 為金絲雀設置了20%的流量權重,并一直暫停 rollout,直到用戶取消或促進發(fā)布。在更新鏡像后,再次觀察rollout,直到它達到暫停狀態(tài)。
- ~ kubectl argo rollouts get rollout rollouts-demo --watch
當 demo rollout 到達第二步時,我們可以從插件中看到,Rollout 處于暫停狀態(tài),現(xiàn)在有5個副本中的1個運行新版本的 pod,其余4個仍然運行舊版本,這相當于 setWeight: 20 步驟所定義的20%的金絲雀權重。
3. Promote Rollout
經過上面的更新后,Rollout 現(xiàn)在處于暫停狀態(tài),當一個 Rollout 到達一個沒有持續(xù)時間的暫停步驟時,它將一直保持在暫停狀態(tài),直到它被恢復/提升。要手動將 Rollout 切換到下一個步驟,請運行插件的 promotion 命令。
- ~ kubectl argo rollouts promote rollouts-demo
切換后 Rollout 將繼續(xù)執(zhí)行剩余的步驟。在我們的例子中,剩余的步驟是完全自動化的,所以 Rollout 最終會完成步驟,直到它已經完全過渡到新版本。再次觀察 Rollout,直到它完成所有步驟。
- ~ kubectl argo rollouts get rollout rollouts-demo --watch
- promote 命令還支持用 --full 標志跳過所有剩余步驟和分析。
可以看到 stable 版本已經切換到 revision:2 這個 ReplicaSet 了。在更新過程中,無論何時,無論是通過失敗的金絲雀分析自動中止,還是由用戶手動中止,Rollout 都會退回到 stable 版本。
4. 中斷 Rollout
接下來我們來了解如何在更新過程中手動中止 Rollout,首先,使用 set image 命令部署一個新的 red 版本的容器,并等待 rollout 再次達到暫停的步驟。
- ~ kubectl argo rollouts set image rollouts-demo \
- rollouts-demo=argoproj/rollouts-demo:red
這一次我們將中止更新,而不是將滾動切換到下一步,這樣它就回到了 stable 版本,該插件同樣提供了一個 abort 命令,可以在更新過程中的任何時候手動中止 Rollout。
- ~ kubectl argo rollouts abort rollouts-demo
當中止?jié)L動時,它將擴大 ReplicaSet 的 stable 版本(在本例中是 yellow 版本),并縮小任何其他版本。盡管 ReplicaSet 的穩(wěn)定版本可能正在運行,并且是健康的,但整個 Rollout 仍然被認為是退化的,因為期望的版本(red 版本)不是實際運行的版本。
為了使 Rollout 再次被認為是健康的而不是有問題的版本,有必要將所需的狀態(tài)改回以前的穩(wěn)定版本。在我們的例子中,我們可以簡單地使用之前的 yellow 鏡像重新運行 set image 命令即可。
- ~ kubectl argo rollouts set image rollouts-demo \
- rollouts-demo=argoproj/rollouts-demo:yellow
運行這個命令后,可以看到 Rollout 立即變成了 health 狀態(tài),而且沒有任何關于創(chuàng)建新 ReplicaSets 的動態(tài)。
當 Rollout 還沒有達到預期狀態(tài)(例如,它被中止了,或者正在更新中),而穩(wěn)定版本的資源清單被重新應用,Rollout 檢測到這是一個回滾,而不是一個更新,并將通過跳過分析和步驟快速部署穩(wěn)定的 ReplicaSet。
上面例子中的 Rollout 沒有使用 Ingress 控制器或服務網格來控制流量。相反,它使用正常的 Kubernetes Service 來實現(xiàn)近似的金絲雀權重,基于新舊副本數量的比例來實現(xiàn)。所以,這個 Rollout 有一個限制,即它只能實現(xiàn) 20% 的最小加權,通過擴展5個pod中的一個來運行新版本。為了實現(xiàn)更細粒度的金絲雀,這就需要一個 Ingress 控制器或服務網格了,這部分我們可以在后續(xù)服務網格的學習中來介紹。
Dashboard
Argo Rollouts Kubectl 插件可以提供一個本地 Dashboard,來可視化你的 Rollouts。
要啟動這個 Dashboard,需要在包含 Rollouts 資源對象的命名空間中運行 kubectl argo rollouts dashboard 命令,然后訪問localhost:3100 即可。
點擊 Rollout 可以進行詳細頁面,在詳細頁面可以看到 Rollout 的配置信息,還可以直接在 UI 界面上執(zhí)行一些常用的操作,比如重啟、重啟、中斷等。
當前文章:Argo Rollouts 實現(xiàn)藍綠/金絲雀發(fā)布
鏈接URL:http://fisionsoft.com.cn/article/dhppece.html


咨詢
建站咨詢
