Развертывание Blue-Green в приложениях контейнеров Azure
Blue-Green Deployment — это стратегия выпуска программного обеспечения, которая направлена на минимизацию простоя и снижение риска, связанного с развертыванием новых версий приложения. В сине-зеленом развертывании настраиваются две идентичные среды, называемые "голубым" и "зеленым". Одна среда (синяя) выполняет текущую версию приложения, а одна среда (зеленая) выполняет новую версию приложения.
После тестирования зеленой среды динамический трафик направляется в него, а синяя среда используется для развертывания новой версии приложения во время следующего цикла развертывания.
Вы можете включить сине-зеленое развертывание в приложениях контейнеров Azure, объединив редакции контейнерных приложений, вес трафика и метки редакции.
Для создания экземпляров синих и зеленых версий приложения используются редакции.
Исправление | Description |
---|---|
Синяя редакция | Редакция, помеченная как синяя , является текущей и стабильной версией приложения. Эта редакция является тем, с которыми взаимодействуют пользователи, и это цель рабочего трафика. |
Зеленая редакция | Редакция, помеченная как зеленая , является копией синей редакции, за исключением того, что она использует более новую версию кода приложения и, возможно, новый набор переменных среды. Изначально он не получает рабочий трафик, но доступен через полное доменное имя (FQDN). |
После тестирования и проверки новой редакции можно указать рабочий трафик на новую редакцию. При возникновении проблем можно легко выполнить откат к предыдущей версии.
Действия | Description |
---|---|
Тестирование и проверка | Зеленая редакция тщательно проверяется и проверяется, чтобы новая версия функций приложения была правильной. Это тестирование может включать различные задачи, включая функциональные тесты, тесты производительности и проверки совместимости. |
Коммутатор трафика | После прохождения всех необходимых тестов зеленая редакция выполняется переключатель трафика, чтобы зеленая редакция начала обслуживать рабочую нагрузку. Этот переключатель выполняется в управляемом режиме, обеспечивая плавный переход. |
Откат | Если проблемы возникают в зеленой редакции, можно вернуть коммутатор трафика, перенаправив трафик обратно в стабильную синюю редакцию. Этот откат гарантирует минимальное влияние на пользователей при возникновении проблем в новой версии. Зеленая редакция по-прежнему доступна для следующего развертывания. |
Изменение роли | Роли синих и зеленых редакций изменяются после успешного развертывания на зеленую редакцию. Во время следующего цикла выпуска зеленая редакция представляет стабильную рабочую среду, а новая версия кода приложения развертывается и проверяется в синей редакции. |
В этой статье показано, как реализовать сине-зеленое развертывание в приложении-контейнере. Для выполнения следующих примеров требуется среда приложения контейнера, в которой можно создать новое приложение.
Примечание.
Полный пример рабочего процесса GitHub, реализующего сине-зеленое развертывание для контейнерных приложений, см. в репозитории containerapps-blue-green .
Создание приложения-контейнера с включенными несколькими активными редакциями
Приложение-контейнер должен иметь 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
Развертывание новой редакции и назначение меток
Голубая метка в настоящее время относится к редакции, которая принимает рабочий трафик, поступающий на полное доменное имя приложения. Зеленая метка ссылается на новую версию приложения, которое будет развернуто в рабочей среде. Новый хэш фиксации определяет новую версию кода приложения. Следующая команда развертывает новую редакцию для хэша фиксации и помечает ее зеленой меткой.
#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
В следующем примере показано, как настроен раздел трафика. Редакция с синим commitId
цветом занимает 100% рабочего трафика, а только что развернутая редакция с зеленым commitId
цветом не принимает рабочий трафик.
{
"traffic": [
{
"revisionName": "<APP_NAME>--fb699ef",
"weight": 100,
"label": "blue"
},
{
"revisionName": "<APP_NAME>--c6f1515",
"weight": 0,
"label": "green"
}
]
}
Недавно развернутая редакция может быть проверена с помощью полного доменного имени для меток:
#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"
}
]
}
Откат развертывания, если возникли проблемы
Если после выполнения в рабочей среде новая редакция найдена с ошибками, можно выполнить откат к предыдущему хорошему состоянию. После отката 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
После исправления ошибок новая версия приложения развертывается в виде зеленой редакции еще раз. Зеленая версия в конечном итоге становится рабочей редакцией.
Следующий цикл развертывания
Теперь зеленая метка помечает редакцию, выполняющую стабильный рабочий код.
В следующем цикле развертывания синий определяет редакцию с новой версией приложения, развернутой в рабочей среде.
В следующих командах показано, как подготовиться к следующему циклу развертывания.
# 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