全部产品
Search
文档中心

Microservices Engine:Implementasi rilis canary end-to-end menggunakan pipeline CI/CD di Jenkins

更新时间:Jul 06, 2025

Anda dapat menggunakan Jenkins untuk membangun pipeline CI/CD dan mengimplementasikan rilis canary end-to-end. Setelah menggunakan skrip pipeline untuk mengintegrasikan tahap pembuatan, penyebaran, dan pengujian ke dalam satu proses, Anda dapat menentukan langkah-langkah selanjutnya berdasarkan hasil rilis canary. Jika versi baru terbukti stabil, Anda dapat menyesuaikan aturan routing untuk secara bertahap meningkatkan persentase trafik canary yang diarahkan ke versi baru hingga semua trafik beralih ke versi tersebut. Jika ditemukan masalah pada versi baru, segera lakukan rollback ke versi lama dan perbaiki masalah tersebut. Proses ini mengotomatiskan manajemen dari tahap pembuatan hingga rilis canary, memastikan keamanan dan stabilitas pembaruan layanan.

Arsitektur keseluruhan

Dalam kebanyakan kasus, Anda dapat melakukan rilis canary berdasarkan salah satu item berikut:

  • Persentase tertentu dari trafik.

  • Aturan tertentu, seperti header atau cookie tertentu.

  • Tag yang digunakan untuk menandai trafik canary dan ditampilkan di klien atau browser web. Misalnya, Anda dapat menggunakan tag yang dibawa dalam header.

Gambar berikut menunjukkan proses rilis canary dari demo yang dijelaskan dalam topik ini.

Persiapan

Aktifkan Microservices Governance untuk aplikasi mikro di kluster ACK

  1. Aktifkan Microservices Governance. Untuk informasi lebih lanjut, lihat Aktifkan Microservices Governance.

  2. Aktifkan Microservices Governance untuk aplikasi mikro di kluster Container Service for Kubernetes (ACK). Untuk informasi lebih lanjut, lihat Aktifkan Microservices Governance untuk Aplikasi Mikro di Kluster ACK.

