Blue-Green Deployment in Azure Container Apps

Blue-Green Deployment je strategie vydávání softwaru, jejímž cílem je minimalizovat výpadky a snížit riziko spojené s nasazením nových verzí aplikace. V nasazení s modrou zelenou barvou jsou nastavena dvě identická prostředí označovaná jako "modrá" a "zelená". Jedno prostředí (modré) spouští aktuální verzi aplikace a jedno prostředí (zelené) spouští novou verzi aplikace.

Po otestovaní zeleného prostředí se na něj směruje živý provoz a modré prostředí se použije k nasazení nové verze aplikace během dalšího cyklu nasazení.

Modré nasazení v Azure Container Apps můžete povolit kombinací revizí aplikací kontejnerů, váhy provozu a popisků revizí.

Screenshot of Azure Container Apps: Blue/Green deployment.

Revize slouží k vytvoření instancí modré a zelené verze aplikace.

Revize Popis
Modrá revize Revize označená jako modrá je aktuálně spuštěná a stabilní verze aplikace. Tato revize je ta, se kterou uživatelé pracují, a je to cíl produkčního provozu.
Zelená revize Revize označená jako zelená je kopií modré revize kromě toho, že používá novější verzi kódu aplikace a případně novou sadu proměnných prostředí. Na začátku neobdrží žádný produkční provoz, ale je přístupný prostřednictvím plně kvalifikovaného názvu domény (FQDN).

Po otestování a ověření nové revize pak můžete směrovat produkční provoz na novou revizi. Pokud narazíte na problémy, můžete se snadno vrátit k předchozí verzi.

Akce Popis
Testování a ověření Zelená revize se důkladně testuje a ověřuje, aby nová verze aplikace fungovala podle očekávání. Toto testování může zahrnovat různé úlohy, včetně funkčních testů, testů výkonnosti a kontrol kompatibility.
Přepínač provozu Jakmile zelená revize projde všemi potřebnými testy, provede se přepínač provozu, aby zelená revize začala obsluhovat produkční zatížení. Tento přepínač se provádí řízeným způsobem a zajišťuje hladký přechod.
Vrácení zpět Pokud dojde k problémům se zelenou revizí, můžete vrátit přepínač provozu a směrovat provoz zpět na stabilní modrou revizi. Toto vrácení zpět zajišťuje minimální dopad na uživatele, pokud v nové verzi dochází k problémům. Zelená revize je stále k dispozici pro další nasazení.
Změna role Role modrých a zelených revizí se po úspěšném nasazení změní na zelenou revizi. Během dalšího cyklu vydání představuje zelená revize stabilní produkční prostředí, zatímco nová verze kódu aplikace se nasadí a testuje v modré revizi.

V tomto článku se dozvíte, jak implementovat modré zelené nasazení v aplikaci kontejneru. Abyste mohli spustit následující příklady, potřebujete prostředí kontejnerové aplikace, ve kterém můžete vytvořit novou aplikaci.

Poznámka:

Kompletní příklad pracovního postupu GitHubu, který implementuje nasazení typu blue-green pro Container Apps, najdete v kontejnerových aplikacích v kontejnerech.

Vytvoření aplikace typu kontejner s povolenými několika aktivními revizemi

Aplikace kontejneru musí mít vlastnost nastavenou configuration.activeRevisionsMode tak, aby multiple umožňovala rozdělení provozu. Pokud chcete získat deterministické názvy revizí, můžete nastavit template.revisionSuffix nastavení konfigurace na řetězcovou hodnotu, která jednoznačně identifikuje verzi. Můžete například použít čísla sestavení nebo potvrzení gitu krátké hodnoty hash.

Pro následující příkazy se použila sada hodnot hash potvrzení.

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

Uložte následující kód do souboru s názvem 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

Pomocí tohoto příkazu nasaďte aplikaci pomocí šablony 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

Nasazení nové revize a přiřazení popisků

Modrý popisek aktuálně odkazuje na revizi, která přebírá produkční provoz přicházející do plně kvalifikovaného názvu domény aplikace. Zelený popisek odkazuje na novou verzi aplikace, která se chystá nasadit do produkčního prostředí. Nová hodnota hash potvrzení identifikuje novou verzi kódu aplikace. Následující příkaz nasadí novou revizi hodnoty hash potvrzení a označí ji zeleným popiskem.

#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

Následující příklad ukazuje, jak je oddíl provozu nakonfigurovaný. Revize s modroucommitId barvou přebírá 100 % produkčního provozu, zatímco nově nasazená revize se zelenoucommitId barvou nepřebírají žádný produkční provoz.

{ 
  "traffic": [
    {
      "revisionName": "<APP_NAME>--fb699ef",
      "weight": 100,
      "label": "blue"
    },
    {
      "revisionName": "<APP_NAME>--c6f1515",
      "weight": 0,
      "label": "green"
    }
  ]
}

Nově nasazenou revizi je možné otestovat pomocí plně kvalifikovaného názvu domény specifického pro popisek:

#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

Odeslání produkčního provozu do zelené revize

Po potvrzení, že kód aplikace v zelené revizi funguje podle očekávání, se do revize odešle 100 % produkčního provozu. Zelená revize se teď stane produkční revizí.

# 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

Následující příklad ukazuje, jak traffic je oddíl nakonfigurovaný po tomto kroku. Zelená revize s novým kódem aplikace přebírá veškerý uživatelský provoz, zatímco modrá revize se starou verzí aplikace nepřijímá žádosti uživatelů.

{ 
  "traffic": [
    {
      "revisionName": "<APP_NAME>--fb699ef",
      "weight": 0,
      "label": "blue"
    },
    {
      "revisionName": "<APP_NAME>--c6f1515",
      "weight": 100,
      "label": "green"
    }
  ]
}

Vrácení nasazení zpět, pokud došlo k problémům

Pokud po spuštění v produkčním prostředí zjistíte, že nová revize má chyby, můžete se vrátit zpět do předchozího dobrého stavu. Po vrácení zpět se do staré verze v modré revizi odešle 100 % provozu a tato revize se znovu označí jako produkční revize.

# 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

Po opravení chyb se nová verze aplikace znovu nasadí jako zelená revize. Zelená verze se nakonec stane produkční revizí.

Další cyklus nasazení

Teď zelený popisek označí revizi, ve které je aktuálně spuštěn stabilní produkční kód.

Během dalšího cyklu nasazení modrá identifikuje revizi s novou verzí aplikace, která se zavádí do produkčního prostředí.

Následující příkazy ukazují, jak se připravit na další cyklus nasazení.

# 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

Další kroky