Rilis Canary yang Lancar Menggunakan APISIX Ingress Controller dengan Flagger

Hengliang Tan

January 19, 2023

Ecosystem

Penulis: Hengliang Tan, Manajer Teknik di XPENG

Dalam proses pengembangan proyek, pembaruan layanan seringkali menjadi tantangan. Untuk memberikan pengalaman pengguna terbaik, kita perlu menghindari risiko ketidaktersediaan layanan sebanyak mungkin. Oleh karena itu, continuous delivery (pengiriman berkelanjutan) lahir, diterima sebagai praktik perangkat lunak perusahaan, dan merupakan evolusi alami dari prinsip-prinsip continuous integration (integrasi berkelanjutan) yang sudah mapan. Namun, continuous deployment (penerapan berkelanjutan) masih sangat jarang dilakukan karena kompleksitas manajemen dan kekhawatiran bahwa kegagalan penerapan akan memengaruhi ketersediaan sistem. Canary release mungkin adalah skenario paling klasik dalam sistem continuous delivery. Berdasarkan ini, kita dapat dengan cepat menemukan layanan yang tidak sehat dan bermasalah serta dengan mudah kembali ke versi sebelumnya.

Canary Release

Canary release juga dikenal sebagai grayscale release. Secara umum, versi baru aplikasi dirilis dan diterapkan sebagai "canary" untuk menguji performa. Versi lama tetap dipertahankan untuk operasi normal pada tahap yang sama. Selama peningkatan, beberapa pengguna akan diarahkan untuk menggunakan versi baru, sementara pengguna lain akan terus menggunakan versi lama. Dengan memastikan stabilitas sistem secara keseluruhan, hal ini memungkinkan deteksi dini bug dan penyesuaian tepat waktu.

Canary release tidak langsung merilis pembaruan. Secara perlahan, ia mengarahkan persentase tertentu dari lalu lintas ke sejumlah kecil pengguna. Jika tidak ada kesalahan yang terdeteksi, maka akan dipromosikan ke semua pengguna, dan versi lama akan dihapus secara bertahap. Metode ini mengurangi risiko memperkenalkan fungsi baru ke lingkungan produksi.

Artikel ini akan memperkenalkan bagaimana mencapai canary release yang lancar melalui Apache APISIX Ingress dan Flagger, meningkatkan efisiensi rilis, dan mengurangi risiko rilis.

Tentang Apache APISIX Ingress

Apache APISIX Ingress diwujudkan oleh Kubernetes Ingress Controller yang menggunakan Apache APISIX sebagai proxy data plane. Ini menyediakan ratusan fungsi, seperti load balancing, upstream dinamis, canary release, routing yang halus, pembatasan kecepatan, degradasi layanan, pemutusan sirkuit layanan, autentikasi, dan observabilitas. Ini telah diadopsi oleh perusahaan dan organisasi domestik dan internasional, termasuk Zoom, Tencent Cloud, Jiakaobaodian, Horizon Robotics, European Copernicus Reference System, dll.

Tentang Flagger

Flagger adalah proyek CNCF (Cloud Native Computing Foundation) dan bagian dari keluarga alat GitOps Flux. Baru-baru ini, CNCF juga mengumumkan kelulusan resmi Flux, yang merupakan indikator yang baik dari kesuksesan dan masa depan yang menjanjikan dari teknologi cloud-native. Sebagai alat pengiriman progresif, Flagger mengotomatiskan proses rilis untuk aplikasi yang berjalan di Kubernetes. Ini mengurangi risiko memperkenalkan versi perangkat lunak baru dalam produksi dengan secara bertahap mengalihkan lalu lintas ke versi baru sambil mengukur metrik analitik dan menjalankan tes kesesuaian.

Setelah upaya terus-menerus dari komunitas Apache APISIX dan Flux, Flagger baru-baru ini merilis v1.27.0, yang mendukung canary release otomatis menggunakan Apache APISIX Ingress dan Flagger.

featured-<Flagger and Apache APISIX Ingress>.jpg

Mari kita alami proses canary release yang lancar ini bersama-sama.

Lingkungan

Membutuhkan kluster Kubernetes v1.19 atau lebih baru, yang dapat Anda instal melalui kind.

Instal Komponen

Gunakan Helm V3 untuk menginstal Apache APISIX dan Apache APISIX Ingress Controller

