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


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

Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2020

Внимание

  • Имена заданий и этапов не могут содержать ключевые слова (например: deployment).
  • Каждое задание на этапе должно иметь уникальное имя.

В конвейерах YAML мы рекомендуем размещать этапы развертывания в специальном типе задания, именуемом заданием развертывания. Задание развертывания — это набор этапов, которые последовательно выполняются в данной среде. Задание развертывания и традиционное задание могут существовать на том же этапе. Azure DevOps поддерживает стратегии runOnce, rolling и canary .

Преимущества выполнения заданий по развертыванию:

  • Журнал развертывания: Вы получаете историю развертывания по всем конвейерам, детализированную до конкретного ресурса и статуса развертываний для целей аудита.
  • Применение стратегии развертывания. Вы определяете способ развертывания приложения.

Задание развертывания не клонирует исходный репозиторий автоматически. Вы можете ознакомиться с исходным репозиторием в рамках вашей работы с checkout: self.

Примечание.

В этой статье рассматривается развертывание с задачами развертывания. Сведения о развертывании в Azure с помощью конвейеров см. в статье "Развертывание в Azure".

Схема

Перейдите к схеме YAML, чтобы просмотреть определения jobs.deployment и jobs.deployment.environment .

Для виртуальных машин не требуется определять пул. Все действия, определенные в задании развертывания с ресурсом виртуальной машины, выполняются на этой виртуальной машине, а не на агенте в пуле. Для других типов ресурсов, таких как Kubernetes, необходимо определить пул, чтобы задачи могли выполняться на этом компьютере.

Стратегии развертывания

При развертывании обновлений приложений важно, чтобы метод, используемый для доставки обновления:

  • Включить инициализацию.
  • Развертывание обновления.
  • Направить трафик на обновленную версию.
  • Протестируйте обновленную версию после маршрутизации трафика.
  • В случае сбоя выполните шаги по восстановлению до последней известной хорошей версии.

Мы делаем это с помощью хуков жизненного цикла, которые могут выполнять шаги во время развертывания. Каждый из хуков жизненного цикла разрешается в задание агента или задание сервера (или задание контейнера или проверки в будущем), в зависимости от атрибута 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:
          ...

Стратегия канареечного развертывания поддерживает 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@1
          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 рекомендует настроить самостоятельно размещённый агент в VNET, имеющей доступ к виртуальной сети кластера. Дополнительные сведения см. в разделе "Параметры подключения к частному кластеру ".

Стратегия последовательного развертывания

Последовательная стратегия для виртуальных машин обновляет до пяти целевых объектов в каждой итерации. 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 процентов модулей, затем увеличит до 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@1 
          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 и типа ресурса: $[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)

Узнайте больше о том, как настроить переменную вывода для нескольких заданий

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

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

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

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

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