Azure Container Apps 中的藍綠部署
藍綠部署 是一種軟體發行策略,旨在將停機時間降到最低,並降低與部署新版應用程式相關聯的風險。 在藍綠部署中,會設定兩個完全相同的環境,稱為「藍色」和「綠色」。 一個環境(藍色)正在執行目前的應用程式版本,而一個環境(綠色)正在執行新的應用程式版本。
一旦測試綠色環境,就會將即時流量導向至該環境,而藍色環境則用來在下一個部署週期期間部署新的應用程式版本。
您可以結合 容器應用程式修訂 、 流量權數 和 修訂標籤 ,在 Azure Container Apps 中啟用藍綠部署。
您可以使用修訂來建立應用程式的藍色和綠色版本的實例。
修訂 | 描述 |
---|---|
藍色 修訂 | 標示為 藍色 的修訂是目前執行且穩定版本的應用程式。 此修訂是使用者與其互動的修訂,也是生產流量的目標。 |
綠色 修訂 | 標示為 綠色 的修訂是藍色 修訂的複本, 但會使用較新版本的應用程式程式碼,而且可能是新的環境變數集。 它一開始不會收到任何生產流量,但可透過加上標籤的完整功能變數名稱 (FQDN) 存取。 |
測試並驗證新修訂之後,您就可以將生產流量指向新的修訂。 如果您遇到問題,您可以輕鬆地回復至舊版。
動作 | 描述 |
---|---|
測試和驗證 | 綠色 修訂經過徹底測試並經過驗證,以確保新版的應用程式如預期般運作。 此測試可能涉及各種工作,包括功能測試、效能測試和相容性檢查。 |
流量交換器 | 一 旦綠色 修訂通過所有必要的測試,就會執行流量交換器, 讓綠色 修訂開始提供生產負載。 此開關會以受控制的方式完成,以確保順暢的轉換。 |
復原 | 如果綠色修訂中 發生問題,您可以還原流量交換器,將流量路由回到穩定的 藍色 修訂。 如果新版本發生問題,此復原可確保對使用者的影響降到最低。 綠色 修訂仍可供下一個部署使用。 |
角色變更 | 成功部署至 綠色 修訂之後,藍色和綠色修訂的角色會變更。 在下一個發行週期中, 綠色 修訂代表穩定的生產環境,而新版的應用程式程式碼會在藍色 修訂中 部署及測試。 |
本文說明如何在容器應用程式中實作藍綠部署。 若要執行下列範例,您需要容器應用程式環境,您可以在其中建立新的應用程式。
建立已啟用多個作用中修訂的容器應用程式
容器應用程式必須將 configuration.activeRevisionsMode
屬性設定為 multiple
,才能啟用流量分割。 若要取得具決定性的修訂名稱,您可以將組 template.revisionSuffix
態設定設定設定為可唯一識別發行的字串值。 例如,您可以使用組建編號,或 git 認可簡短雜湊。
針對下列命令,使用了一組認可雜湊。
export APP_NAME=<APP_NAME>
export APP_ENVIRONMENT_NAME=<APP_ENVIRONMENT_NAME>
export RESOURCE_GROUP=<RESOURCE_GROUP>
# A commitId that is assumed to correspond to the app code currently in production
export BLUE_COMMIT_ID=fb699ef
# A commitId that is assumed to correspond to the new version of the code to be deployed
export GREEN_COMMIT_ID=c6f1515
# create a new app with a new revision
az containerapp create --name $APP_NAME \
--environment $APP_ENVIRONMENT_NAME \
--resource-group $RESOURCE_GROUP \
--image mcr.microsoft.com/k8se/samples/test-app:$BLUE_COMMIT_ID \
--revision-suffix $BLUE_COMMIT_ID \
--env-vars REVISION_COMMIT_ID=$BLUE_COMMIT_ID \
--ingress external \
--target-port 80 \
--revisions-mode multiple
# Fix 100% of traffic to the revision
az containerapp ingress traffic set \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--revision-weight $APP_NAME--$BLUE_COMMIT_ID=100
# give that revision a label 'blue'
az containerapp revision label add \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--label blue \
--revision $APP_NAME--$BLUE_COMMIT_ID
將下列程式碼儲存到名為 的 main.bicep
檔案中。
targetScope = 'resourceGroup'
param location string = resourceGroup().location
@minLength(1)
@maxLength(64)
@description('Name of containerapp')
param appName string
@minLength(1)
@maxLength(64)
@description('Container environment name')
param containerAppsEnvironmentName string
@minLength(1)
@maxLength(64)
@description('CommitId for blue revision')
param blueCommitId string
@maxLength(64)
@description('CommitId for green revision')
param greenCommitId string = ''
@maxLength(64)
@description('CommitId for the latest deployed revision')
param latestCommitId string = ''
@allowed([
'blue'
'green'
])
@description('Name of the label that gets 100% of the traffic')
param productionLabel string = 'blue'
var currentCommitId = !empty(latestCommitId) ? latestCommitId : blueCommitId
resource containerAppsEnvironment 'Microsoft.App/managedEnvironments@2022-03-01' existing = {
name: containerAppsEnvironmentName
}
resource blueGreenDeploymentApp 'Microsoft.App/containerApps@2022-11-01-preview' = {
name: appName
location: location
tags: {
blueCommitId: blueCommitId
greenCommitId: greenCommitId
latestCommitId: currentCommitId
productionLabel: productionLabel
}
properties: {
environmentId: containerAppsEnvironment.id
configuration: {
maxInactiveRevisions: 10 // Remove old inactive revisions
activeRevisionsMode: 'multiple' // Multiple active revisions mode is required when using traffic weights
ingress: {
external: true
targetPort: 80
traffic: !empty(blueCommitId) && !empty(greenCommitId) ? [
{
revisionName: '${appName}--${blueCommitId}'
label: 'blue'
weight: productionLabel == 'blue' ? 100 : 0
}
{
revisionName: '${appName}--${greenCommitId}'
label: 'green'
weight: productionLabel == 'green' ? 100 : 0
}
] : [
{
revisionName: '${appName}--${blueCommitId}'
label: 'blue'
weight: 100
}
]
}
}
template: {
revisionSuffix: currentCommitId
containers:[
{
image: 'mcr.microsoft.com/k8se/samples/test-app:${currentCommitId}'
name: appName
resources: {
cpu: json('0.5')
memory: '1.0Gi'
}
env: [
{
name: 'REVISION_COMMIT_ID'
value: currentCommitId
}
]
}
]
}
}
}
output fqdn string = blueGreenDeploymentApp.properties.configuration.ingress.fqdn
output latestRevisionName string = blueGreenDeploymentApp.properties.latestRevisionName
使用此命令以 Bicep 範本部署應用程式:
export APP_NAME=<APP_NAME>
export APP_ENVIRONMENT_NAME=<APP_ENVIRONMENT_NAME>
export RESOURCE_GROUP=<RESOURCE_GROUP>
# A commitId that is assumed to belong to the app code currently in production
export BLUE_COMMIT_ID=fb699ef
# A commitId that is assumed to belong to the new version of the code to be deployed
export GREEN_COMMIT_ID=c6f1515
# create a new app with a blue revision
az deployment group create \
--name createapp-$BLUE_COMMIT_ID \
--resource-group $RESOURCE_GROUP \
--template-file main.bicep \
--parameters appName=$APP_NAME blueCommitId=$BLUE_COMMIT_ID containerAppsEnvironmentName=$APP_ENVIRONMENT_NAME \
--query properties.outputs.fqdn
部署新的修訂並指派標籤
藍色 標籤目前是指採用實際執行流量抵達應用程式 FQDN 的修訂。 綠色 標籤是指即將推出至生產環境的新版本應用程式。 新的認可雜湊會識別新版的應用程式程式碼。 下列命令會針對該認可雜湊部署新的修訂,並以綠色 標籤標示。
#create a second revision for green commitId
az containerapp update --name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--image mcr.microsoft.com/k8se/samples/test-app:$GREEN_COMMIT_ID \
--revision-suffix $GREEN_COMMIT_ID \
--set-env-vars REVISION_COMMIT_ID=$GREEN_COMMIT_ID
#give that revision a 'green' label
az containerapp revision label add \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--label green \
--revision $APP_NAME--$GREEN_COMMIT_ID
#deploy a new version of the app to green revision
az deployment group create \
--name deploy-to-green-$GREEN_COMMIT_ID \
--resource-group $RESOURCE_GROUP \
--template-file main.bicep \
--parameters appName=$APP_NAME blueCommitId=$BLUE_COMMIT_ID greenCommitId=$GREEN_COMMIT_ID latestCommitId=$GREEN_COMMIT_ID productionLabel=blue containerAppsEnvironmentName=$APP_ENVIRONMENT_NAME \
--query properties.outputs.fqdn
下列範例示範如何設定流量區段。 具有藍色 的修訂採用 100% 的生產流量,而以綠色 commitId
新增的修訂 不會採用任何生產流量。 commitId
{
"traffic": [
{
"revisionName": "<APP_NAME>--fb699ef",
"weight": 100,
"label": "blue"
},
{
"revisionName": "<APP_NAME>--c6f1515",
"weight": 0,
"label": "green"
}
]
}
您可以使用標籤特定的 FQDN 來測試新部署的修訂:
#get the containerapp environment default domain
export APP_DOMAIN=$(az containerapp env show -g $RESOURCE_GROUP -n $APP_ENVIRONMENT_NAME --query properties.defaultDomain -o tsv | tr -d '\r\n')
#Test the production FQDN
curl -s https://$APP_NAME.$APP_DOMAIN/api/env | jq | grep COMMIT
#Test the blue lable FQDN
curl -s https://$APP_NAME---blue.$APP_DOMAIN/api/env | jq | grep COMMIT
#Test the green lable FQDN
curl -s https://$APP_NAME---green.$APP_DOMAIN/api/env | jq | grep COMMIT
將生產流量傳送至綠色修訂
確認綠色 修訂中的 應用程式程式碼如預期般運作之後,100% 的生產流量會傳送至修訂。 綠色 修訂現在會變成生產修訂。
# set 100% of traffic to green revision
az containerapp ingress traffic set \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--label-weight blue=0 green=100
# make green the prod revision
az deployment group create \
--name make-green-prod-$GREEN_COMMIT_ID \
--resource-group $RESOURCE_GROUP \
--template-file main.bicep \
--parameters appName=$APP_NAME blueCommitId=$BLUE_COMMIT_ID greenCommitId=$GREEN_COMMIT_ID latestCommitId=$GREEN_COMMIT_ID productionLabel=green containerAppsEnvironmentName=$APP_ENVIRONMENT_NAME \
--query properties.outputs.fqdn
下列範例示範在此步驟之後如何 traffic
設定 區段。 具有 新應用程式程式碼的綠色 修訂會採用所有使用者流量,而 使用舊應用程式版本的藍色 修訂不接受使用者要求。
{
"traffic": [
{
"revisionName": "<APP_NAME>--fb699ef",
"weight": 0,
"label": "blue"
},
{
"revisionName": "<APP_NAME>--c6f1515",
"weight": 100,
"label": "green"
}
]
}
如果發生問題,請回復部署
如果在生產環境中執行之後,發現新的修訂有 Bug,您可以回復到先前的良好狀態。 復原之後,會將 100% 的流量傳送至藍色 修訂中的 舊版本,並將該修訂指定為生產修訂。
# set 100% of traffic to green revision
az containerapp ingress traffic set \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--label-weight blue=100 green=0
# rollback traffic to blue revision
az deployment group create \
--name rollback-to-blue-$GREEN_COMMIT_ID \
--resource-group $RESOURCE_GROUP \
--template-file main.bicep \
--parameters appName=$APP_NAME blueCommitId=$BLUE_COMMIT_ID greenCommitId=$GREEN_COMMIT_ID latestCommitId=$GREEN_COMMIT_ID productionLabel=blue containerAppsEnvironmentName=$APP_ENVIRONMENT_NAME \
--query properties.outputs.fqdn
修正 Bug 之後,新版的應用程式會再次部署為 綠色 修訂。 綠色 版本最終會變成生產修訂。
下一個部署週期
現在綠色 標籤會 標示目前執行穩定生產程式碼的修訂。
在下一個部署週期期間, 藍色 會識別將新應用程式版本推出至生產環境的修訂。
下列命令示範如何準備下一個部署週期。
# set the new commitId
export BLUE_COMMIT_ID=ad1436b
# create a third revision for blue commitId
az containerapp update --name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--image mcr.microsoft.com/k8se/samples/test-app:$BLUE_COMMIT_ID \
--revision-suffix $BLUE_COMMIT_ID \
--set-env-vars REVISION_COMMIT_ID=$BLUE_COMMIT_ID
# give that revision a 'blue' label
az containerapp revision label add \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--label blue \
--revision $APP_NAME--$BLUE_COMMIT_ID
# set the new commitId
export BLUE_COMMIT_ID=ad1436b
# deploy new version of the app to blue revision
az deployment group create \
--name deploy-to-blue-$BLUE_COMMIT_ID \
--resource-group $RESOURCE_GROUP \
--template-file main.bicep \
--parameters appName=$APP_NAME blueCommitId=$BLUE_COMMIT_ID greenCommitId=$GREEN_COMMIT_ID latestCommitId=$BLUE_COMMIT_ID productionLabel=green containerAppsEnvironmentName=$APP_ENVIRONMENT_NAME \
--query properties.outputs.fqdn