Sebarkan aplikasi demo

  1. Masuk ke Konsol ACK. Di panel navigasi di sebelah kiri, klik Clusters.

  2. Di halaman Clusters, temukan kluster yang ingin Anda kelola dan klik nama kluster tersebut atau pilih Details di kolom Actions. Halaman detail kluster akan muncul.

  3. Di panel navigasi di sebelah kiri halaman detail, pilih Workloads > Deployments.

  4. Di halaman Deployments, klik Create from YAML.

  5. Konfigurasikan parameter dan klik Create.

    Dalam contoh ini, aplikasi berikut diterapkan: spring-cloud-a (Aplikasi A), spring-cloud-b (Aplikasi B), spring-cloud-c (Aplikasi C), nacos-server, dan spring-cloud-zuul. Aplikasi nacos-server diterapkan sebagai registri dan aplikasi spring-cloud-zuul diterapkan sebagai aplikasi ingress. Aplikasi dipanggil dalam urutan berikut: spring-cloud-zuul -> spring-cloud-a -> spring-cloud-b -> spring-cloud-c.

    Aplikasi spring-cloud-zuul menangani default 100 QPS dan tambahan 10 QPS untuk permintaan yang dilampirkan dengan header x-mse-tag: gray. Header ini adalah header canary bawaan di MSE. Jika permintaan dilampirkan dengan header x-mse-tag: gray setelah Microservices Governance diaktifkan dan agen diinstal, permintaan yang dilampirkan dengan header ini secara otomatis diarahkan ke node hilir yang ditandai dengan gray. Anda dapat mengganti gray dengan nilai tag node lainnya sesuai dengan kebutuhan bisnis Anda.

    • Kode Yet Another Markup Language (YAML) untuk aplikasi ingress spring-cloud-zuul

      Show code

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: spring-cloud-zuul
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: spring-cloud-zuul
        template:
          metadata: 
            labels:
              app: spring-cloud-zuul
              msePilotCreateAppName: spring-cloud-zuul
          spec:
            containers:
              - name: spring-cloud-zuul
                image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-zuul:1.0.1
                imagePullPolicy: Always
                ports:
                  - containerPort: 20000
    • Kode YAML untuk versi dasar spring-cloud-a

      Show code

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: spring-cloud-a
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: spring-cloud-a
        template:
          metadata:
            labels:
              app: spring-cloud-a
              msePilotCreateAppName: spring-cloud-a
          spec:
            containers:
            - name: spring-cloud-a
              image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOT
              imagePullPolicy: Always
              ports:
              - containerPort: 20001
              livenessProbe:
                tcpSocket:
                  port: 20001
                initialDelaySeconds: 10
                periodSeconds: 30
    • Kode YAML untuk versi dasar spring-cloud-b

      Show code

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: spring-cloud-b
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: spring-cloud-b
        strategy:
        template:
          metadata: 
            labels:
              app: spring-cloud-b
              msePilotCreateAppName: spring-cloud-b
          spec:
            containers:
            - name: spring-cloud-b
              image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:0.1-SNAPSHOT
              imagePullPolicy: Always
              ports:
              - containerPort: 8080
              livenessProbe:
                tcpSocket:
                  port: 20002
                initialDelaySeconds: 10
                periodSeconds: 30
    • Kode YAML untuk versi dasar spring-cloud-c

      Show code

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: spring-cloud-c
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: spring-cloud-c
        template:
          metadata:  
            labels:
              app: spring-cloud-c
              msePilotCreateAppName: spring-cloud-c
          spec:
            containers:
            - name: spring-cloud-c
              image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:0.1-SNAPSHOT
              imagePullPolicy: Always
              ports:
              - containerPort: 20003
              livenessProbe:
                tcpSocket:
                  port: 20003
                initialDelaySeconds: 10
                periodSeconds: 30
    • Kode YAML untuk nacos-server

      Show code

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: nacos-server
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: nacos-server
        template:
          metadata:
            labels:
              app: nacos-server
          spec:
            containers:
            - env:
              - name: MODE
                value: standalone
              image: nacos/nacos-server:v2.2.0
              imagePullPolicy: Always
              name: nacos-server
            dnsPolicy: ClusterFirst
            restartPolicy: Always
      
      # Buat instance Server Load Balancer (SLB) untuk aplikasi spring-cloud-zuul.
      ---
      apiVersion: v1
      kind: Service
      metadata:
        annotations:
          service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small
        name: zuul-slb
      spec:
        ports:
          - port: 80
            protocol: TCP
            targetPort: 20000
        selector:
          app: spring-cloud-zuul
        type: LoadBalancer
  6. Setelah aplikasi diterapkan, lihat trafik yang melewati Aplikasi A di Konsol MSE, dan verifikasi bahwa semua trafik diarahkan ke node untagged dan tidak ada trafik yang diarahkan ke node canary.

Konfigurasikan izin untuk mendorong gambar ke repositori gambar

Dalam contoh ini, kode sumber perlu dikemas menjadi gambar dan kemudian didorong ke repositori gambar. Pastikan Jenkins memiliki izin untuk mendorong gambar ke repositori gambar. Untuk informasi lebih lanjut, lihat Sebarkan Jenkins di Kluster ACK dan Buat serta Sebarkan Aplikasi.

