Tugas penyebaran

Layanan Azure DevOps | Azure DevOps Server | Azure DevOps Server 2022

Penting

  • Nama pekerjaan dan tahap tidak boleh bertentangan dengan kata kunci yang dicadangkan (seperti deployment untuk jenis pekerjaan)
  • Setiap pekerjaan dalam satu tahap harus memiliki nama yang unik.

Dalam alur YAML, kami sarankan Anda menempatkan langkah-langkah penyebaran Anda dalam jenis pekerjaan khusus yang disebut pekerjaan penyebaran. Pekerjaan penyebaran adalah kumpulan langkah-langkah yang dijalankan secara berurutan terhadap lingkungan. Pekerjaan penyebaran dan pekerjaan tradisional dapat ada dalam tahap yang sama. Azure DevOps mendukung runOnce, rolling, dan canary strategies.

Tugas penyebaran memberikan manfaat berikut:

  • Riwayat penyebaran: Anda mendapatkan riwayat penyebaran di seluruh alur, hingga ke sumber daya dan status penyebaran tertentu untuk audit.
  • Menerapkan strategi penyebaran: Anda menentukan bagaimana aplikasi Anda diluncurkan.

Pekerjaan penyebaran tidak secara otomatis mengkloning repositori sumber. Anda dapat memeriksa repositori sumber dalam pekerjaan Anda dengan checkout: self.

Catatan

Artikel ini berfokus pada penyebaran melalui pekerjaan penyebaran. Untuk mempelajari cara menyebarkan ke Azure dengan jalur pipa, lihat Gambaran Umum Penyebaran ke Azure.

Skema

Pergi ke Skema YAML untuk mempelajari definisi jobs.deployment dan definisi jobs.deployment.environment.

Untuk komputer virtual, Anda tidak perlu menentukan kumpulan. Setiap langkah yang Anda tentukan dalam pekerjaan penyebaran dengan sumber daya mesin virtual dijalankan pada mesin virtual tersebut dan bukan pada agen di kumpulan. Untuk jenis sumber daya lain seperti Kubernetes, Anda perlu menentukan kumpulan sehingga tugas dapat berjalan pada komputer tersebut.

Strategi penerapan

Saat Anda menyebarkan pembaruan aplikasi, penting bahwa teknik yang Anda gunakan untuk memberikan pembaruan akan:

  • Aktifkan inisialisasi.
  • Sebarkan pembaruan.
  • Arahkan lalu lintas ke versi yang diperbarui.
  • Uji versi yang diperbarui setelah mengalihkan lalu lintas.
  • Jika terjadi kegagalan, jalankan langkah-langkah untuk memulihkan ke versi baik terakhir yang diketahui.

Kami mencapai ini dengan menggunakan kait siklus hidup yang dapat menjalankan langkah-langkah selama penyebaran. Setiap kait siklus hidup diselesaikan menjadi pekerjaan agen atau pekerjaan server (atau pekerjaan kontainer atau validasi di masa mendatang), tergantung pada pool atribut . Secara bawaan, kait siklus hidup mewarisi pool yang ditentukan oleh tugas deployment.

Tugas penyebaran menggunakan variabel sistem $(Pipeline.Workspace).

Deskripsi kait siklus hidup

preDeploy: Digunakan untuk menjalankan langkah-langkah yang menginisialisasi sumber daya sebelum penyebaran aplikasi dimulai.

deploy: Digunakan untuk menjalankan langkah-langkah yang menyebarkan aplikasi Anda. Tugas unduh artefak hanya disuntikkan secara otomatis di kait deploy untuk pekerjaan penyebaran. Untuk berhenti mengunduh artefak, gunakan - download: none atau pilih artefak tertentu untuk diunduh dengan menentukan tugas Unduh Artefak Alur.

routeTraffic: Digunakan untuk menjalankan tahapan yang mengalihkan trafik ke versi yang diperbarui.

postRouteTraffic: Digunakan untuk menjalankan langkah-langkah setelah lalu lintas dirutekan. Biasanya, tugas-tugas ini memantau kesehatan versi yang diperbarui untuk interval yang ditentukan.

on: failure atau on: success: Digunakan untuk menjalankan langkah-langkah dalam tindakan pemulihan kembali atau untuk membersihkan.

Strategi penyebaran RunOnce

runOnce adalah strategi penyebaran paling sederhana di mana semua kait siklus hidup, yaitu preDeploydeploy, routeTraffic, dan postRouteTraffic, dijalankan sekali. Lalu, antara on:success atau on:failure dijalankan.

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:
          ...

Jika Anda menggunakan agen yang dihost sendiri, Anda dapat menggunakan opsi bersih ruang kerja untuk membersihkan ruang kerja penyebaran Anda.

  jobs:
  - deployment: MyDeploy
    pool:
      vmImage: 'ubuntu-latest'
    workspace:
      clean: all
    environment: staging

