通過Jenkins構建CI/CD實現全鏈路灰度
作者:卜比
本文介紹通過 Jenkins 構建流水線的方式實現全鏈路灰度功能。
在釋出過程中,為了整體穩定性,我們總是希望能夠用小部分特定流量來驗證下新發布應用是否正常。
即使新版本有問題,也能及時發現,控制影響面,保障了整體的穩定性。
整體架構
我們以如下 Demo 為例:
為了保證穩定,我們約定如下上線流程:
其中,在灰度驗證中,有幾種不同的策略:
- 直接使用線上小部分流量來測試(按照百分比放量)
- 從線上按照特定規則選擇流量(比如特定的 header、特定的 cookie 等)
- 在客戶端或瀏覽器上標識出流量是否灰度(比如通過 header 傳遞)
部署應用&建立泳道
按照參考文件部署應用後,我們首先要區分線上流量和灰度流量。
建立泳道組,將整個鏈路涉及到的應用全選:
然後建立泳道組,將符合規則的應用劃入 gray 泳道:
注:沒有匹配的流量,會走到基線環境,也就是沒有打標的應用節點上。
配置完成後,訪問閘道器,如果不符合灰度規則,走基線環境:
如何符合灰度規則,走灰度環境:
配置 Jenkins 流水線
本文實踐需要將原始碼打包後執行映象推送,請確保 Jenkins 有許可權推送到映象倉庫中。具體操作,請參見使用 kaniko 構建和推送容器映象。
在 Jenkins 名稱空間下使用生成的 config.json 檔案建立名為 jenkins-docker-cfg 的 Secret。
kubectl create secret generic jenkins-docker-cfg -n jenkins --from-file=/root/.docker/config.json
在 Jenkins 中建立全鏈路灰度釋出流水線
基於 Jenkins 實現自動化釋出的流水線,通過該流水線可以使應用釋出具備可灰度、可觀測、可回滾的安全生產三板斧能力。
-
在 Jenkins 控制檯左側導航欄單擊新建任務。
-
輸入任務名稱,選擇流水線,然後單擊確定。
-
在頂部選單欄單擊流水線頁籤,在流水線區域配置相關引數選擇,輸入指令碼路徑,然後單擊儲存。
-
- 定義:選擇 Pipeline script from SCM。
-
- SCM:選擇 Git。
-
- Repository URL:輸入 Git 倉庫的 URL。
-
- 指令碼路徑:輸入 Jenkinsfile。
您可以參考以下的檔案填寫好指定的引數,當然您也可以根據需求編寫 Jenkinsfile ,並上傳至 Git 的指定路徑下(流水線中指定的指令碼路徑)。
```
!groovy
pipeline {
// 定義本次構建使用哪個標籤的構建環境,本示例中為 “slave-pipeline”
agent{
node{
label 'slave-pipeline'
}
}
//常量引數,初始確定後一般不需更改
environment{
IMAGE = sh(returnStdout: true,script: 'echo registry.$image_region.aliyuncs.com/$image_namespace/$image_reponame:$image_tag').trim()
BRANCH = sh(returnStdout: true,script: 'echo $branch').trim()
}
options {
//保持構建的最大個數
buildDiscarder(logRotator(numToKeepStr: '10'))
}
parameters {
string(name: 'image_region', defaultValue: 'cn-shanghai')
string(name: 'image_namespace', defaultValue: 'yizhan')
string(name: 'image_reponame', defaultValue: 'spring-cloud-a')
string(name: 'image_tag', defaultValue: 'gray')
string(name: 'branch', defaultValue: 'master')
string(name: 'number_of_pods', defaultValue: '2')
}
//pipeline的各個階段場景
stages {
stage('程式碼打包') {
steps{
container("maven") {
echo "映象構建......"
sh "cd A && mvn clean package"
}
}
}
stage('映象構建及釋出'){
steps{
container("kaniko") {
sh "kaniko -f pwd
/A/Dockerfile -c pwd
/A --destination=${IMAGE} --skip-tls-verify"
}
}
}
stage('灰度部署') {
steps{
container('kubectl') {
echo "灰度部署......"
sh "cd A && sed -i -E "s/${env.image_reponame}:.+/${env.image_reponame}:${env.image_tag}/" A-gray-deployment.yaml"
sh "cd A && sed -i -E "s/replicas:.+/replicas: ${env.number_of_pods}/" A-gray-deployment.yaml"
sh "kubectl apply -f A/A-gray-deployment.yaml -n default"
}
}
}
stage('結束灰度') {
input {
message "請確認是否全量釋出"
ok "確認"
parameters {
string(name: 'continue', defaultValue: 'true', description: 'true為全量釋出,其他為回滾')
}
}
steps{
script {
env.continue = sh (script: 'echo ${continue}', returnStdout: true).trim()
if (env.continue.equals('true')) {
container('kubectl') {
echo "全量釋出......"
sh "cd A && sed -i -E "s/${env.image_reponame}:.+/${env.image_reponame}:${env.image_tag}/" A-deployment.yaml"
sh "cd A && sed -i -E "s/replicas:.+/replicas: ${env.number_of_pods}/" A-deployment.yaml"
sh "kubectl apply -f A/A-deployment.yaml -n default"
}
} else {
echo '回滾'
}
container('kubectl') {
sh "kubectl delete -f A/A-gray-deployment.yaml -n default"
}
}
}
}
}
}
```
構建 Jenkins 流水線
-
在 Jenkins 控制檯單擊流水線右側的圖示。
-
單擊流水線的開始構建。
說明:第一次構建因為需要從 Git 倉庫拉取配置並初始化流水線,所以可能會報錯,再次執行 Build with Parameters,生成相關的引數,填寫相關的引數,再次執行構建。
檢視部署狀態,程式碼打包,映象構建及釋出,灰度部署階段都已經完成,結束灰度階段等待確認。
-
- 如果驗證結果符合預期,則執行全量釋出,請參見後文的全量釋出應用。
-
- 如果驗證結果不符合預期時,則執行回滾,請參見後文的回滾應用。
結果驗證
-
登入容器服務控制檯,在控制檯左側導航欄中,單擊叢集。
-
在叢集列表頁面中,單擊目標叢集名稱或者目標叢集右側操作列下的詳情。
-
在叢集管理頁面左側導航欄選擇工作負載 > 無狀態。
-
在無狀態應用列表頁面,spring-cloud-a-gray應用已經自動建立,並且它的映象已經替換為spring-cloud-a:gray版本。
-
在叢集管理頁面左側導航欄選擇網路 > 服務,選擇設定的名稱空間,單擊zuul-slb服務的外部端點,檢視真實的呼叫情況。
-
- 不帶灰度 Header 進行呼叫,發現路由到 A 的正常節點。
-
-
- Curl 命令:
-
curl http://182.92.XX.XX/A/a
-
-
- 執行結果如下:
-
A[10.4.XX.XX] -> B[10.4.XX.XX] -> C[10.4.XX.XX]%
-
- 帶上符合條件的引數進行訪問,路由到 A 的灰度節點中。
-
-
- Curl 命令:
-
curl http://182.92.XX.XX/A/a?name=xiaoming
-
-
- 執行結果如下:
-
Agray[10.4.XX.XX] -> B[10.4.XX.XX] -> C[10.4.XX.XX]%
- 登入 MSE 治理中心控制檯,在應用詳情頁面,可以看到灰度流量已經進入到灰度的 Pod 中。
全量釋出應用
結果驗證通過之後,確認全量釋出。
-
在 Jenkins 控制檯中,單擊目標流水線名稱。
-
單擊需要全量釋出的階段,在請確認是否全量釋出對話方塊中輸入 true,然後單擊確認。
- 在容器服務控制檯,發現 spring-cloud-a-gray 應用已經被刪除,並且 spring-cloud-a 應用的映象已經替換為 spring-cloud-a:gray 版本。
- 在 MSE治理中心控制檯,發現灰度流量已經消失。
回滾應用
如果發現驗證結果不符合預期時,則回滾應用。
-
在 Jenkins 控制檯中,單擊目標流水線名稱。
-
單擊需要全量釋出的階段,在請確認是否全量釋出對話方塊中輸入 false,然後單擊確認。
- 在容器服務控制檯,發現 spring-cloud-a-gray 應用已經被刪除,並且 spring-cloud-a 應用的映象仍然是老版本。
- 在 MSE 治理中心控制檯,發現灰度流量已經消失。
總結
在微服務治理架構中,全鏈路灰度功能能提供虛擬泳道,極大的方便了測試、釋出時的快速驗證,能夠幫助 DevOPs 提升線上穩定性。
阿里雲微服務引擎(MSE)能夠給您帶來全生命週期的、全方位的微服務治理能力,保障您的線上穩定性、提升開發、運維效率。
相關連結:
參考文件:
示例程式碼倉庫地址:
https://gitee.com/mse-group/alibabacloud-microservice-demo/tree/master/mse-simple-demo
容器服務控制檯:
https://cs.console.aliyun.com/#/k8s/cluster/list
MSE治理中心控制檯:
https://mse.console.aliyun.com/#/overview
使用 kaniko 構建和推送容器映象:
- 工作一年,我重新理解了《重構》
- 談談我對於關鍵思考的理解
- 談談我工作中的23個設計模式
- 談談我工作中的23個設計模式
- Serverless 奇點已來,下一個十年將駛向何方?
- 阿里巴巴重磅開源雲原生閘道器: Higress
- 我們總結了 3 大使用建議,並首次公開 Nacos3.0 規劃圖 | Nacos 開源 4 週年
- SAE 助力貴州酒店集團從容支撐貴州特產搶購
- 甩掉容量規劃炸彈:用 AHPA 實現 Kubernetes 智慧彈性伸縮
- 聊聊降本提效這件事兒
- 主流定時任務解決方案全橫評
- 通過Jenkins構建CI/CD實現全鏈路灰度
- 一站式動態多環境建設案例
- Proxyless Mesh 在 Dubbo 中的實踐
- ChaosBlade Java 場景效能優化,那些你不知道的事
- 新零售標杆 SKG 全面擁抱 Serverless,實現敏捷交付
- 「技術人生」第9篇:如何設定業務目標
- 面向物件分析與設計的底層邏輯
- 微服務治理熱門技術揭祕:動態讀寫分離
- Helm Chart 多環境、多叢集交付實踐,透視資源拓撲和差異