Buat jalur

  1. Masuk ke Konsol MSE, dan pilih wilayah di bilah navigasi atas.

  2. Di panel navigasi di sebelah kiri, pilih Microservices Governance > Full link grayscale.

  3. Di halaman Full link grayscale, klik Create Lane Group and Lane. Jika grup jalur tersedia di namespace mikro yang Anda pilih, klik + Create Lane Group.

  4. Di panel Create Lane Group, pilih aplikasi ingress dan aplikasi yang terlibat dalam proses panggilan, lalu klik OK.

    Parameter

    Deskripsi

    Lane Group Name

    Masukkan nama untuk grup jalur.

    Ingress Type

    Pilih Java Microservice Gateway.

    Lane Group Traffic Entry

    Pilih aplikasi ingress Anda dari daftar drop-down.

    Lane Group Application

    Pilih semua aplikasi yang terkait dengan aplikasi ingress atau gateway ingress Anda.

    Setelah grup jalur dibuat, grup jalur ditampilkan di bagian applications involved in the lane group di halaman Full link grayscale. Periksa apakah aplikasi ingress dan aplikasi yang terlibat telah dipilih dengan benar. Untuk mengedit informasi tentang grup jalur, klik 编辑 dan edit informasi tersebut.

  5. Di halaman Full link grayscale, pilih namespace mikro yang sama dengan grup jalur yang Anda buat. Di bagian bawah halaman, klik Click to Create First Split Lane.

    Jika jalur tersedia di namespace mikro yang Anda pilih, Anda dapat mengklik Create Lane.

    Penting

    Setelah Anda mengonfigurasi rilis canary end-to-end untuk aplikasi, aplikasi tersebut tidak lagi mendukung fitur seperti rilis canary dan routing berbasis tag.

  6. Di panel Create Lane, konfigurasikan parameter dan tambahkan aplikasi yang cocok dengan aturan ke jalur abu-abu. Lalu, klik OK.

    Parameter

    Deskripsi

    Add Node Tag

    Tambahkan tag secara manual untuk node aplikasi canary Anda. Tag ini digunakan untuk membedakan node tersebut dari node lainnya.

    Enter lane information

    Tag Jalur: tag trafik yang cocok di jalur.

    Konfirmasi Hubungan Pencocokan: memungkinkan Anda memeriksa apakah jumlah node aplikasi yang ditandai sesuai dengan harapan.

    Konfigurasikan Routing dan Aturan Rilis Canary

    • Path: path yang akan dicocokkan. Anda dapat memilih beberapa path. Jika Anda tidak menentukan parameter ini, path acak akan dicocokkan.

    • Mode Kondisi: hubungan antara kondisi routing.

    • Kondisi

      • Tipe Parameter: sumber parameter. Nilai valid: Parameter (parameter permintaan), Header (header permintaan), Cookie, dan Body Content (badan permintaan dalam format JSON).

      • Parameter: nama parameter.

      • Kondisi: aturan pencocokan.

      • Nilai: nilai yang digunakan untuk mencocokkan parameter.

Penting

Trafik yang tidak memenuhi kondisi diarahkan ke node aplikasi tanpa tag di versi dasar.

Setelah konfigurasi selesai, gateway mengarahkan trafik berdasarkan aturan tertentu.

  • Trafik yang tidak memenuhi aturan untuk rilis canary diarahkan ke versi dasar.1

  • Trafik yang memenuhi aturan untuk rilis canary diarahkan ke versi canary.1

Konfigurasikan pipeline Jenkins

Dalam contoh ini, kode sumber perlu dikemas menjadi gambar dan kemudian didorong ke repositori gambar. Pastikan Jenkins memiliki izin untuk mendorong gambar ke repositori gambar. Untuk informasi lebih lanjut, lihat Siapkan Jenkins untuk Membangun Pipeline Pengiriman Aplikasi.

Buat Secret bernama jenkins-docker-cfg di namespace Jenkins dengan menggunakan file config.json yang dihasilkan.

kubectl create secret generic jenkins-docker-cfg -n jenkins --from-file=/root/.docker/config.json

Buat pipeline rilis canary end-to-end di Jenkins

