All Products
Search
Document Center

Container Service for Kubernetes:Implementasikan rilis bertahap dan penyebaran biru-hijau dengan Nginx Ingress

Last Updated:Jun 16, 2026

Alihkan lalu lintas secara bertahap ke versi layanan baru berdasarkan header, cookie, atau bobot sebelum beralih sepenuhnya.

Latar Belakang

Baik rilis bertahap (juga disebut rilis canary) maupun penyebaran biru-hijau menjalankan versi baru secara bersamaan dengan versi lama dan mengarahkan sebagian lalu lintas ke versi baru tersebut. Setelah stabil, seluruh lalu lintas dialihkan dan versi lama dihentikan.

ACK Nginx Ingress Controller mendukung dua metode pemisahan lalu lintas berbasis anotasi:

Metode Status Catatan
canary-* annotations Aktif Metode resmi dari komunitas. Gunakan metode ini untuk semua konfigurasi baru.
service-* annotations Tidak digunakan lagi Tidak tersedia lagi di Nginx Ingress Controller v1.12 dan seterusnya. Jangan gunakan.

Kasus Penggunaan

  • Pemisahan lalu lintas berdasarkan permintaan klien: Arahkan lalu lintas ke versi baru hanya ketika permintaan berisi header atau cookie tertentu—misalnya, foo=bar. Permintaan lain tetap diarahkan ke versi lama. Setelah stabil, alihkan seluruh lalu lintas.

    image

  • Pemisahan lalu lintas berdasarkan bobot layanan: Arahkan persentase tetap lalu lintas—misalnya, 20%—ke versi baru. Tingkatkan persentase secara bertahap hingga seluruh lalu lintas dialihkan ke versi baru.

    image

Dimensi pemisahan lalu lintas yang didukung:

  • Header permintaan — cocok untuk rilis bertahap dan Pengujian A/B

  • Cookie — cocok untuk rilis bertahap dan Pengujian A/B

  • Parameter kueri — cocok untuk rilis bertahap dan Pengujian A/B

  • Bobot layanan — cocok untuk penyebaran biru-hijau

Metode anotasi canary-*

Referensi anotasi

Semua konfigurasi canary memerlukan anotasi nginx.ingress.kubernetes.io/canary: "true". Anotasi lain menentukan logika routing.

Anotasi Deskripsi Versi min.
nginx.ingress.kubernetes.io/canary Mengaktifkan fitur canary. Harus diatur ke true agar anotasi canary lain berlaku. Nilai yang valid: true, false. >=v0.22.0
nginx.ingress.kubernetes.io/canary-by-header Mengarahkan permintaan ke layanan canary berdasarkan header permintaan. Nilai khusus: always (selalu diarahkan ke canary), never (tidak pernah diarahkan ke canary). Jika tidak ada nilai yang ditentukan, traffic diteruskan selama header tersebut ada. >=v0.22.0
nginx.ingress.kubernetes.io/canary-by-header-value Mengarahkan permintaan ke layanan canary ketika header yang ditentukan oleh canary-by-header sesuai dengan nilai eksak. Harus digunakan bersama canary-by-header. >=v0.30.0
nginx.ingress.kubernetes.io/canary-by-header-pattern Mengarahkan permintaan ke layanan canary ketika header yang ditentukan oleh canary-by-header sesuai dengan ekspresi reguler. Harus digunakan bersama canary-by-header. >=v0.44.0
nginx.ingress.kubernetes.io/canary-by-cookie Mengarahkan permintaan ke layanan canary berdasarkan cookie, misalnya nginx.ingress.kubernetes.io/canary-by-cookie: foo. Nilai cookie: always (foo=always diarahkan ke canary), never (foo=never tidak diarahkan). Traffic diteruskan hanya jika cookie tersebut ada dan nilainya always. >=v0.22.0
nginx.ingress.kubernetes.io/canary-weight Mengarahkan persentase permintaan ke layanan canary berdasarkan bobot. Rentang: 0 hingga canary-weight-total (default 100). >=v0.22.0
nginx.ingress.kubernetes.io/canary-weight-total Menetapkan penyebut total bobot. Default: 100. >=v1.1.2

Prioritas anotasi (menurun):

canary-by-header > canary-by-cookie > canary-weight