helm repo add apisix https://charts.apiseven.com kubectl create ns apisix helm upgrade -i apisix apisix/apisix --version=0.11.3 \ --namespace apisix \ --set apisix.podAnnotations."prometheus\.io/scrape"=true \ --set apisix.podAnnotations."prometheus\.io/port"=9091 \ --set apisix.podAnnotations."prometheus\.io/path"=/apisix/prometheus/metrics \ --set pluginAttrs.prometheus.export_addr.ip=0.0.0.0 \ --set pluginAttrs.prometheus.export_addr.port=9091 \ --set pluginAttrs.prometheus.export_uri=/apisix/prometheus/metrics \ --set pluginAttrs.prometheus.metric_prefix=apisix_ \ --set ingress-controller.enabled=true \ --set ingress-controller.config.apisix.serviceNamespace=apisix

Instal komponen Flagger dan Prometheus di namespace apisix.

helm repo add flagger https://flagger.app helm upgrade -i flagger flagger/flagger \ --namespace apisix \ --set prometheus.install=true \ --set meshProvider=apisix

Catatan: jika Anda perlu menyesuaikan Prometheus atau Prometheus Operator, Anda dapat mencari artikel terkait untuk modifikasi.

Inisialisasi Aplikasi

Flagger dapat diterapkan pada deployment Kubernetes dan workload lainnya, dan juga dapat dikombinasikan dengan HPA. Ini akan membuat serangkaian objek: deployment Kubernetes, layanan ClusterIP, dan ApisixRoute. Objek-objek ini dapat mengekspos aplikasi ke luar kluster untuk menyediakan layanan dan digunakan untuk analisis proses canary release.

Buat namespace tes baru:

kubectl create ns test

Buat deployment dan HPA baru. Di sini kami mengambil contoh kode resmi dari Flagger.

kubectl apply -k https://github.com/fluxcd/flagger//kustomize/podinfo?ref=main

Terapkan layanan pengujian beban Flagger untuk menghasilkan lalu lintas selama canary release untuk analisis.

helm upgrade -i flagger-loadtester flagger/loadtester \ --namespace=test

Buat ApisixRoute dari Apache APISIX, kemudian Flagger akan merujuk sumber daya yang dibuat dan menghasilkan ApisixRoute dari Apache APISIX Ingress dalam versi canary. (Ganti app.example.com dalam contoh di bawah dengan nama domain Anda yang sebenarnya)

