Поделиться через


Задания развертывания

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 deployrouteTrafficи 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, , deployrouteTrafficи 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 перехватчик жизненного цикла (выполнен один раз) и выполняет итерацию с routeTrafficdeployпомощью перехватчиков жизненного цикла и 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)

Дополнительные сведения о настройке переменной вывода с несколькими заданиями

Вопросы и ответы

Мой конвейер завис с сообщением "Задание ожидается...". Как это исправить?

Это может произойти, когда между двумя заданиями возникает конфликт имен. Убедитесь, что все задания развертывания на том же этапе имеют уникальное имя, а имена заданий и этапов не содержат ключевых слов. Если переименование не устраняет проблему, просмотрите запуски конвейера устранения неполадок.

Поддерживаются ли декораторы в группах развертывания?

№ Вы не можете использовать декораторы в группах развертывания.