Setiap aturan Ingress hanya mendukung satu Ingress canary. Ingress canary tambahan akan diabaikan.

Langkah 1: Penerapan layanan

Terapkan layanan Nginx dan buka akses domain Lapisan 7 melalui Nginx Ingress Controller.

  1. Buat Deployment dan Service. Simpan konten berikut ke dalam nginx.yaml.

    Lihat file YAML

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: old-nginx
    spec:
      replicas: 2
      selector:
        matchLabels:
          run: old-nginx
      template:
        metadata:
          labels:
            run: old-nginx
        spec:
          containers:
          - image: registry.cn-hangzhou.aliyuncs.com/acs-sample/old-nginx
            imagePullPolicy: Always
            name: old-nginx
            ports:
            - containerPort: 80
              protocol: TCP
          restartPolicy: Always
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: old-nginx
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
      selector:
        run: old-nginx
      sessionAffinity: None
      type: NodePort

    Terapkan manifes:

    kubectl apply -f nginx.yaml
  2. Buat Ingress. Simpan konten berikut ke dalam ingress.yaml.

    Untuk kluster v1.19 dan yang lebih baru

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: gray-release
    spec:
      ingressClassName: nginx
      rules:
      - host: www.example.com
        http:
          paths:
          # Versi lama layanan.
          - path: /
            backend:
              service:
                name: old-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific

    Untuk kluster sebelum v1.19

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: gray-release
    spec:
      rules:
      - host: www.example.com
        http:
          paths:
          # Versi lama layanan.
          - path: /
            backend:
              serviceName: old-nginx
              servicePort: 80

    Terapkan manifes:

    kubectl apply -f ingress.yaml
  3. Verifikasi penerapan. Dapatkan alamat IP eksternal:

    kubectl get ingress

    Periksa akses routing:

    curl -H "Host: www.example.com" http://<EXTERNAL_IP>

    Output yang diharapkan:

    old

Langkah 2: Rilis versi layanan baru