apiVersion: apisix.apache.org/v2 kind: ApisixRoute metadata: name: podinfo namespace: test spec: http: - backends: - serviceName: podinfo servicePort: 80 match: hosts: - app.example.com methods: - GET paths: - /* name: method plugins: - name: prometheus enable: true config: disable: false prefer_name: true

Simpan sebagai podinfo-apisixroute.yaml dan kirim ke kluster:

kubectl apply -f ./podinfo-apisixroute.yaml

Buat sumber daya kustom Flagger Canary. (Ganti app.example.com dalam contoh dengan nama domain Anda yang sebenarnya)

apiVersion: flagger.app/v1beta1 kind: Canary metadata: name: podinfo namespace: test spec: provider: apisix targetRef: apiVersion: apps/v1 kind: Deployment name: podinfo # Referensi rute apisix routeRef: apiVersion: apisix.apache.org/v2 kind: ApisixRoute name: podinfo progressDeadlineSeconds: 60 service: port: 80 targetPort: 9898 analysis: interval: 10s # jumlah maksimum kegagalan untuk roll back threshold: 10 # persentase maksimum lalu lintas ke versi canary # (0-100) maxWeight: 50 # ukuran langkah dari analisis canary # (0-100) stepWeight: 10 # gunakan Prometheus untuk memeriksa informasi lalu lintas APISIX metrics: - name: request-success-rate # tingkat keberhasilan minimum (tidak ada respons 5xx) # (0-100) thresholdRange: min: 99 interval: 1m - name: request-duration # P99 adalah penundaan permintaan terbesar (ms) thresholdRange: max: 500 interval: 30s webhooks: # lalu lintas otomatis untuk analisis canary, dimodifikasi berdasarkan skenario aktual - name: load-test url: http://flagger-loadtester.test/ timeout: 5s type: rollout metadata: cmd: |- hey -z 1m -q 10 -c 2 -h2 -host app.example.com http://apisix-gateway.apisix/api/info

Simpan sebagai podinfo-canary.yaml dan kirim ke kluster:

kubectl apply -f ./podinfo-canary.yaml

Flagger akan secara otomatis menghasilkan sumber daya terkait:

# Dikirim deployment.apps/podinfo horizontalpodautoscaler.autoscaling/podinfo apisixroute/podinfo canary.flagger.app/podinfo

# Dihasilkan otomatis deployment.apps/podinfo-primary horizontalpodautoscaler.autoscaling/podinfo-primary service/podinfo service/podinfo-canary service/podinfo-primary apisixroute/podinfo-podinfo-canary

featured-<version 1>.jpg

Pada titik ini, Anda dapat mengakses aplikasi melalui nama domain app.example.com (Ganti app.example.com dalam contoh dengan nama domain Anda yang sebenarnya), dan Anda akan melihat versi aplikasi saat ini.

Otomatisasi Canary Release

Flagger mengimplementasikan loop kontrol yang secara bertahap mengalihkan lalu lintas ke node canary sambil mengukur metrik kinerja kunci seperti tingkat keberhasilan permintaan HTTP, durasi permintaan rata-rata, dan kesehatan pod. Menurut analisis indikator terkait, rilis atau hentikan deployment canary dan publikasikan hasil analisis ke platform terkait seperti Slack, MS Teams atau Prometheus Alert Manager, dll.

Flagger Control Loop

Picu canary release dengan memperbarui versi gambar kontainer

kubectl -n test set image deployment/podinfo \ podinfod=stefanprodan/podinfo:6.0.1

Flagger mendeteksi bahwa ada versi baru dari deployment dan akan memulai uji coba analisis canary release.

kubectl -n test describe canary/podinfo Status: Canary Weight: 0 Conditions: Message: Canary analysis completed successfully, promotion finished. Reason: Succeeded Status: True Type: Promoted Failed Checks: 1 Iterations: 0 Phase: Succeeded Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning Synced 2m59s flagger podinfo-primary.test not ready: waiting for rollout to finish: observed deployment generation less than desired generation Warning Synced 2m50s flagger podinfo-primary.test not ready: waiting for rollout to finish: 0 of 1 (readyThreshold 100%) updated replicas are available Normal Synced 2m40s (x3 over 2m59s) flagger all the metrics providers are available! Normal Synced 2m39s flagger Initialization done! podinfo.test Normal Synced 2m20s flagger New revision detected! Scaling up podinfo.test Warning Synced 2m (x2 over 2m10s) flagger canary deployment podinfo.test not ready: waiting for rollout to finish: 0 of 1 (readyThreshold 100%) updated replicas are available Normal Synced 110s flagger Starting canary analysis for podinfo.test Normal Synced 109s flagger Advance podinfo.test canary weight 10 Warning Synced 100s flagger Halt advancement no values found for apisix metric request-success-rate probably podinfo.test is not receiving traffic: running query failed: no values found Normal Synced 90s flagger Advance podinfo.test canary weight 20 Normal Synced 80s flagger Advance podinfo.test canary weight 30 Normal Synced 69s flagger Advance podinfo.test canary weight 40 Normal Synced 59s flagger Advance podinfo.test canary weight 50 Warning Synced 30s (x2 over 40s) flagger podinfo-primary.test not ready: waiting for rollout to finish: 1 old replicas are pending termination Normal Synced 9s (x3 over 50s) flagger (combined from similar events): Promotion completed! Scaling down podinfo.test

Selama proses canary release, Anda akan menerima respons yang berbeda ketika Anda mengakses aplikasi melalui nama domain app.example.com (Ganti app.example.com dengan nama domain Anda yang sebenarnya).

featured-<version 2>.jpg

Dengan melihat sumber daya ApisixRoute podinfo-podinfo-canary dari Apache APISIX yang dibuat secara otomatis oleh Flagger, Anda akan menemukan bahwa bobot layanan podinfo-primary dan layanan podinfo-canary berubah seiring dengan proses penerbitan.

spec: http: - backends: - serviceName: podinfo-primary servicePort: 80 # Disesuaikan otomatis oleh Flagger weight: 80 - serviceName: podinfo-canary servicePort: 80 # Disesuaikan otomatis oleh Flagger weight: 20

Anda akan melihat versi stabil terbaru ketika rilis akhir selesai.

featured-<version 3>.jpg

Catatan: Flagger akan menjalankan kembali analisis canary jika Anda mengubah deployment lagi selama canary release.

Anda dapat mengamati semua canary release dengan perintah ini:

watch kubectl get canaries --all-namespaces NAMESPACE NAME STATUS WEIGHT LASTTRANSITIONTIME test podinfo-2 Progressing 10 2022-11-23T05:00:54Z test podinfo Succeeded 0 2022-11-23T06:00:54Z

Rollback

Selama analisis canary release, Anda dapat menguji Flagger untuk menghentikan canary release dan kembali ke versi lama dengan menghasilkan HTTP 500 Bad Request.

Picu canary release lain:

kubectl -n test set image deployment/podinfo \ podinfod=stefanprodan/podinfo:6.0.2

Masuk ke kontainer load tester

kubectl -n test exec -it deploy/flagger-loadtester bash

Hasilkan kesalahan HTTP 500:

hey -z 1m -c 5 -q 5 -host app.example.com http://apisix-gateway.apisix/status/500

Simulasi penundaan server:

watch -n 1 curl -H \"host: app.example.com\" http://apisix-gateway.apisix/delay/1

Ketika jumlah kegagalan yang terdeteksi mencapai ambang analisis canary, lalu lintas secara otomatis dialihkan kembali ke node master, node canary dikecilkan ke nol, dan proses canary release ditandai sebagai gagal.

kubectl -n apisix logs deploy/flagger -f | jq .msg "New revision detected! Scaling up podinfo.test" "canary deployment podinfo.test not ready: waiting for rollout to finish: 0 of 1 (readyThreshold 100%) updated replicas are available" "Starting canary analysis for podinfo.test" "Advance podinfo.test canary weight 10" "Halt podinfo.test advancement success rate 0.00% < 99%" "Halt podinfo.test advancement success rate 26.76% < 99%" "Halt podinfo.test advancement success rate 34.19% < 99%" "Halt podinfo.test advancement success rate 37.32% < 99%" "Halt podinfo.test advancement success rate 39.04% < 99%" "Halt podinfo.test advancement success rate 40.13% < 99%" "Halt podinfo.test advancement success rate 48.28% < 99%" "Halt podinfo.test advancement success rate 50.35% < 99%" "Halt podinfo.test advancement success rate 56.92% < 99%" "Halt podinfo.test advancement success rate 67.70% < 99%" "Rolling back podinfo.test failed checks threshold reached 10" "Canary failed! Scaling down podinfo.test"

Kustomisasi Metrik untuk Analisis Canary

Analisis canary dapat diperluas dengan mengkueri metrik Prometheus. Kami menyesuaikan berdasarkan skenario bisnis aktual. Buat template metrik dan kirim ke kluster.

apiVersion: flagger.app/v1beta1 kind: MetricTemplate metadata: name: not-found-percentage namespace: test spec: provider: type: prometheus address: http://flagger-prometheus.apisix:9090 query: | sum( rate( apisix_http_status{ route=~"{{ namespace }}_{{ route }}-{{ target }}-canary_.+", code!~"4.." }[{{ interval }}] ) ) / sum( rate( apisix_http_status{ route=~"{{ namespace }}_{{ route }}-{{ target }}-canary_.+" }[{{ interval }}] ) ) * 100 # Modifikasi analisis dalam canary release dan tambahkan template indikator yang dibuat di atas. analysis: metrics: - name: "404s percentage" templateRef: name: not-found-percentage thresholdRange: max: 5 interval: 1m

Konfigurasi di atas memvalidasi canary dengan memeriksa apakah QPS (Queries per second) dari permintaan HTTP 404 lebih tinggi dari 5% dari total lalu lintas. Rollout canary gagal jika permintaan HTTP 404 melebihi ambang batas 5%.

Ringkasan

Proses di atas dapat diperluas dengan lebih banyak pemeriksaan metrik kustom, Webhook, persetujuan manual, dan notifikasi Slack atau MS Teams.

Canary release yang sangat lancar dicapai melalui integrasi Apache APISIX dan Flagger, yang meningkatkan efisiensi rilis dan mengurangi risiko rilis. Di masa depan, kedua komunitas akan bekerja sama lebih erat untuk mewujudkan lebih banyak kemampuan penerbitan seperti Blue/Green Mirroring dan A/B Testing.

Tags: