Delen via


Blauw-groen implementatie in Azure Container Apps

Blue-Green Deployment is een softwarereleasestrategie die de downtime minimaliseert en het risico vermindert dat gepaard gaat met het implementeren van nieuwe versies van een toepassing. In een blauwgroene implementatie worden twee identieke omgevingen ingesteld, 'blauw' en 'groen'. Eén omgeving (blauw) voert de huidige toepassingsversie uit en één omgeving (groen) voert de nieuwe toepassingsversie uit.

Zodra de groene omgeving is getest, wordt het liveverkeer ernaar geleid en wordt de blauwe omgeving gebruikt om een nieuwe toepassingsversie te implementeren tijdens de volgende implementatiecyclus.

U kunt blauwgroene implementatie inSchakelen in Azure Container Apps door container-apps revisies, verkeersgewichten en revisielabels te combineren.

Screenshot of Azure Container Apps: Blue/Green deployment.

U gebruikt revisies om instanties van de blauwe en groene versies van de toepassing te maken.

Revisie Omschrijving
Blauwe revisie De revisie die als blauw wordt gelabeld, is de momenteel actieve en stabiele versie van de toepassing. Deze revisie is degene waarmee gebruikers communiceren en het is het doel van productieverkeer.
Groene revisie De revisie die als groen is gelabeld, is een kopie van de blauwe revisie, met uitzondering van een nieuwere versie van de app-code en mogelijk nieuwe set omgevingsvariabelen. Het ontvangt in eerste instantie geen productieverkeer, maar is toegankelijk via een gelabelde FQDN (Fully Qualified Domain Name).

Nadat u de nieuwe revisie hebt getest en gecontroleerd, kunt u productieverkeer naar de nieuwe revisie verwijzen. Als u problemen ondervindt, kunt u eenvoudig terugkeren naar de vorige versie.

Acties Omschrijving
Testen en verifiëren De groene revisie wordt grondig getest en gecontroleerd om ervoor te zorgen dat de nieuwe versie van de toepassing werkt zoals verwacht. Deze tests kunnen betrekking hebben op verschillende taken, waaronder functionele tests, prestatietests en compatibiliteitscontroles.
Verkeersswitch Zodra de groene revisie alle benodigde tests heeft doorstaan, wordt er een verkeersswitch uitgevoerd, zodat de groene revisie de productiebelasting gaat verwerken. Deze switch wordt op een gecontroleerde manier uitgevoerd om een soepele overgang te garanderen.
Terugdraaiactie Als er problemen optreden in de groene revisie, kunt u de verkeersswitch terugzetten, verkeer terugsturen naar de stabiele blauwe revisie. Deze terugdraaiactie zorgt voor minimale impact op gebruikers als er problemen zijn in de nieuwe versie. De groene revisie is nog steeds beschikbaar voor de volgende implementatie.
Rolwijziging De rollen van de blauwe en groene revisies veranderen na een geslaagde implementatie in de groene revisie. Tijdens de volgende releasecyclus vertegenwoordigt de groene revisie de stabiele productieomgeving terwijl de nieuwe versie van de toepassingscode wordt geïmplementeerd en getest in de blauwe revisie.

In dit artikel wordt beschreven hoe u blauwgroene implementatie implementeert in een container-app. Als u de volgende voorbeelden wilt uitvoeren, hebt u een container-app-omgeving nodig waar u een nieuwe app kunt maken.

Notitie

Raadpleeg de containerapps-blue-green-opslagplaats voor een volledig voorbeeld van een GitHub-werkstroom waarmee blauwgroene implementatie voor Container Apps wordt geïmplementeerd.

Een container-app maken waarvoor meerdere actieve revisies zijn ingeschakeld

De container-app moet de configuration.activeRevisionsMode eigenschap hebben ingesteld om multiple verkeer splitsen in te schakelen. Als u deterministische revisienamen wilt ophalen, kunt u de template.revisionSuffix configuratie-instelling instellen op een tekenreekswaarde waarmee een release uniek wordt geïdentificeerd. U kunt bijvoorbeeld buildnummers of git-doorvoeringen korte hashes gebruiken.

Voor de volgende opdrachten is een set doorvoer-hashes gebruikt.

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

Sla de volgende code op in een bestand met de naam 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

Implementeer de app met de Bicep-sjabloon met behulp van deze opdracht:

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

Een nieuwe revisie implementeren en labels toewijzen

Het blauwe label verwijst momenteel naar een revisie die het productieverkeer naar de FQDN van de app brengt. Het groene label verwijst naar een nieuwe versie van een app die binnenkort in productie wordt geïmplementeerd. Een nieuwe doorvoerhash identificeert de nieuwe versie van de app-code. Met de volgende opdracht wordt een nieuwe revisie voor die doorvoerhash geïmplementeerd en gemarkeerd met een groen label.

#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

In het volgende voorbeeld ziet u hoe de verkeerssectie is geconfigureerd. De revisie met blauw commitId neemt 100% van het productieverkeer in beslag terwijl de zojuist geïmplementeerde revisie met groencommitId geen productieverkeer in beslag neemt.

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

De zojuist geïmplementeerde revisie kan worden getest met behulp van de labelspecifieke 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

Productieverkeer verzenden naar de groene revisie

Nadat u hebt bevestigd dat de app-code in de groene revisie werkt zoals verwacht, wordt 100% van het productieverkeer naar de revisie verzonden. De groene revisie wordt nu de productierevisie.

# 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

In het volgende voorbeeld ziet u hoe de traffic sectie na deze stap is geconfigureerd. De groene revisie met de nieuwe toepassingscode neemt al het gebruikersverkeer over terwijl blauwe revisie met de oude toepassingsversie geen gebruikersaanvragen accepteert.

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

De implementatie terugdraaien als er problemen zijn

Als na uitvoering in productie de nieuwe revisie fouten heeft gevonden, kunt u terugdraaien naar de vorige goede status. Na het terugdraaien wordt 100% van het verkeer naar de oude versie in de blauwe revisie verzonden en wordt die revisie opnieuw aangewezen als productierevisie.

# 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

Nadat de fouten zijn opgelost, wordt de nieuwe versie van de toepassing opnieuw geïmplementeerd als een groene revisie. De groene versie wordt uiteindelijk de productierevisie.

Volgende implementatiecyclus

Nu markeert het groene label de revisie waarop de stabiele productiecode wordt uitgevoerd.

Tijdens de volgende implementatiecyclus identificeert het blauw de revisie met de nieuwe toepassingsversie die wordt geïmplementeerd in productie.

De volgende opdrachten laten zien hoe u zich voorbereidt op de volgende implementatiecyclus.

# 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

Volgende stappen