Задания развертывания
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2020
Внимание
- Имена заданий и этапов не могут содержать ключевые слова (например:
deployment
). - Каждое задание на этапе должно иметь уникальное имя.
В конвейерах YAML мы рекомендуем размещать этапы развертывания в специальном типе задания, именуемом заданием развертывания. Задание развертывания — это набор этапов, которые последовательно выполняются в среде. Задание развертывания и традиционное задание могут существовать на том же этапе. Azure DevOps поддерживает стратегии runOnce, rolling и canary .
Задания развертывания обеспечивают следующие преимущества:
- Журнал развертывания. Предоставляется журнал развертывания в конвейерах вплоть до определенного ресурса и состояния развертываний для аудита.
- Применение стратегии развертывания. Вы определяете способ развертывания приложения.
Задание развертывания не клонирует исходный репозиторий автоматически. Вы можете извлечь исходный репозиторий в задании checkout: self
.
Примечание.
В этой статье рассматривается развертывание с заданиями развертывания. Сведения о развертывании в Azure с помощью конвейеров см. в статье "Развертывание в Azure".
Схема
Ниже приведен полный синтаксис для указания задания развертывания:
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 ]
Существует более подробный альтернативный синтаксис, который можно также использовать для 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.
Для виртуальных машин не требуется определять пул. Все действия, определенные в задании развертывания с ресурсом виртуальной машины, будут выполняться с этой виртуальной машиной, а не с агентом в пуле. Для других типов ресурсов, таких как Kubernetes, необходимо определить пул, чтобы задачи могли выполняться на этом компьютере.
Стратегии развертывания
При развертывании обновлений приложений важно, чтобы метод, используемый для доставки обновления:
- Включить инициализацию.
- Развертывание обновления.
- Маршрутизация трафика в обновленную версию.
- Протестируйте обновленную версию после маршрутизации трафика.
- В случае сбоя выполните шаги по восстановлению до последней известной хорошей версии.
Мы достигаем этого с помощью перехватчиков жизненного цикла, которые могут выполнять шаги во время развертывания. Каждый из перехватчиков жизненного цикла разрешается в задание агента или задание сервера (или контейнер или задание проверки в будущем), в зависимости от атрибута pool
. По умолчанию перехватчики жизненного цикла наследуют pool
указанные заданием deployment
.
Задания развертывания используют системную $(Pipeline.Workspace)
переменную.
Описание перехватчиков жизненного цикла
preDeploy
: используется для выполнения шагов, которые инициализируют ресурсы перед началом развертывания приложения.
deploy
: используется для выполнения шагов, которые развертывают приложение. Задача скачивания артефактов автоматически внедряется только в deploy
перехватчик для заданий развертывания. Чтобы остановить загрузку артефактов, используйте - download: none
или выберите определенные артефакты для скачивания, указав задачу download Pipeline Artifact.
routeTraffic
: используется для выполнения шагов, которые служат трафику обновленной версии.
postRouteTraffic
: используется для выполнения шагов после маршрутизации трафика. Как правило, эти задачи отслеживают работоспособность обновленной версии для определенного интервала.
on: failure
или on: success
: используется для выполнения шагов для действий отката или очистки.
Стратегия развертывания RunOnce
runOnce
— это простейшая стратегия развертывания, в которой выполняются все перехватчики жизненного цикла, а именно preDeploy
deploy
routeTraffic
и postRouteTraffic
один раз. После этого выполняется on:
success
или 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:
...
Если вы используете локальные агенты, можно использовать параметры очистки рабочей области для очистки рабочей области развертывания.
jobs:
- deployment: MyDeploy
pool:
vmImage: 'ubuntu-latest'
workspace:
clean: all
environment: staging
Стратегия последовательного развертывания
Последовательное развертывание заменяет экземпляры предыдущей версии приложения экземплярами новой версии приложения на фиксированном наборе виртуальных машин (скользящий набор) в каждой итерации.
В настоящее время мы поддерживаем только последовательную стратегию для ресурсов виртуальных машин.
Например, последовательное развертывание обычно ожидает развертывания на каждом наборе виртуальных машин, прежде чем переходить к следующему набору развертываний. Вы можете выполнить проверку работоспособности после каждой итерации и при возникновении существенной проблемы, последовательное развертывание может быть остановлено.
Последовательное развертывание можно настроить, указав ключевое слово rolling:
под strategy:
узлом.
Переменная strategy.name
доступна в этом блоке стратегии, которая принимает имя стратегии. В этом случае прокатка.
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:
...
Поддерживаются все перехватчики жизненного цикла, а задания перехватчика жизненного цикла создаются для запуска на каждой виртуальной машине.
preDeploy
, , deploy
routeTraffic
и postRouteTraffic
выполняются один раз на каждый пакетный размер, определенныйmaxParallel
.
После этого выполняется on: success
или on: failure
.
С помощью maxParallel: <# or % of VMs>
функции можно управлять числом и процентом целевых объектов виртуальной машины для параллельного развертывания. Это гарантирует, что приложение работает на этих компьютерах и может обрабатывать запросы во время развертывания на остальных компьютерах, что снижает общее время простоя.
Примечание.
В этой функции есть несколько известных пробелов. Например, при повторном выполнении этапа он повторно запустит развертывание на всех виртуальных машинах, а не только сбой целевых объектов.
Стратегия канареечного развертывания
Стратегия развертывания canary — это расширенная стратегия развертывания, которая помогает снизить риск, связанный с развертыванием новых версий приложений. С помощью этой стратегии можно сначала развернуть изменения в небольшом подмножестве серверов. По мере того, как вы обретете больше уверенности в новой версии, вы сможете выпустить ее на другие сервера в своей инфраструктуре и направить на нее больше трафика.
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:
...
Стратегия развертывания canary поддерживает preDeploy
перехватчик жизненного цикла (выполнен один раз) и выполняет итерацию с routeTraffic
deploy
помощью перехватчиков жизненного цикла и postRouteTraffic
перехватчиков жизненного цикла. Затем он выходит с помощью либо success
failure
крючка.
В этой стратегии доступны следующие переменные:
strategy.name
: имя стратегии. Например, канарея.
strategy.action
: действие, выполняемое в кластере Kubernetes. Например, развертывание, повышение или отклонение.
strategy.increment
: значение увеличения, используемое в текущем взаимодействии. Эта переменная доступна только в deploy
, routeTraffic
а postRouteTraffic
также в перехватчиках жизненного цикла.
Примеры
Стратегия развертывания RunOnce
В следующем примере фрагмента КОДА YAML демонстрируется простое использование задания развертывания с помощью runOnce
стратегии развертывания. В этом примере содержится шаг выхода.
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
При каждом выполнении этого задания журнал развертывания записывается в smarthotel-dev
среду.
Примечание.
- Кроме того, можно создать среду с пустыми ресурсами и использовать ее в качестве абстрактной оболочки для записи журнала развертывания, как показано в предыдущем примере.
В следующем примере показано, как конвейер может ссылаться как на среду, так и на ресурс, который будет использоваться в качестве целевого объекта для задания развертывания.
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)
Этот подход имеет следующие преимущества:
- Записывает журнал развертывания для определенного ресурса в среде, а не запись журнала во всех ресурсах в среде.
- Действия в задании развертывания автоматически наследуют сведения о подключении ресурса (в данном случае пространство имен Kubernetes),
smarthotel-dev.bookings
так как задание развертывания связано с средой. Это полезно в тех случаях, когда для задания задано одно и то же значение соединения.
Примечание.
Если вы используете частный кластер AKS, убедитесь, что вы подключены к виртуальной сети кластера, так как конечная точка сервера API не предоставляется через общедоступный IP-адрес.
Azure Pipelines рекомендует настроить локальный агент в виртуальной сети с доступом к виртуальной сети кластера. Дополнительные сведения см. в разделе "Параметры подключения к частному кластеру ".
Стратегия последовательного развертывания
Последовательная стратегия для виртуальных машин обновляет до пяти целевых объектов в каждой итерации. maxParallel
определяет количество целевых объектов, для которых развертывание может выполняться параллельно. При выборе учитывается абсолютное количество или доля целевых объектов, которые в любое время должны оставаться доступными (кроме целевых объектов, для которых выполняется развертывание). При этом также учитываются условия, определяющие выполнение и невыполнение развертывания.
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
Стратегия канареечного развертывания
В следующем примере канарская стратегия AKS сначала развернет изменения с 10-процентными модулями pod, за которыми следует 20 процентов, а также мониторинг работоспособности во время postRouteTraffic
. Если все идет хорошо, это будет способствовать до 100 процентов.
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...
Автоматическое внедрение шагов с помощью декораторов конвейера
Декораторы конвейеров можно использовать в заданиях развертывания для автоматического внедрения любого пользовательского шага (например, сканера уязвимостей) для каждого перехватчика жизненного цикла каждого задания развертывания. Так как декораторы конвейеров можно применять ко всем конвейерам в организации, это можно применять как часть применения безопасных методов развертывания.
Кроме того, задания развертывания можно запускать как задание контейнера вместе со службами на стороне автомобиля , если определено.
Поддержка выходных переменных
Определите выходные переменные в перехватчиках жизненного цикла задания развертывания и потребляют их в других подчиненных шагах и заданиях на том же этапе.
Чтобы совместно использовать переменные между этапами, выведите артефакт на одном этапе, а затем используйте его на следующем этапе или используйте синтаксис, описанный stageDependencies
в переменных.
При выполнении стратегий развертывания можно получить доступ к выходным переменным между заданиями с помощью следующего синтаксиса.
- Для стратегии runOnce :
$[dependencies.<job-name>.outputs['<job-name>.<step-name>.<variable-name>']]
(например,$[dependencies.JobA.outputs['JobA.StepA.VariableA']]
) - Для стратегии runOnce плюс resourceType:
$[dependencies.<job-name>.outputs['Deploy_<resource-name>.<step-name>.<variable-name>']]
(например,$[dependencies.JobA.outputs['Deploy_VM1.StepA.VariableA']]
) - Для канарной стратегии:
$[dependencies.<job-name>.outputs['<lifecycle-hookname>_<increment-value>.<step-name>.<variable-name>']]
- Для последовательной стратегии:
$[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
Для задания укажите имя задания вместо перехватчика жизненного цикла:
# 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
При определении среды в задании развертывания синтаксис выходной переменной зависит от способа определения среды. В этом примере env1
используется сокращенная нотация и env2
включает полный синтаксис с определенным типом ресурса.
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
При выходе переменной из задания на одном этапе, ссылка на нее из задания развертывания на следующем этапе использует другой синтаксис в зависимости от того, нужно ли задать переменную или использовать ее в качестве условия для этапа.
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)
При выходе переменной из задания развертывания используйте синтаксис stageDependencies, чтобы ссылаться на нее на следующем этапе (например, $[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)
Дополнительные сведения о настройке переменной вывода с несколькими заданиями
Вопросы и ответы
Мой конвейер завис с сообщением "Задание ожидается...". Как это исправить?
Это может произойти, когда между двумя заданиями возникает конфликт имен. Убедитесь, что все задания развертывания на том же этапе имеют уникальное имя, а имена заданий и этапов не содержат ключевых слов. Если переименование не устраняет проблему, просмотрите запуски конвейера устранения неполадок.
Поддерживаются ли декораторы в группах развертывания?
№ Вы не можете использовать декораторы в группах развертывания.