Strategi penyebaran bergulir

Penyebaran bergulir menggantikan instans dari versi aplikasi sebelumnya dengan instans versi baru aplikasi pada sekumpulan komputer virtual tetap (set bergulir) di setiap iterasi.

Saat ini kami hanya mendukung strategi bergulir untuk sumber daya VM.

Misalnya, penyebaran bergulir biasanya menunggu penyebaran pada setiap set komputer virtual selesai sebelum melanjutkan ke serangkaian penyebaran berikutnya. Anda dapat melakukan pemeriksaan kesehatan setelah setiap perulangan dan jika masalah signifikan terjadi, penyebaran bergulir dapat dihentikan.

Penyebaran bergulir dapat dikonfigurasi dengan menentukan kata kunci rolling: di bawah simpul strategy: . Variabel strategy.name tersedia dalam blok strategi ini, yang mengambil nama strategi. Dalam hal ini, bergulir.

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:
        ...

Semua kait siklus hidup didukung dan tugas kait siklus hidup dibuat untuk dijalankan pada setiap VM.

preDeploy, , deployrouteTraffic, dan postRouteTraffic dijalankan sekali per ukuran batch yang ditentukan oleh maxParallel. Kemudian, baik on: success maupun on: failure dijalankan.

Dengan maxParallel: <# or % of VMs>, Anda dapat mengontrol jumlah/persentase target komputer virtual untuk disebarkan secara paralel. Ini memastikan bahwa aplikasi berjalan pada komputer ini dan mampu menangani permintaan saat penyebaran berlangsung di komputer lainnya, yang mengurangi waktu henti keseluruhan.

Catatan

Terdapat beberapa celah yang diketahui dalam fitur ini. Misalnya, saat Anda mencoba kembali tahapan, ia menjalankan kembali penyebaran pada semua VM bukan hanya target yang gagal.

Strategi penyebaran bertahap

Strategi penyebaran Canary adalah strategi penyebaran tingkat lanjut yang membantu mengurangi risiko yang terlibat dalam meluncurkan versi aplikasi baru. Dengan menggunakan strategi ini, Anda dapat meluncurkan perubahan ke sebagian kecil server terlebih dahulu. Saat Anda semakin percaya diri dengan versi baru, Anda dapat merilisnya ke lebih banyak server di infrastruktur Anda dan mengarahkan lebih banyak lalu lintas ke sana.

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:
          ...

Strategi penyebaran kenari mendukung preDeploy kait siklus hidup (dijalankan sekali) dan melakukan iterasi dengan deploykait siklus hidup , , routeTrafficdan postRouteTraffic . Kemudian mengakhiri dengan kait success atau failure.

Variabel berikut tersedia dalam strategi ini:

strategy.name: Nama strategi. Misalnya, kenari.
strategy.action: Tindakan yang akan dilakukan pada kluster Kubernetes. Misalnya, menyebarkan, mempromosikan, atau menolak.
strategy.increment: Nilai kenaikan yang digunakan dalam interaksi saat ini. Variabel ini hanya tersedia di deploy, routeTraffic, dan postRouteTraffic kait siklus hidup.

Contoh

Strategi penyebaran RunOnce

Contoh cuplikan YAML berikut menampilkan penggunaan sederhana dari job penyebaran dengan menggunakan strategi penyebaran runOnce. Contohnya mencakup tahap checkout.

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

Dengan setiap eksekusi pekerjaan ini, riwayat penyebaran dicatat di lingkungan smarthotel-dev.

Catatan

  • Anda juga dapat membuat lingkungan dengan sumber daya kosong dan menggunakannya sebagai shell abstrak untuk merekam riwayat penyebaran, seperti yang ditunjukkan pada contoh sebelumnya.

Contoh berikutnya menunjukkan bagaimana alur dapat merujuk lingkungan dan sumber daya yang akan digunakan sebagai target untuk pekerjaan penyebaran.

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)

Pendekatan ini memiliki manfaat berikut:

  • Merekam riwayat penyebaran pada sumber daya tertentu dalam lingkungan, dibandingkan dengan merekam riwayat pada semua sumber daya dalam lingkungan.
  • Langkah-langkah dalam pekerjaan penyebaran secara otomatis mewarisi detail koneksi sumber daya (dalam hal ini, namespace Kubernetes, smarthotel-dev.bookings), karena pekerjaan penyebaran ditautkan ke lingkungan. Ini berguna dalam kasus ketika detail koneksi yang sama diatur untuk beberapa langkah-langkah pekerjaan.

Catatan

Jika Anda menggunakan kluster AKS privat, pastikan Anda terhubung ke jaringan virtual kluster karena titik akhir server API tidak diekspos melalui alamat IP publik.

