Distributionsjobb
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2020
Viktigt!
- Jobb- och stegnamn får inte innehålla nyckelord (exempel:
deployment
). - Varje jobb i en fas måste ha ett unikt namn.
I YAML-pipelines rekommenderar vi att du anger distributionsstegen i en särskild typ av jobb som kallas för ett distributionsjobb. Ett distributionsjobb är en samling steg som körs sekventiellt mot miljön. Ett distributionsjobb och ett traditionellt jobb kan finnas i samma fas. Azure DevOps stöder runOnce, rullande och kanariestrategier .
Distributionsjobb ger följande fördelar:
- Distributionshistorik: Du får distributionshistoriken över pipelines, ned till en specifik resurs och status för distributionerna för granskning.
- Tillämpa distributionsstrategi: Du definierar hur programmet distribueras.
Ett distributionsjobb klonar inte källdatabasen automatiskt. Du kan checka ut källdatabasen i jobbet med checkout: self
.
Kommentar
Den här artikeln fokuserar på distribution med distributionsjobb. Information om hur du distribuerar till Azure med pipelines finns i Distribuera till Azure-översikt.
Schema
Här är den fullständiga syntaxen för att ange ett distributionsjobb:
jobs:
- deployment: string # name of the deployment job, A-Z, a-z, 0-9, and underscore. The word "deploy" is a keyword and is unsupported as the deployment name.
displayName: string # friendly name to display in the UI
pool: # not required for virtual machine resources
name: string # Use only global level variables for defining a pool name. Stage/job level variables are not supported to define pool name.
demands: string | [ string ]
workspace:
clean: outputs | resources | all # what to clean up before the job runs
dependsOn: string
condition: string
continueOnError: boolean # 'true' if future jobs should run even if this job fails; defaults to 'false'
container: containerReference # container to run this job inside
services: { string: string | container } # container resources to run as a service container
timeoutInMinutes: nonEmptyString # how long to run the job before automatically cancelling
cancelTimeoutInMinutes: nonEmptyString # how much time to give 'run always even if cancelled tasks' before killing them
variables: # several syntaxes, see specific section
environment: string # target environment name and optionally a resource name to record the deployment history; format: <environment-name>.<resource-name>
strategy:
runOnce: #rolling, canary are the other strategies that are supported
deploy:
steps: [ script | bash | pwsh | powershell | checkout | task | templateReference ]
Det finns en mer detaljerad, alternativ syntax som du också kan använda för egenskapen environment
.
environment:
name: string # Name of environment.
resourceName: string # Name of resource.
resourceId: string # Id of resource.
resourceType: string # Type of environment resource.
tags: string # List of tag filters.
För virtuella datorer behöver du inte definiera en pool. Alla steg som du definierar i ett distributionsjobb med en virtuell datorresurs körs mot den virtuella datorn och inte mot agenten i poolen. För andra resurstyper, till exempel Kubernetes, måste du definiera en pool så att aktiviteter kan köras på den datorn.
Distributionsstrategier
När du distribuerar programuppdateringar är det viktigt att den teknik du använder för att leverera uppdateringen kommer att:
- Aktivera initiering.
- Distribuera uppdateringen.
- Dirigera trafik till den uppdaterade versionen.
- Testa den uppdaterade versionen efter routning av trafik.
- I händelse av fel kör du steg för att återställa till den senast kända versionen.
Vi uppnår detta genom att använda livscykelkrokar som kan köra steg under distributionen. Var och en av livscykeln kopplas till ett agentjobb eller ett serverjobb (eller en container eller ett valideringsjobb i framtiden), beroende på pool
attributet. Som standard ärver livscykelkrokerna den pool
som angetts av deployment
jobbet.
Distributionsjobb använder $(Pipeline.Workspace)
systemvariabeln.
Beskrivningar av livscykelkrokar
preDeploy
: Används för att köra steg som initierar resurser innan programdistributionen startar.
deploy
: Används för att köra steg som distribuerar ditt program. Ladda ned artefaktaktivitet matas bara in automatiskt i kroken deploy
för distributionsjobb. Om du vill sluta ladda ned artefakter använder - download: none
eller väljer du specifika artefakter att ladda ned genom att ange ladda ned pipelineartefaktaktivitet.
routeTraffic
: Används för att köra steg som hanterar trafiken till den uppdaterade versionen.
postRouteTraffic
: Används för att köra stegen när trafiken dirigeras. Normalt övervakar dessa uppgifter hälsotillståndet för den uppdaterade versionen för definierat intervall.
on: failure
eller on: success
: Används för att köra steg för återställningsåtgärder eller rensning.
RunOnce-distributionsstrategi
runOnce
är den enklaste distributionsstrategin där alla livscykelkrokar, nämligen preDeploy
deploy
, routeTraffic
och postRouteTraffic
, körs en gång. Sedan körs antingen on:
success
eller on:
failure
.
strategy:
runOnce:
preDeploy:
pool: [ server | pool ] # See pool schema.
steps:
- script: [ script | bash | pwsh | powershell | checkout | task | templateReference ]
deploy:
pool: [ server | pool ] # See pool schema.
steps:
...
routeTraffic:
pool: [ server | pool ]
steps:
...
postRouteTraffic:
pool: [ server | pool ]
steps:
...
on:
failure:
pool: [ server | pool ]
steps:
...
success:
pool: [ server | pool ]
steps:
...
Om du använder lokalt installerade agenter kan du använda alternativen för att rensa arbetsytan på arbetsytan för att rensa distributionsarbetsytan.
jobs:
- deployment: MyDeploy
pool:
vmImage: 'ubuntu-latest'
workspace:
clean: all
environment: staging
Strategi för rullande distribution
En löpande distribution ersätter instanser av den tidigare versionen av ett program med instanser av den nya versionen av programmet på en fast uppsättning virtuella datorer (rullande uppsättning) i varje iteration.
För närvarande stöder vi bara den löpande strategin för VM-resurser.
En rullande distribution väntar till exempel vanligtvis på att distributionerna på varje uppsättning virtuella datorer ska slutföras innan du fortsätter till nästa uppsättning distributioner. Du kan göra en hälsokontroll efter varje iteration och om ett betydande problem uppstår kan den löpande distributionen stoppas.
Rullande distributioner kan konfigureras genom att ange nyckelordet rolling:
under strategy:
noden.
Variabeln strategy.name
är tillgänglig i det här strategiblocket, som tar namnet på strategin. I det här fallet rullande.
strategy:
rolling:
maxParallel: [ number or percentage as x% ]
preDeploy:
steps:
- script: [ script | bash | pwsh | powershell | checkout | task | templateReference ]
deploy:
steps:
...
routeTraffic:
steps:
...
postRouteTraffic:
steps:
...
on:
failure:
steps:
...
success:
steps:
...
Alla livscykelkrokar stöds och livscykelkrokjobb skapas för att köras på varje virtuell dator.
preDeploy
, deploy
, routeTraffic
, och postRouteTraffic
körs en gång per batchstorlek som definieras av maxParallel
.
Sedan körs antingen on: success
eller on: failure
.
Med maxParallel: <# or % of VMs>
kan du styra antalet/procentandelen virtuella datormål som ska distribueras parallellt. Detta säkerställer att appen körs på dessa datorer och kan hantera begäranden medan distributionen sker på resten av datorerna, vilket minskar den totala stilleståndstiden.
Kommentar
Det finns några kända luckor i den här funktionen. När du till exempel försöker utföra en fas igen körs distributionen på alla virtuella datorer, inte bara misslyckade mål.
Strategi för canary-distribution
Strategi för canary-distribution är en avancerad distributionsstrategi som hjälper till att minska risken med att lansera nya versioner av program. Med den här strategin kan du distribuera ändringarna till en liten delmängd av servrarna först. När du får mer förtroende för den nya versionen kan du släppa den till fler servrar i infrastrukturen och dirigera mer trafik till den.
strategy:
canary:
increments: [ number ]
preDeploy:
pool: [ server | pool ] # See pool schema.
steps:
- script: [ script | bash | pwsh | powershell | checkout | task | templateReference ]
deploy:
pool: [ server | pool ] # See pool schema.
steps:
...
routeTraffic:
pool: [ server | pool ]
steps:
...
postRouteTraffic:
pool: [ server | pool ]
steps:
...
on:
failure:
pool: [ server | pool ]
steps:
...
success:
pool: [ server | pool ]
steps:
...
Strategin för canary-distribution stöder preDeploy
livscykelkroken (körs en gång) och itererar med deploy
routeTraffic
, och postRouteTraffic
livscykelkrokar. Den avslutas sedan med antingen eller failure
krokensuccess
.
Följande variabler är tillgängliga i den här strategin:
strategy.name
: Namnet på strategin. Till exempel kanariefågel.
strategy.action
: Den åtgärd som ska utföras på Kubernetes-klustret. Du kan till exempel distribuera, höja upp eller avvisa.
strategy.increment
: Det inkrementsvärde som används i den aktuella interaktionen. Den här variabeln är endast tillgänglig i deploy
, routeTraffic
och postRouteTraffic
livscykelkrokar.
Exempel
RunOnce-distributionsstrategi
I följande exempel visar YAML-kodavsnittet en enkel användning av ett distributionsjobb med hjälp av distributionsstrategin runOnce
. Exemplet innehåller ett utcheckningssteg.
jobs:
# Track deployments on the environment.
- deployment: DeployWeb
displayName: deploy Web App
pool:
vmImage: 'ubuntu-latest'
# Creates an environment if it doesn't exist.
environment: 'smarthotel-dev'
strategy:
# Default deployment strategy, more coming...
runOnce:
deploy:
steps:
- checkout: self
- script: echo my first deployment
För varje körning av det här jobbet registreras distributionshistoriken smarthotel-dev
mot miljön.
Kommentar
- Det går också att skapa en miljö med tomma resurser och använda den som ett abstrakt gränssnitt för att registrera distributionshistorik, som du ser i föregående exempel.
Nästa exempel visar hur en pipeline kan referera till både en miljö och en resurs som ska användas som mål för ett distributionsjobb.
jobs:
- deployment: DeployWeb
displayName: deploy Web App
pool:
vmImage: 'ubuntu-latest'
# Records deployment against bookings resource - Kubernetes namespace.
environment: 'smarthotel-dev.bookings'
strategy:
runOnce:
deploy:
steps:
# No need to explicitly pass the connection details.
- task: KubernetesManifest@0
displayName: Deploy to Kubernetes cluster
inputs:
action: deploy
namespace: $(k8sNamespace)
manifests: |
$(System.ArtifactsDirectory)/manifests/*
imagePullSecrets: |
$(imagePullSecret)
containers: |
$(containerRegistry)/$(imageRepository):$(tag)
Den här metoden har följande fördelar:
- Registrerar distributionshistorik för en specifik resurs i miljön, i stället för att registrera historiken för alla resurser i miljön.
- Steg i distributionsjobbet ärver automatiskt anslutningsinformationen för resursen (i det här fallet ett Kubernetes-namnområde,
smarthotel-dev.bookings
), eftersom distributionsjobbet är länkat till miljön. Detta är användbart i de fall där samma anslutningsinformation har angetts för flera steg i jobbet.
Kommentar
Om du använder ett privat AKS-kluster kontrollerar du att du är ansluten till klustrets virtuella nätverk eftersom API-serverslutpunkten inte exponeras via en offentlig IP-adress.
Azure Pipelines rekommenderar att du konfigurerar en lokalt installerad agent i ett virtuellt nätverk som har åtkomst till klustrets virtuella nätverk. Mer information finns i Alternativ för att ansluta till det privata klustret .
Strategi för rullande distribution
Den löpande strategin för virtuella datorer uppdaterar upp till fem mål i varje iteration. maxParallel
avgör antalet mål som kan distribueras till, parallellt. Valet står för absolut antal eller procentandel av mål som måste vara tillgängliga när som helst, exklusive de mål som distribueras till. Den används också för att fastställa villkoren för lyckade och misslyckade distributioner.
jobs:
- deployment: VMDeploy
displayName: web
environment:
name: smarthotel-dev
resourceType: VirtualMachine
strategy:
rolling:
maxParallel: 5 #for percentages, mention as x%
preDeploy:
steps:
- download: current
artifact: drop
- script: echo initialize, cleanup, backup, install certs
deploy:
steps:
- task: IISWebAppDeploymentOnMachineGroup@0
displayName: 'Deploy application to Website'
inputs:
WebSiteName: 'Default Web Site'
Package: '$(Pipeline.Workspace)/drop/**/*.zip'
routeTraffic:
steps:
- script: echo routing traffic
postRouteTraffic:
steps:
- script: echo health check post-route traffic
on:
failure:
steps:
- script: echo Restore from backup! This is on failure
success:
steps:
- script: echo Notify! This is on success
Strategi för canary-distribution
I nästa exempel distribuerar kanariestrategin för AKS först ändringarna med 10 procent poddar, följt av 20 procent, samtidigt som hälsotillståndet övervakas under postRouteTraffic
. Om allt går bra kommer det att höjas till 100 procent.
jobs:
- deployment:
environment: smarthotel-dev.bookings
pool:
name: smarthotel-devPool
strategy:
canary:
increments: [10,20]
preDeploy:
steps:
- script: initialize, cleanup....
deploy:
steps:
- script: echo deploy updates...
- task: KubernetesManifest@0
inputs:
action: $(strategy.action)
namespace: 'default'
strategy: $(strategy.name)
percentage: $(strategy.increment)
manifests: 'manifest.yml'
postRouteTraffic:
pool: server
steps:
- script: echo monitor application health...
on:
failure:
steps:
- script: echo clean-up, rollback...
success:
steps:
- script: echo checks passed, notify...
Använd pipelinedekoratörer för att mata in steg automatiskt
Pipelinedekoratörer kan användas i distributionsjobb för att automatiskt mata in alla anpassade steg (till exempel sårbarhetsskanner) till varje livscykelkrokkörning för varje distributionsjobb. Eftersom pipelinedekoratörer kan tillämpas på alla pipelines i en organisation kan detta användas som en del av att tillämpa säkra distributionsmetoder.
Dessutom kan distributionsjobb köras som ett containerjobb tillsammans med tjänster på sidovagnen om det definieras.
Stöd för utdatavariabler
Definiera utdatavariabler i ett distributionsjobbs livscykelkrokar och använd dem i andra underordnade steg och jobb inom samma fas.
Om du vill dela variabler mellan faser matar du ut en artefakt i ett steg och använder den sedan i en efterföljande fas, eller använder syntaxen stageDependencies
som beskrivs i variabler.
När du kör distributionsstrategier kan du komma åt utdatavariabler mellan jobb med hjälp av följande syntax.
- För runOnce-strategi :
$[dependencies.<job-name>.outputs['<job-name>.<step-name>.<variable-name>']]
(till exempel$[dependencies.JobA.outputs['JobA.StepA.VariableA']]
) - För runOnce-strategi plus en resourceType:
$[dependencies.<job-name>.outputs['Deploy_<resource-name>.<step-name>.<variable-name>']]
. (till exempel$[dependencies.JobA.outputs['Deploy_VM1.StepA.VariableA']]
) - För kanariestrategi :
$[dependencies.<job-name>.outputs['<lifecycle-hookname>_<increment-value>.<step-name>.<variable-name>']]
- För löpande strategi:
$[dependencies.<job-name>.outputs['<lifecycle-hookname>_<resource-name>.<step-name>.<variable-name>']]
# Set an output variable in a lifecycle hook of a deployment job executing canary strategy.
- deployment: A
pool:
vmImage: 'ubuntu-latest'
environment: staging
strategy:
canary:
increments: [10,20] # Creates multiple jobs, one for each increment. Output variable can be referenced with this.
deploy:
steps:
- bash: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]this is the deployment variable value"
name: setvarStep
- bash: echo $(setvarStep.myOutputVar)
name: echovar
# Map the variable from the job.
- job: B
dependsOn: A
pool:
vmImage: 'ubuntu-latest'
variables:
myVarFromDeploymentJob: $[ dependencies.A.outputs['deploy_10.setvarStep.myOutputVar'] ]
steps:
- script: "echo $(myVarFromDeploymentJob)"
name: echovar
För ett runOnce
jobb anger du namnet på jobbet i stället för livscykelkroken:
# Set an output variable in a lifecycle hook of a deployment job executing runOnce strategy.
- deployment: A
pool:
vmImage: 'ubuntu-latest'
environment: staging
strategy:
runOnce:
deploy:
steps:
- bash: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]this is the deployment variable value"
name: setvarStep
- bash: echo $(setvarStep.myOutputVar)
name: echovar
# Map the variable from the job.
- job: B
dependsOn: A
pool:
vmImage: 'ubuntu-latest'
variables:
myVarFromDeploymentJob: $[ dependencies.A.outputs['A.setvarStep.myOutputVar'] ]
steps:
- script: "echo $(myVarFromDeploymentJob)"
name: echovar
När du definierar en miljö i ett distributionsjobb varierar syntaxen för utdatavariabeln beroende på hur miljön definieras. I det här exemplet env1
använder du kortfattad notation och env2
innehåller den fullständiga syntaxen med en definierad resurstyp.
stages:
- stage: StageA
jobs:
- deployment: A1
pool:
vmImage: 'ubuntu-latest'
environment: env1
strategy:
runOnce:
deploy:
steps:
- bash: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]this is the deployment variable value"
name: setvarStep
- bash: echo $(System.JobName)
- deployment: A2
pool:
vmImage: 'ubuntu-latest'
environment:
name: env2
resourceName: vmsfortesting
resourceType: virtualmachine
strategy:
runOnce:
deploy:
steps:
- script: echo "##vso[task.setvariable variable=myOutputVarTwo;isOutput=true]this is the second deployment variable value"
name: setvarStepTwo
- job: B1
dependsOn: A1
pool:
vmImage: 'ubuntu-latest'
variables:
myVarFromDeploymentJob: $[ dependencies.A1.outputs['A1.setvarStep.myOutputVar'] ]
steps:
- script: "echo $(myVarFromDeploymentJob)"
name: echovar
- job: B2
dependsOn: A2
pool:
vmImage: 'ubuntu-latest'
variables:
myVarFromDeploymentJob: $[ dependencies.A2.outputs['A2.setvarStepTwo.myOutputVarTwo'] ]
myOutputVarTwo: $[ dependencies.A2.outputs['Deploy_vmsfortesting.setvarStepTwo.myOutputVarTwo'] ]
steps:
- script: "echo $(myOutputVarTwo)"
name: echovartwo
När du matar ut en variabel från ett jobb i steg ett används olika syntaxer beroende på om du vill ange en variabel eller använda den som ett villkor för fasen när du refererar till den från ett distributionsjobb i nästa steg.
stages:
- stage: StageA
jobs:
- job: A1
steps:
- pwsh: echo "##vso[task.setvariable variable=RunStageB;isOutput=true]true"
name: setvarStep
- bash: echo $(System.JobName)
- stage: StageB
dependsOn:
- StageA
# when referring to another stage, stage name is included in variable path
condition: eq(dependencies.StageA.outputs['A1.setvarStep.RunStageB'], 'true')
# Variables reference syntax differs slightly from inter-stage condition syntax
variables:
myOutputVar: $[stageDependencies.StageA.A1.outputs['setvarStep.RunStageB']]
jobs:
- deployment: B1
pool:
vmImage: 'ubuntu-latest'
environment: envB
strategy:
runOnce:
deploy:
steps:
- bash: echo $(myOutputVar)
När du matar ut en variabel från ett distributionsjobb använder du syntaxen stageDependencies för att referera till den från nästa steg (till exempel $[stageDependencies.<stage-name>.<job-name>.outputs[Deploy_<resource-name>.<step-name>.<variable-name>]]
).
stages:
- stage: StageA
jobs:
- deployment: A1
environment:
name: env1
resourceName: DevEnvironmentV
resourceType: virtualMachine
strategy:
runOnce:
deploy:
steps:
- script: echo "##vso[task.setvariable variable=myVar;isOutput=true]true"
name: setvarStep
- script: |
echo "Value of myVar in the same Job : $(setVarStep.myVar)"
displayName: 'Verify variable in StageA'
- stage: StageB
dependsOn: StageA
# Full Variables syntax for inter-stage jobs
variables:
myOutputVar: $[stageDependencies.StageA.A1.outputs['Deploy_DevEnvironmentV.setvarStep.myVar']]
jobs:
- deployment: B1
pool:
vmImage: 'ubuntu-latest'
environment: envB
strategy:
runOnce:
deploy:
steps:
- bash: echo $(myOutputVar)
Läs mer om hur du anger en utdatavariabel för flera jobb
Vanliga frågor
Min pipeline har fastnat med meddelandet "Jobbet väntar...". Hur kan jag åtgärda detta?
Detta kan inträffa när det finns en namnkonflikt mellan två jobb. Kontrollera att alla distributionsjobb i samma fas har ett unikt namn och att jobb- och stegnamnen inte innehåller nyckelord. Om du inte löser problemet genom att byta namn läser du felsökning av pipelinekörningar.
Stöds dekoratörer i distributionsgrupper?
Nej. Du kan inte använda dekoratörer i distributionsgrupper.