Terapkan versi Nginx baru dan konfigurasikan aturan routing canary.

  1. Buat Deployment dan Service baru. Simpan konten berikut ke dalam nginx1.yaml.

    Lihat file YAML

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: new-nginx
    spec:
      replicas: 1
      selector:
        matchLabels:
          run: new-nginx
      template:
        metadata:
          labels:
            run: new-nginx
        spec:
          containers:
          - image: registry.cn-hangzhou.aliyuncs.com/acs-sample/new-nginx
            imagePullPolicy: Always
            name: new-nginx
            ports:
            - containerPort: 80
              protocol: TCP
          restartPolicy: Always
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: new-nginx
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
      selector:
        run: new-nginx
      sessionAffinity: None
      type: NodePort

    Terapkan manifes:

    kubectl apply -f nginx1.yaml
  2. Buat Ingress canary untuk mengarahkan lalu lintas ke versi baru. Tiga strategi tersedia. Strategi A: Routing berdasarkan header permintaan Arahkan permintaan ke versi baru hanya ketika header foo bernilai bar. Permintaan lain diarahkan ke versi lama. Simpan konten berikut ke dalam ingress1.yaml. Untuk kluster v1.19 dan yang lebih baru:

    • Dengan header `foo: bar`: 100% lalu lintas diarahkan ke new-nginx (dikendalikan oleh canary-by-header dan canary-by-header-value).

    • Tanpa header `foo: bar`: 50% lalu lintas diarahkan ke new-nginx (dikendalikan oleh canary-weight).

    Untuk kluster v1.19 dan yang lebih baru

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: gray-release-canary
      annotations:
        # Aktifkan routing canary.
        nginx.ingress.kubernetes.io/canary: "true"
        # Arahkan ke new-nginx hanya jika header foo bernilai bar.
        nginx.ingress.kubernetes.io/canary-by-header: "foo"
        nginx.ingress.kubernetes.io/canary-by-header-value: "bar"
    spec:
      ingressClassName: nginx
      rules:
      - host: www.example.com
        http:
          paths:
          # Versi baru layanan.
          - path: /
            backend:
              service:
                name: new-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific

    Untuk kluster sebelum v1.19

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: gray-release-canary
      annotations:
        nginx.ingress.kubernetes.io/canary: "true"
        nginx.ingress.kubernetes.io/canary-by-header: "foo"
        nginx.ingress.kubernetes.io/canary-by-header-value: "bar"
        nginx.ingress.kubernetes.io/canary-weight: "50"
    spec:
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              serviceName: new-nginx
              servicePort: 80

    Terapkan manifes dan verifikasi:

    kubectl get ingress
    curl -H "Host: www.example.com" http://<EXTERNAL_IP>

    Uji tanpa header (diarahkan ke versi lama):

    curl -H "Host: www.example.com" http://<EXTERNAL_IP>

    Output yang diharapkan: old Uji dengan header foo: bar (diarahkan ke versi baru):

    curl -H "Host: www.example.com" -H "foo: bar" http://<EXTERNAL_IP>

    Output yang diharapkan: new

    Strategi B: Routing berdasarkan header dan membagi sisa lalu lintas berdasarkan bobot

    Arahkan semua permintaan dengan foo=bar ke versi baru, dan 50% permintaan lain ke versi baru. Perbarui ingress1.yaml dengan konten berikut.

    Untuk kluster v1.19 dan yang lebih baru

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: gray-release-canary
      annotations:
        nginx.ingress.kubernetes.io/canary: "true"
        # Arahkan 50% trafik ke new-nginx. Bobot total default adalah 100.
        nginx.ingress.kubernetes.io/canary-weight: "50"
    spec:
      ingressClassName: nginx
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              service:
                name: new-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific

    Untuk kluster sebelum v1.19

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: gray-release-canary
      annotations:
        nginx.ingress.kubernetes.io/canary: "true"
        nginx.ingress.kubernetes.io/canary-by-header: "foo"
        nginx.ingress.kubernetes.io/canary-by-header-value: "bar"
        nginx.ingress.kubernetes.io/canary-weight: "50"
    spec:
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              serviceName: new-nginx
              servicePort: 80

    Terapkan manifes:

    kubectl apply -f ingress1.yaml

    Strategi C: Routing hanya berdasarkan bobot

    Arahkan 50% lalu lintas ke versi baru, terlepas dari header atau cookie. Perbarui ingress1.yaml dengan konten berikut.

    Untuk kluster v1.19 dan yang lebih baru

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: gray-release-canary
      annotations:
        nginx.ingress.kubernetes.io/canary: "true"
        # Arahkan 50% seluruh traffic ke new-nginx. Bobot total default adalah 100.
        nginx.ingress.kubernetes.io/canary-weight: "50"
    spec:
      ingressClassName: nginx
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              service:
                name: new-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific

    Untuk kluster sebelum v1.19

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: gray-release-canary
      annotations:
        nginx.ingress.kubernetes.io/canary: "true"
        nginx.ingress.kubernetes.io/canary-weight: "50"
    spec:
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              serviceName: new-nginx
              servicePort: 80

    Terapkan manifes:

    kubectl apply -f ingress1.yaml

    Verifikasi: jalankan perintah ini beberapa kali. Sekitar 50% tanggapan seharusnya mengembalikan new.

    curl -H "Host: www.example.com" http://<EXTERNAL_IP>

Langkah 3: Selesaikan alih traffic

Setelah versi baru stabil, hentikan versi lama.

  1. Perbarui nginx.yaml untuk mengarahkan Service lama ke Deployment baru.

    Lihat file YAML

    apiVersion: v1
    kind: Service
    metadata:
      name: old-nginx
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
      selector:
        # Arahkan ke versi layanan baru.
        run: new-nginx
      sessionAffinity: None
      type: NodePort

    Terapkan pembaruan:

    kubectl apply -f nginx.yaml
  2. Verifikasi seluruh lalu lintas diarahkan ke versi baru:

    kubectl get ingress
    curl -H "Host: www.example.com" http://<EXTERNAL_IP>

    Output yang diharapkan: new

  3. Hapus Ingress canary:

    kubectl delete ingress gray-release-canary
  4. Hapus Deployment lama dan Service baru:

    kubectl delete deploy old-nginx
    kubectl delete svc new-nginx

Metode anotasi service-*

Penting

Anotasi service-* tidak tersedia lagi di Nginx Ingress Controller v1.12 dan seterusnya. Jangan gunakan.