Anda dapat menggunakan pipeline Jenkins untuk pelepasan otomatis. Pipeline dapat menyediakan kemampuan rilis canary, observabilitas, dan rollback untuk pelepasan aplikasi guna memastikan keamanan produksi.

  1. Di panel navigasi di sebelah kiri dasbor Jenkins, klik New Item.

  2. Masukkan item name, pilih pipeline, dan kemudian klik OK.

  3. Di halaman yang muncul, klik tab Pipeline. Di tab Pipeline, konfigurasikan parameter, masukkan jalur di bidang Script Path, dan kemudian klik Save.

    • Definition: Pilih Pipeline script from SCM dari daftar drop-down.

    • SCM: Pilih Git dari daftar drop-down.

    • Repository URL: Masukkan URL repositori Git. Dalam contoh ini, URL repositori adalah https://github.com/aliyun/alibabacloud-microservice-demo/tree/master/mse-simple-demo.

      Catatan

      Alibaba Cloud tidak dapat menarik kode sumber dari GitHub. Dalam hal ini, kode sumber dari Gitee digunakan sebagai gantinya.

    • Script Path: Masukkan Jenkinsfile.

      Konfigurasi parameter berikut disediakan untuk referensi Anda. Anda juga dapat mengedit Jenkinsfile dan menambahkan file tersebut ke jalur yang ditentukan di repositori Git. Jalur ini adalah jalur skrip yang ditentukan dari pipeline.

      Show code

      #!groovy
      pipeline {
      
          // Tentukan tag lingkungan build. Dalam contoh ini, slave-pipeline digunakan.
          agent{
              node{
                label 'slave-pipeline'
              }
          }
      
          // Parameter konstan. Dalam kebanyakan kasus, parameter ini tidak perlu dimodifikasi setelah ditentukan.
          environment{
              IMAGE = sh(returnStdout: true,script: 'echo registry.$image_region.aliyuncs.com/$image_namespace/$image_reponame:$image_tag').trim()
              BRANCH =  sh(returnStdout: true,script: 'echo $branch').trim()
          }
          options {
              // Pertahankan jumlah maksimum build.
              buildDiscarder(logRotator(numToKeepStr: '10'))
          }
      
          parameters {
              string(name: 'image_region', defaultValue: 'cn-shanghai')
              string(name: 'image_namespace', defaultValue: 'yizhan')
              string(name: 'image_reponame', defaultValue: 'spring-cloud-a')
              string(name: 'image_tag', defaultValue: 'gray')
              string(name: 'branch', defaultValue: 'master')
              string(name: 'number_of_pods', defaultValue: '2')
          }
      
          // Lewati setiap tahap pipeline.
          stages {
      
              stage('Pengemasan kode') {
                  steps{
                      container("maven") {
                          echo "Membangun gambar......"
                          sh "cd A && mvn clean package"
                      }
      
                  }
              }
      
      
              stage('Pembuatan dan pelepasan gambar'){
                steps{
                    container("kaniko") {
                        sh "kaniko -f `pwd`/A/Dockerfile -c `pwd`/A --destination=${IMAGE} --skip-tls-verify"
                    }
                }
              }
      
      
      
              stage('Penyebaran canary') {
                  steps{
                      container('kubectl') {
                          echo "Penyebaran canary......"
                          sh "cd A && sed -i -E \"s/${env.image_reponame}:.+/${env.image_reponame}:${env.image_tag}/\" A-gray-deployment.yaml"
                          sh "cd A && sed -i -E \"s/replicas:.+/replicas: ${env.number_of_pods}/\" A-gray-deployment.yaml"
                          sh "kubectl apply -f A/A-gray-deployment.yaml -n default"
                      }
                  }
              }
      
              stage('Menyelesaikan penyebaran canary') {
                  input {
                      message "Apakah Anda yakin ingin mengaktifkan pelepasan penuh"
                      ok "OK"
                      parameters {
                          string(name: 'continue', defaultValue: 'true', description: 'true menunjukkan pelepasan penuh, dan false menunjukkan rollback')
                      }
                  }
                  steps{
                      script {
                          env.continue = sh (script: 'echo ${continue}', returnStdout: true).trim()
                          if (env.continue.equals('true')) {
                              container('kubectl') {
                                  echo "Pelepasan penuh......"
                                  sh "cd A && sed -i -E \"s/${env.image_reponame}:.+/${env.image_reponame}:${env.image_tag}/\" A-deployment.yaml"
                                  sh "cd A && sed -i -E \"s/replicas:.+/replicas: ${env.number_of_pods}/\" A-deployment.yaml"
                                  sh "kubectl apply -f A/A-deployment.yaml -n default"
                              }
                          } else {
                              echo 'Melakukan rollback'
                          }
                          container('kubectl') {
                              sh "kubectl delete -f A/A-gray-deployment.yaml -n default"
                          }
                      }
                  }
              }
          }
      }
                                          

