Задания развертывания
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
или выберите определенные артефакты для скачивания, указав задачу "Скачать артефакт конвейера".
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
перехватчик жизненного цикла (выполняется один раз) и выполняет итерацию с deploy
обработчиками жизненного цикла , routeTraffic
и 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
), так как задание развертывания связано со средой. Это полезно в случаях, когда для нескольких шагов задания заданы одинаковые сведения о подключении.
Стратегия последовательного развертывания
Стратегия последовательного развертывания виртуальных машин обновляет до пяти целевых объектов в каждой итерации. 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
Стратегия канареечного развертывания
В следующем примере стратегия canary для 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['Deploy.StepA.VariableA']]
) - Для стратегии runOnce плюс resourceType:
$[dependencies.<job-name>.outputs['<job-name>_<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
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.myOutputVar'] ]
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)
Узнайте больше о том, как задать выходную переменную с несколькими заданиями.
Вопросы и ответы
Мой конвейер завис с сообщением "Задание ожидается...". Как это исправить?
Это может произойти при конфликте имен между двумя заданиями. Убедитесь, что все задания развертывания на одном этапе имеют уникальное имя, а имена заданий и стадий не содержат ключевых слов. Если переименование не устраняет проблему, ознакомьтесь с разделом Устранение неполадок при выполнении конвейера.
Поддерживаются ли декораторы в группах развертывания?
Нет. Декораторы нельзя использовать в группах развертывания.