Referensi anotasi

Anotasi Deskripsi
nginx.ingress.kubernetes.io/service-match Menentukan aturan routing yang memetakan atribut permintaan ke layanan. Sintaks: nginx.ingress.kubernetes.io/service-match: | <service-name>: <match-rule>. Jenis pencocokan yang didukung: header, cookie, query. Format pencocokan: regex /regular expression/, eksak "exact value". Contoh: new-nginx: header("foo", /^bar$/); new-nginx: header("foo", "bar"); new-nginx: cookie("foo", /^sticky-.+$/); new-nginx: query("foo", "bar").
nginx.ingress.kubernetes.io/service-weight Menetapkan bobot traffic antara versi layanan lama dan baru. Sintaks: nginx.ingress.kubernetes.io/service-weight: | <new-svc-name>:<new-svc-weight>, <old-svc-name>:<old-svc-weight>. Contoh: new-nginx: 20, old-nginx: 60.

Langkah 1: Penerapan layanan

Terapkan layanan Nginx dan buka akses domain Lapisan 7 melalui Nginx Ingress Controller.

  1. Buat Deployment dan Service. Simpan konten berikut ke dalam nginx.yaml.

    Lihat file YAML

    old

    Terapkan manifes:

    kubectl apply -f nginx.yaml
  2. Buat Ingress. Simpan konten berikut ke dalam ingress.yaml.

    Untuk kluster v1.19 dan yang lebih baru

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: gray-release
    spec:
      ingressClassName: nginx
      rules:
      - host: www.example.com
        http:
          paths:
          # Versi lama layanan.
          - path: /
            backend:
              service:
                name: old-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific

    Untuk kluster sebelum v1.19

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: gray-release
    spec:
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              serviceName: new-nginx
              servicePort: 80

    Terapkan manifes:

    kubectl apply -f ingress.yaml
    kubectl get ingress
  3. Verifikasi penerapan. Dapatkan alamat IP eksternal:

    kubectl get ingress

    Periksa akses routing:

    curl -H "Host: www.example.com" http://<EXTERNAL_IP>

    Output yang diharapkan:

    old

Langkah 2: Rilis versi layanan baru

