Zadania wdrażania
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2020
Ważne
- Nazwy zadań i etapów nie mogą zawierać słów kluczowych (na przykład:
deployment
). - Każde zadanie na etapie musi mieć unikatową nazwę.
W przypadku potoków YAML zaleca się umieszczenie kroków wdrożenia w specjalnym typie zadania o nazwie zadanie wdrażania. Zadanie wdrożenia to kolekcja kroków, które są uruchamiane sekwencyjnie względem środowiska. Zadanie wdrożenia i tradycyjne zadanie mogą istnieć na tym samym etapie. Usługa Azure DevOps obsługuje strategie runOnce, rolling i kanary .
Zadania wdrożenia zapewniają następujące korzyści:
- Historia wdrożenia: uzyskujesz historię wdrożenia we wszystkich potokach, dla określonych zasobów i stanów wdrożeń na potrzeby inspekcji.
- Stosowanie strategii wdrożenia: definiujesz sposób wdrażania aplikacji.
Zadanie wdrożenia nie klonuje automatycznie repozytorium źródłowego. Możesz wyewidencjonować repozytorium źródłowe w ramach zadania za pomocą polecenia checkout: self
.
Uwaga
Ten artykuł koncentruje się na wdrażaniu z zadaniami wdrażania. Aby dowiedzieć się, jak wdrażać na platformie Azure za pomocą potoków, zobacz Wdrażanie na platformie Azure — omówienie.
Schemat
Oto pełna składnia określająca zadanie wdrożenia:
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 ]
Istnieje bardziej szczegółowa, alternatywna składnia, której można również użyć dla environment
właściwości .
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.
W przypadku maszyn wirtualnych nie trzeba definiować puli. Wszystkie kroki zdefiniowane w zadaniu wdrożenia z zasobem maszyny wirtualnej będą uruchamiane względem tej maszyny wirtualnej, a nie względem agenta w puli. W przypadku innych typów zasobów, takich jak Kubernetes, należy zdefiniować pulę, aby zadania mogły być uruchamiane na tym komputerze.
Strategie wdrażania
Podczas wdrażania aktualizacji aplikacji ważne jest, aby technika używana do dostarczania aktualizacji:
- Włącz inicjowanie.
- Wdróż aktualizację.
- Kierowanie ruchu do zaktualizowanej wersji.
- Przetestuj zaktualizowaną wersję po routingu ruchu.
- W przypadku awarii uruchom kroki przywracania do ostatniej znanej dobrej wersji.
Osiągamy to za pomocą punktów zaczepienia cyklu życia, które mogą uruchamiać kroki podczas wdrażania. Każdy z punktów zaczepienia cyklu życia jest rozpoznawany jako zadanie agenta lub zadanie serwera (albo kontener lub zadanie weryfikacji w przyszłości), w zależności od atrybutu pool
. Domyślnie haki cyklu życia będą dziedziczyć pool
określone przez deployment
zadanie.
Zadania wdrażania używają zmiennej $(Pipeline.Workspace)
systemowej.
Opisy punktów zaczepienia cyklu życia
preDeploy
: służy do uruchamiania kroków inicjowania zasobów przed rozpoczęciem wdrażania aplikacji.
deploy
: służy do uruchamiania kroków wdrażania aplikacji. Zadanie pobierania artefaktu zostanie automatycznie wprowadzone tylko w haczyku deploy
dla zadań wdrażania. Aby zatrzymać pobieranie artefaktów, użyj - download: none
lub wybierz określone artefakty do pobrania, określając zadanie Pobierz artefakt potoku.
routeTraffic
: służy do uruchamiania kroków obsługujących ruch do zaktualizowanej wersji.
postRouteTraffic
: służy do uruchamiania kroków po kierowaniu ruchu. Zazwyczaj te zadania monitorują kondycję zaktualizowanej wersji dla zdefiniowanego interwału.
on: failure
lub on: success
: służy do uruchamiania kroków dla akcji wycofywania lub czyszczenia.
Strategia wdrażania RunOnce
runOnce
jest najprostszą strategią wdrażania, w której wszystkie elementy zaczepienia cyklu życia, czyli preDeploy
deploy
, routeTraffic
i postRouteTraffic
, są wykonywane raz. Następnie wykonywana jest wartość on:
success
lub 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:
...
Jeśli używasz własnych agentów, możesz użyć opcji czyszczenia obszaru roboczego, aby wyczyścić obszar roboczy wdrożenia.
jobs:
- deployment: MyDeploy
pool:
vmImage: 'ubuntu-latest'
workspace:
clean: all
environment: staging
Strategia wdrażania stopniowego
Wdrożenie stopniowe zastępuje wystąpienia poprzedniej wersji aplikacji wystąpieniami nowej wersji aplikacji w stałym zestawie maszyn wirtualnych (zestaw kroczący) w każdej iteracji.
Obecnie obsługujemy tylko strategię stopniowej dla zasobów maszyny wirtualnej.
Na przykład wdrożenie stopniowe zwykle czeka na wdrożenia dla każdego zestawu maszyn wirtualnych do ukończenia przed przejściem do następnego zestawu wdrożeń. Możesz przeprowadzić kontrolę kondycji po każdej iteracji i jeśli wystąpi istotny problem, wdrożenie stopniowe można zatrzymać.
Wdrożenia stopniowe można skonfigurować, określając słowo kluczowe rolling:
w węźle strategy:
.
Zmienna strategy.name
jest dostępna w tym bloku strategii, który przyjmuje nazwę strategii. W tym przypadku stopniowe.
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:
...
Wszystkie haki cyklu życia są obsługiwane, a zadania punktów zaczepienia cyklu życia są tworzone do uruchamiania na każdej maszynie wirtualnej.
preDeploy
, , deploy
routeTraffic
i postRouteTraffic
są wykonywane raz na rozmiar partii zdefiniowany przez maxParallel
.
Następnie wykonywana jest wartość on: success
lub on: failure
.
Za pomocą programu maxParallel: <# or % of VMs>
można kontrolować liczbę/procent miejsc docelowych maszyn wirtualnych, aby wdrożyć je równolegle. Dzięki temu aplikacja jest uruchomiona na tych maszynach i może obsługiwać żądania, gdy wdrożenie odbywa się na pozostałych maszynach, co zmniejsza całkowity przestój.
Uwaga
Istnieje kilka znanych luk w tej funkcji. Na przykład ponawianie próby etapu spowoduje ponowne uruchomienie wdrożenia na wszystkich maszynach wirtualnych, które nie tylko nie zakończyły się niepowodzeniem.
Strategia wdrażania kanarkowego
Strategia wdrażania kanarowego to zaawansowana strategia wdrażania, która pomaga ograniczyć ryzyko związane z wdrażaniem nowych wersji aplikacji. Korzystając z tej strategii, można najpierw wdrożyć zmiany w małym podzestawie serwerów. Gdy zyskujesz większą pewność co do nowej wersji, możesz zwolnić ją na więcej serwerów w infrastrukturze i kierować do niej większy ruch.
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:
...
Strategia wdrażania kanarowego obsługuje preDeploy
punkt zaczepienia cyklu życia (wykonywany raz) i iteruje przy deploy
użyciu punktów zaczepienia , routeTraffic
i postRouteTraffic
cyklu życia. Następnie kończy się za pomocą haka success
lub failure
.
W tej strategii są dostępne następujące zmienne:
strategy.name
: nazwa strategii. Na przykład kanary.
strategy.action
: Akcja do wykonania w klastrze Kubernetes. Na przykład wdróż, podwyższ poziom lub odrzuć.
strategy.increment
: wartość przyrostowa używana w bieżącej interakcji. Ta zmienna jest dostępna tylko w deploy
punktach zaczepienia , routeTraffic
i postRouteTraffic
cyklu życia.
Przykłady
Strategia wdrażania RunOnce
Poniższy przykładowy fragment kodu YAML przedstawia proste użycie zadania wdrażania przy użyciu runOnce
strategii wdrażania. Przykład zawiera krok wyewidencjonowania.
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
W przypadku każdego uruchomienia tego zadania historia wdrożenia jest rejestrowana w smarthotel-dev
środowisku.
Uwaga
- Istnieje również możliwość utworzenia środowiska z pustymi zasobami i użycia go jako abstrakcyjnej powłoki do rejestrowania historii wdrożenia, jak pokazano w poprzednim przykładzie.
W następnym przykładzie pokazano, jak potok może odwoływać się zarówno do środowiska, jak i zasobu, który ma być używany jako element docelowy zadania wdrożenia.
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)
Ta metoda ma następujące zalety:
- Rejestruje historię wdrażania dla określonego zasobu w środowisku, w przeciwieństwie do rejestrowania historii na wszystkich zasobach w środowisku.
- Kroki w zadaniu wdrażania automatycznie dziedziczą szczegóły połączenia zasobu (w tym przypadku przestrzeń nazw Kubernetes),
smarthotel-dev.bookings
ponieważ zadanie wdrożenia jest połączone ze środowiskiem. Jest to przydatne w przypadkach, w których ten sam szczegół połączenia jest ustawiany dla wielu kroków zadania.
Uwaga
Jeśli używasz prywatnego klastra usługi AKS, upewnij się, że masz połączenie z siecią wirtualną klastra, ponieważ punkt końcowy serwera interfejsu API nie jest uwidoczniony za pośrednictwem publicznego adresu IP.
Usługa Azure Pipelines zaleca skonfigurowanie własnego agenta w sieci wirtualnej, która ma dostęp do sieci wirtualnej klastra. Aby uzyskać szczegółowe informacje, zobacz Opcje nawiązywania połączenia z klastrem prywatnym.
Strategia wdrażania stopniowego
Strategia stopniowej maszyn wirtualnych aktualizuje maksymalnie pięć elementów docelowych w każdej iteracji. maxParallel
Określi liczbę obiektów docelowych, które można wdrożyć równolegle. Wybór odpowiada bezwzględnej liczbie lub procentowi miejsc docelowych, które muszą pozostać dostępne w dowolnym momencie z wyłączeniem miejsc docelowych, do których są wdrażane. Służy również do określania warunków powodzenia i niepowodzenia podczas wdrażania.
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
Strategia wdrażania kanarkowego
W następnym przykładzie strategia kanargu dla usługi AKS najpierw wdroży zmiany z 10-procentowymi zasobnikami, a następnie 20 procentami, monitorując kondycję podczas wykonywania postRouteTraffic
operacji . Jeśli wszystko pójdzie dobrze, będzie promować do 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...
Automatyczne wstrzykiwanie kroków za pomocą dekoratorów potoków
Dekoratory potoków mogą być używane w zadaniach wdrażania w celu automatycznego wstrzykiwania dowolnego niestandardowego kroku (na przykład skanera luk w zabezpieczeniach) do każdego wykonania każdego zadania wdrażania w ramach cyklu życia. Ponieważ dekoratory potoków można stosować do wszystkich potoków w organizacji, można je stosować w ramach wymuszania bezpiecznych praktyk wdrażania.
Ponadto zadania wdrażania można uruchamiać jako zadanie kontenera wraz z samochodem bocznym usług, jeśli zostały zdefiniowane.
Obsługa zmiennych wyjściowych
Zdefiniuj zmienne wyjściowe w punktach zaczepienia cyklu życia zadania wdrożenia i używają ich w innych krokach podrzędnych i zadaniach w ramach tego samego etapu.
Aby udostępnić zmienne między etapami, wyprowadź artefakt w jednym etapie, a następnie użyj go w kolejnym etapie lub użyj składni opisanej stageDependencies
w zmiennych.
Podczas wykonywania strategii wdrażania można uzyskać dostęp do zmiennych wyjściowych między zadaniami przy użyciu następującej składni.
- W przypadku strategii runOnce :
$[dependencies.<job-name>.outputs['<job-name>.<step-name>.<variable-name>']]
(na przykład$[dependencies.JobA.outputs['JobA.StepA.VariableA']]
) - Dla strategii runOnce plus resourceType:
$[dependencies.<job-name>.outputs['Deploy_<resource-name>.<step-name>.<variable-name>']]
. (na przykład$[dependencies.JobA.outputs['Deploy_VM1.StepA.VariableA']]
) - Strategia kanarowa :
$[dependencies.<job-name>.outputs['<lifecycle-hookname>_<increment-value>.<step-name>.<variable-name>']]
- W przypadku strategii stopniowej :
$[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
runOnce
W przypadku zadania określ nazwę zadania zamiast haka cyklu życia:
# 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
Podczas definiowania środowiska w zadaniu wdrażania składnia zmiennej wyjściowej różni się w zależności od sposobu definiowania środowiska. W tym przykładzie env1
użyto notacji skróconej i env2
zawiera pełną składnię ze zdefiniowanym typem zasobu.
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
W przypadku wyprowadzania zmiennej z zadania w etapie drugim, odwoływanie się do niej z zadania wdrożenia na następnym etapie używa innej składni w zależności od tego, czy chcesz ustawić zmienną lub użyć jej jako warunku dla etapu.
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)
Podczas wyprowadzania zmiennej z zadania wdrażania użyj składni stageDependencies, aby odwoływać się do niej z następnego etapu (na przykład $[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)
Dowiedz się więcej na temat ustawiania zmiennej wyjściowej z wieloma zadaniami
Często zadawane pytania
Mój potok jest zablokowany z komunikatem "Zadanie jest oczekujące...". Jak rozwiązać ten problem?
Może się to zdarzyć, gdy występuje konflikt nazw między dwoma zadaniami. Sprawdź, czy wszystkie zadania wdrażania na tym samym etapie mają unikatową nazwę, a nazwy zadań i etapów nie zawierają słów kluczowych. Jeśli zmiana nazwy nie rozwiąże problemu, zapoznaj się z tematem Rozwiązywanie problemów z przebiegami potoku.
Czy dekoratory są obsługiwane w grupach wdrożeń?
L.p. Nie można używać dekoratorów w grupach wdrożeń.