Azure Pipelines merekomendasikan untuk menyiapkan agen yang dihost sendiri dalam VNET yang memiliki akses ke jaringan virtual kluster. Lihat Opsi untuk menyambungkan ke kluster privat untuk detailnya.

Strategi penyebaran bergulir

Strategi bergulir untuk VM memperbarui hingga lima target di setiap iterasi. maxParallel menentukan jumlah target yang dapat disebarkan, secara paralel. Pilihan ini memperhitungkan jumlah mutlak atau persentase target yang harus tetap tersedia setiap saat, tidak termasuk target yang sedang disebarkan. Ini juga digunakan untuk menentukan kondisi keberhasilan dan kegagalan selama penyebaran.

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

Strategi penyebaran bertahap

Dalam contoh berikutnya, strategi kenari untuk AKS akan terlebih dahulu menyebarkan perubahan dengan 10 persen pod, diikuti oleh 20 persen, sambil memantau kesehatan selama postRouteTraffic. Jika semua berjalan dengan baik, itu akan mencapai 100 persen.

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...

Menggunakan dekorator alur untuk menyuntikkan langkah-langkah secara otomatis

Dekorator pipeline dapat digunakan dalam pekerjaan penyebaran untuk menyuntikkan secara otomatis langkah kustom apa pun (misalnya, pemindai kerentanan) ke setiap eksekusi hook siklus hidup dari setiap pekerjaan penyebaran. Karena dekorator alur dapat diterapkan ke semua alur dalam organisasi, ini dapat diterapkan sebagai bagian dari memberlakukan praktik penyebaran yang aman.

Selain itu, pekerjaan penyebaran dapat dijalankan sebagai pekerjaan kontainer bersamaan dengan layanan side-car jika telah ditentukan.

Dukungan untuk variabel output

Tentukan variabel output di lifecycle hooks dalam pekerjaan penyebaran dan manfaatkan variabel tersebut di langkah dan pekerjaan selanjutnya dalam tahap yang sama.

Untuk berbagi variabel antar tahap, keluarkan artefak dalam satu tahap lalu gunakan dalam tahap berikutnya, atau gunakan stageDependencies sintaks yang dijelaskan dalam variabel.

Saat menjalankan strategi penyebaran, Anda dapat mengakses variabel output di seluruh pekerjaan dengan menggunakan sintaks berikut.

  • Untuk strategi runOnce : $[dependencies.<job-name>.outputs['<job-name>.<step-name>.<variable-name>']] (misalnya, $[dependencies.JobA.outputs['JobA.StepA.VariableA']])
  • Untuk strategi runOnce dengan resourceType: $[dependencies.<job-name>.outputs['Deploy_<resource-name>.<step-name>.<variable-name>']]. (Contohnya, $[dependencies.JobA.outputs['Deploy_VM1.StepA.VariableA']])
  • Untuk strategi canary : $[dependencies.<job-name>.outputs['<lifecycle-hookname>_<increment-value>.<step-name>.<variable-name>']]
  • Untuk strategi bergulir : $[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 Untuk pekerjaan, tentukan nama pekerjaan alih-alih kait siklus hidup:

# 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

Saat Anda menentukan lingkungan dalam pekerjaan penyebaran, sintaks variabel output bervariasi tergantung pada bagaimana lingkungan ditentukan. Dalam contoh ini, env1 menggunakan notasi singkat dan env2 menyertakan sintaks penuh dengan jenis sumber daya yang ditentukan.

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

Saat Anda mengeluarkan variabel dari pekerjaan di tahap pertama, merujuknya dari pekerjaan penyebaran pada tahap berikutnya menggunakan sintaks yang berbeda tergantung pada apakah Anda ingin mengatur variabel atau menggunakannya sebagai kondisi untuk tahap tersebut.

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)

Saat Anda memunculkan variabel dari pekerjaan penyebaran, gunakan sintaks stageDependencies untuk mereferensikannya dari tahap selanjutnya (misalnya, $[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)

Pelajari selengkapnya tentang cara mengatur variabel output multi-pekerjaan

FAQ

Alur saya terjebak dengan pesan "Pekerjaan tertunda...". Bagaimana aku bisa memperbaiki ini?

Ini dapat terjadi ketika ada konflik nama antara dua pekerjaan. Verifikasi bahwa pekerjaan penyebaran apa pun dalam tahap yang sama memiliki nama yang unik dan nama pekerjaan dan tahapan tersebut tidak berisi kata kunci. Jika mengganti nama tidak memperbaiki masalah, tinjau pemecahan masalah pemrosesan pipeline.

Apakah dekorator didukung dalam grup penyebaran?

Tidak. Anda tidak dapat menggunakan dekorator dalam grup penyebaran.