Bangun pipeline Jenkins

  1. Di dasbor Jenkins, klik 构建 di sebelah kanan pipeline.

  2. Klik Build.

    Catatan

    Jika Anda membangun pipeline Jenkins untuk pertama kali, Anda harus menarik konfigurasi dari repositori Git dan menginisialisasi pipeline. Jika terjadi kesalahan selama proses ini, Anda dapat mengklik Build with Parameters untuk menghasilkan parameter yang relevan, tentukan parameter tersebut, dan kemudian bangun pipeline Jenkins lagi.

    Lihat status penyebaran. Tahap code packaging, image building and releasing, dan canary deployment telah selesai, dan tahap untuk completing the canary deployment menunggu konfirmasi.

Verifikasi hasil

  1. Masuk ke Konsol ACK. Di panel navigasi di sebelah kiri, klik Clusters.

  2. Di halaman Clusters, temukan kluster yang ingin Anda kelola dan klik namanya. Di panel sebelah kiri, pilih Workloads > Deployments.

  3. Di halaman Deployments, konfirmasikan bahwa aplikasi spring-cloud-a-gray yang dibuat ditampilkan dan versi gambarnya diganti dengan versi spring-cloud-a:gray.

  4. Di halaman detail kluster, pilih Network > Services, pilih namespace yang diperlukan, dan kemudian klik public endpoint dari layanan zuul-slb untuk melihat hasil panggilan aktual.

    • Jika Anda menggunakan header non-canary, trafik diarahkan ke node untuk versi dasar spring-cloud-a.

      • Perintah curl:

        curl http://182.92.XX.XX/A/a
      • Output:

        A[10.4.XX.XX] -> B[10.4.XX.XX] -> C[10.4.XX.XX]%
    • Jika Anda menggunakan header dengan tag rilis canary, trafik diarahkan ke node canary spring-cloud-a.

      • Perintah curl:

        curl http://182.92.XX.XX/A/a?name=xiaoming
      • Output:

        Agray[10.4.XX.XX] -> B[10.4.XX.XX] -> C[10.4.XX.XX]%
  5. Masuk ke Konsol MSE. Di halaman application details, konfirmasikan bahwa trafik canary diarahkan ke node canary.

Lakukan pelepasan penuh aplikasi

Setelah hasilnya lolos verifikasi, konfirmasikan untuk melakukan pelepasan penuh aplikasi.

  1. Di dasbor Jenkins, klik nama pipeline yang diinginkan.

  2. Klik tahap tempat Anda ingin mengaktifkan pelepasan penuh, masukkan true di kotak dialog Are you sure that you want to enable a full release, dan kemudian klik OK.

  3. Di Konsol ACK, konfirmasikan bahwa aplikasi spring-cloud-a-gray dihapus dan versi gambarnya diganti dengan versi spring-cloud-a:gray.

  4. Di Konsol MSE, konfirmasikan bahwa trafik canary menghilang.

Rollback aplikasi

Rollback aplikasi jika hasilnya tidak lolos verifikasi.

  1. Di dasbor Jenkins, klik nama pipeline yang diinginkan.

  2. Klik tahap tempat Anda ingin menonaktifkan pelepasan penuh, masukkan false di kotak dialog Are you sure that you want to enable a full release, dan kemudian klik OK.

  3. Di Konsol ACK, konfirmasikan bahwa aplikasi spring-cloud-a-gray dihapus dan versi gambarnya tetap pada versi aslinya.

  4. Di Konsol MSE, konfirmasikan bahwa trafik canary tidak ada.