Terapkan versi Nginx baru dan konfigurasikan aturan routing.

  1. Buat Deployment dan Service baru. Simpan konten berikut ke dalam nginx1.yaml.

    Lihat file YAML

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: new-nginx
    spec:
      replicas: 1
      selector:
        matchLabels:
          run: new-nginx
      template:
        metadata:
          labels:
            run: new-nginx
        spec:
          containers:
          - image: registry.cn-hangzhou.aliyuncs.com/acs-sample/new-nginx
            imagePullPolicy: Always
            name: new-nginx
            ports:
            - containerPort: 80
              protocol: TCP
          restartPolicy: Always
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: new-nginx
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
      selector:
        run: new-nginx
      sessionAffinity: None
      type: NodePort

    Terapkan manifes:

    kubectl apply -f nginx1.yaml
  2. Ubah Ingress gray-release. Tiga strategi tersedia. Strategi A: Routing berdasarkan header permintaan Arahkan permintaan ke versi baru hanya ketika header foo sesuai dengan bar. Perbarui ingress.yaml dengan konten berikut. Untuk kluster v1.19 dan yang lebih baru:

    Untuk kluster v1.19 dan yang lebih baru

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: gray-release
      annotations:
        # Arahkan ke new-nginx jika header foo sesuai ^bar$.
        nginx.ingress.kubernetes.io/service-match: |
          new-nginx: header("foo", /^bar$/)
    spec:
      ingressClassName: nginx
      rules:
      - host: www.example.com
        http:
          paths:
          # Versi lama layanan.
          - path: /
            backend:
              service:
                name: old-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific
          # Versi baru layanan.
          - path: /
            backend:
              service:
                name: new-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific

    Untuk kluster sebelum v1.19

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: gray-release
      annotations:
        nginx.ingress.kubernetes.io/service-match: |
            new-nginx: header("foo", /^bar$/)
        nginx.ingress.kubernetes.io/service-weight: |
            new-nginx: 50, old-nginx: 50
    spec:
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              serviceName: old-nginx
              servicePort: 80
          - path: /
            backend:
              serviceName: new-nginx
              servicePort: 80

    Terapkan manifes dan verifikasi:

    kubectl apply -f ingress.yaml
    kubectl get ingress

    Uji tanpa header (diarahkan ke versi lama):

    curl -H "Host: www.example.com" http://<EXTERNAL_IP>

    Output yang diharapkan: old Uji dengan header foo: bar (diarahkan ke versi baru):

    curl -H "Host: www.example.com" -H "foo: bar" http://<EXTERNAL_IP>

    Output yang diharapkan: new

    Strategi B: Routing berdasarkan header dengan pembagian berbasis bobot

    Arahkan permintaan yang sesuai foo=bar ke kedua versi, dengan 50% masing-masing. Perbarui ingress.yaml dengan konten berikut.

    Untuk kluster v1.19 dan yang lebih baru

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: gray-release
      annotations:
        nginx.ingress.kubernetes.io/service-match: |
            new-nginx: header("foo", /^bar$/)
        # Dari permintaan yang sesuai, arahkan 50% ke new-nginx dan 50% ke old-nginx.
        nginx.ingress.kubernetes.io/service-weight: |
            new-nginx: 50, old-nginx: 50
    spec:
      ingressClassName: nginx
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              service:
                name: old-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific
          - path: /
            backend:
              service:
                name: new-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific

    Untuk kluster sebelum v1.19

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: gray-release
      annotations:
        nginx.ingress.kubernetes.io/service-match: |
            new-nginx: header("foo", /^bar$/)
        nginx.ingress.kubernetes.io/service-weight: |
            new-nginx: 50, old-nginx: 50
    spec:
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              serviceName: old-nginx
              servicePort: 80
          - path: /
            backend:
              serviceName: new-nginx
              servicePort: 80

    Terapkan manifes:

    kubectl apply -f ingress.yaml

    Jalankan perintah uji beberapa kali. Sekitar 50% permintaan foo: bar seharusnya mengembalikan new.

    Strategi C: Routing hanya berdasarkan bobot

    Arahkan 50% lalu lintas ke versi baru. Perbarui ingress.yaml dengan konten berikut.

    Untuk kluster v1.19 dan yang lebih baru

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: gray-release
      annotations:
        # Arahkan 50% seluruh traffic ke new-nginx.
        nginx.ingress.kubernetes.io/service-weight: |
            new-nginx: 50, old-nginx: 50
    spec:
      ingressClassName: nginx
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              service:
                name: old-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific
          - path: /
            backend:
              service:
                name: new-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific

    Untuk kluster sebelum v1.19

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: gray-release
      annotations:
        nginx.ingress.kubernetes.io/service-weight: |
            new-nginx: 50, old-nginx: 50
    spec:
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              serviceName: old-nginx
              servicePort: 80
          - path: /
            backend:
              serviceName: new-nginx
              servicePort: 80

    Terapkan manifes:

    kubectl apply -f ingress.yaml

    Verifikasi: jalankan perintah ini beberapa kali. Sekitar 50% tanggapan seharusnya mengembalikan new.

    curl -H "Host: www.example.com" http://<EXTERNAL_IP>

Langkah 3: Selesaikan alih traffic

Setelah versi baru stabil, hentikan versi lama.

  1. Untuk kluster v1.19 dan yang lebih baru

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: gray-release
    spec:
      ingressClassName: nginx
      rules:
      - host: www.example.com
        http:
          paths:
          # Versi baru layanan.
          - path: /
            backend:
              service:
                name: new-nginx
                port:
                  number: 80
            pathType: ImplementationSpecific

    Untuk kluster sebelum v1.19

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: gray-release
    spec:
      rules:
      - host: www.example.com
        http:
          paths:
          - path: /
            backend:
              serviceName: new-nginx
              servicePort: 80

    Terapkan pembaruan:

    kubectl apply -f ingress.yaml
  2. Verifikasi seluruh lalu lintas diarahkan ke versi baru:

    kubectl get ingress
    curl -H "Host: www.example.com" http://<EXTERNAL_IP>

    Output yang diharapkan: new

  3. Hapus Deployment dan Service lama:

    kubectl delete deploy <Deployment_name>
    kubectl delete svc <Service_name>