APISIX Ingress Controller और Flagger का उपयोग करके स्मूथ Canary रिलीज़

Hengliang Tan

January 19, 2023

Ecosystem

लेखक: हेंगलियांग तान, XPENG में इंजीनियरिंग मैनेजर

प्रोजेक्ट विकास की प्रक्रिया में, सेवा अपडेट अक्सर एक चुनौती होती है। सर्वोत्तम उपयोगकर्ता अनुभव प्रदान करने के लिए, हमें सेवा अनुपलब्धता के जोखिम को यथासंभव कम करने की आवश्यकता होती है। इस प्रकार, निरंतर वितरण (Continuous Delivery) का जन्म हुआ, जिसे एक उद्यम सॉफ्टवेयर प्रथा के रूप में स्वीकार किया गया है और यह स्थापित निरंतर एकीकरण (Continuous Integration) सिद्धांतों का एक प्राकृतिक विकास है। हालांकि, प्रबंधन की जटिलता और डिप्लॉयमेंट विफलताओं के कारण सिस्टम की उपलब्धता प्रभावित होने के डर से निरंतर डिप्लॉयमेंट (Continuous Deployment) अभी भी बहुत कम ही देखा जाता है। कैनरी रिलीज़ (Canary Release) शायद निरंतर वितरण प्रणाली में सबसे क्लासिक परिदृश्य है। इसके आधार पर, हम अस्वस्थ और समस्याग्रस्त सेवाओं को जल्दी से खोज सकते हैं और पिछले संस्करण में आसानी से वापस लौट सकते हैं।

कैनरी रिलीज़

कैनरी रिलीज़ को ग्रेस्केल रिलीज़ (Grayscale Release) के रूप में भी जाना जाता है। आम तौर पर, एप्लिकेशन के नए संस्करण को एक "कैनरी" के रूप में जारी और डिप्लॉय किया जाता है ताकि इसके प्रदर्शन का परीक्षण किया जा सके। पुराना संस्करण सामान्य संचालन के लिए उसी चरण में बना रहता है। अपग्रेड के दौरान, कुछ उपयोगकर्ताओं को नए संस्करण का उपयोग करने के लिए निर्देशित किया जाएगा, जबकि अन्य उपयोगकर्ता पुराने संस्करण का उपयोग करना जारी रखेंगे। समग्र सिस्टम की स्थिरता सुनिश्चित करने के आधार पर, यह बग्स का शीघ्र पता लगाने और समय पर समायोजन करने में सक्षम बनाता है।

कैनरी रिलीज़ सीधे अपडेट जारी नहीं करता है। यह धीरे-धीरे कुछ प्रतिशत ट्रैफ़िक को कुछ उपयोगकर्ताओं की ओर निर्देशित करता है। यदि कोई त्रुटि नहीं पाई जाती है, तो इसे सभी उपयोगकर्ताओं के लिए प्रचारित किया जाएगा, और पुराना संस्करण चरणबद्ध तरीके से हटा दिया जाएगा। यह विधि उत्पादन वातावरण में नई सुविधाओं को शामिल करने के जोखिम को कम करती है।

यह लेख बताएगा कि कैसे Apache APISIX Ingress और Flagger के माध्यम से सुचारू कैनरी रिलीज़ प्राप्त किया जा सकता है, रिलीज़ दक्षता में सुधार किया जा सकता है, और रिलीज़ जोखिम को कम किया जा सकता है।

Apache APISIX Ingress के बारे में

Apache APISIX Ingress को Kubernetes Ingress Controller द्वारा प्राप्त किया जाता है जो Apache APISIX को डेटा प्लेन प्रॉक्सी के रूप में उपयोग करता है। यह लोड बैलेंसिंग, डायनामिक अपस्ट्रीम, कैनरी रिलीज़, सूक्ष्म रूटिंग, दर सीमित करना, सेवा डिग्रेडेशन, सेवा सर्किट ब्रेकर, प्रमाणीकरण और प्रेक्षणीयता जैसी सैकड़ों सुविधाएँ प्रदान करता है। इसे Zoom, Tencent Cloud, Jiakaobaodian, Horizon Robotics, European Copernicus Reference System आदि जैसी घरेलू और विदेशी कंपनियों और संगठनों द्वारा अपनाया गया है।

Flagger के बारे में

Flagger एक CNCF (क्लाउड नेटिव कंप्यूटिंग फाउंडेशन) प्रोजेक्ट है और Flux परिवार के GitOps टूल्स का हिस्सा है। हाल ही में, CNCF ने Flux के आधिकारिक स्नातक होने की घोषणा की है, जो क्लाउड-नेटिव तकनीक की सफलता और भविष्य के लिए एक अच्छा संकेतक है। एक प्रगतिशील वितरण टूल के रूप में, Flagger Kubernetes पर चलने वाले एप्लिकेशन के लिए रिलीज़ प्रक्रिया को स्वचालित करता है। यह नए सॉफ्टवेयर संस्करण को उत्पादन में शामिल करने के जोखिम को कम करता है, जबकि नए संस्करण की ओर ट्रैफ़िक को धीरे-धीरे स्थानांतरित करता है और एनालिटिक्स मेट्रिक्स को मापता है और अनुरूपता परीक्षण चलाता है।

Apache APISIX और Flux समुदायों के निरंतर प्रयासों के बाद, Flagger ने हाल ही में v1.27.0 जारी किया है, जो Apache APISIX Ingress और Flagger का उपयोग करके स्वचालित कैनरी रिलीज़ का समर्थन करता है।

featured-<Flagger and Apache APISIX Ingress>.jpg

आइए इस सुचारू कैनरी रिलीज़ प्रक्रिया का अनुभव करें।

पर्यावरण

v1.19 या नए Kubernetes क्लस्टर की आवश्यकता होती है, जिसे आप kind के माध्यम से इंस्टॉल कर सकते हैं।

घटक इंस्टॉल करें

Helm V3 का उपयोग करके Apache APISIX और 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

Flagger और Prometheus घटकों को apisix नेमस्पेस में इंस्टॉल करें।

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

नोट: यदि आपको Prometheus या Prometheus Operator को कस्टमाइज़ करने की आवश्यकता है, तो आप संबंधित लेखों को खोजकर संशोधन कर सकते हैं।

एप्लिकेशन आरंभीकरण

Flagger को Kubernetes डिप्लॉयमेंट और अन्य वर्कलोड्स पर लागू किया जा सकता है और इसे HPA के साथ भी जोड़ा जा सकता है। यह कई ऑब्जेक्ट्स बनाएगा: Kubernetes डिप्लॉयमेंट्स, ClusterIP सेवाएँ, और ApisixRoute। ये ऑब्जेक्ट्स एप्लिकेशन को बाहरी क्लस्टरों के लिए उजागर कर सकते हैं ताकि सेवाएँ प्रदान की जा सकें और कैनरी रिलीज़ प्रक्रिया के विश्लेषण के लिए उपयोग किए जा सकें।

एक नया परीक्षण नेमस्पेस बनाएँ:

kubectl create ns test

एक नया डिप्लॉयमेंट और HPA बनाएँ। यहाँ हम Flagger से आधिकारिक कोड नमूना निकालते हैं।

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

कैनरी रिलीज़ के दौरान ट्रैफ़िक उत्पन्न करने के लिए Flagger के लोड टेस्टिंग सेवा को डिप्लॉय करें।

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

Apache APISIX का ApisixRoute बनाएँ, और फिर Flagger बनाए गए संसाधन का संदर्भ लेगा और कैनरी संस्करण में Apache APISIX Ingress का ApisixRoute उत्पन्न करेगा। (नीचे दिए गए उदाहरण में app.example.com को अपने वास्तविक डोमेन नाम से बदलें)

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

इसे podinfo-apisixroute.yaml के रूप में सहेजें और क्लस्टर में सबमिट करें:

kubectl apply -f ./podinfo-apisixroute.yaml

एक Flagger कस्टम संसाधन Canary बनाएँ। (उदाहरण में app.example.com को अपने वास्तविक डोमेन नाम से बदलें)

apiVersion: flagger.app/v1beta1 kind: Canary metadata: name: podinfo namespace: test spec: provider: apisix targetRef: apiVersion: apps/v1 kind: Deployment name: podinfo # Apisix route का संदर्भ लें routeRef: apiVersion: apisix.apache.org/v2 kind: ApisixRoute name: podinfo progressDeadlineSeconds: 60 service: port: 80 targetPort: 9898 analysis: interval: 10s # रोल बैक के लिए अधिकतम विफलताएँ threshold: 10 # कैनरी संस्करण की ओर अधिकतम ट्रैफ़िक प्रतिशत # (0-100) maxWeight: 50 # कैनरी विश्लेषण का चरण आकार # (0-100) stepWeight: 10 # APISIX के ट्रैफ़िक जानकारी की जाँच के लिए Prometheus का उपयोग करें metrics: - name: request-success-rate # न्यूनतम सफलता दर (कोई 5xx प्रतिक्रियाएँ नहीं) # (0-100) thresholdRange: min: 99 interval: 1m - name: request-duration # P99 सबसे बड़ा अनुरोध विलंब (ms) thresholdRange: max: 500 interval: 30s webhooks: # कैनरी विश्लेषण के लिए स्वचालित ट्रैफ़िक, वास्तविक परिदृश्य के आधार पर संशोधित - 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

इसे podinfo-canary.yaml के रूप में सहेजें और क्लस्टर में सबमिट करें:

kubectl apply -f ./podinfo-canary.yaml

Flagger स्वचालित रूप से संबंधित संसाधन उत्पन्न करेगा:

# सबमिट किया गया deployment.apps/podinfo horizontalpodautoscaler.autoscaling/podinfo apisixroute/podinfo canary.flagger.app/podinfo

# स्वचालित रूप से उत्पन्न deployment.apps/podinfo-primary horizontalpodautoscaler.autoscaling/podinfo-primary service/podinfo service/podinfo-canary service/podinfo-primary apisixroute/podinfo-podinfo-canary

featured-<version 1>.jpg

इस बिंदु पर, आप डोमेन नाम app.example.com के माध्यम से एप्लिकेशन तक पहुँच सकते हैं (उदाहरण में app.example.com को अपने वास्तविक डोमेन नाम से बदलें), और आप एप्लिकेशन का वर्तमान संस्करण देखेंगे।

कैनरी रिलीज़ की स्वचालन

Flagger एक नियंत्रण लूप लागू करता है जो धीरे-धीरे ट्रैफ़िक को कैनरी नोड्स की ओर स्थानांतरित करता है, जबकि HTTP अनुरोध सफलता दर, औसत अनुरोध अवधि और पॉड स्वास्थ्य जैसे प्रमुख प्रदर्शन मेट्रिक्स को मापता है। संबंधित संकेतकों के विश्लेषण के अनुसार, रिलीज़ या कैनरी डिप्लॉयमेंट को रोकें और विश्लेषण परिणामों को Slack, MS Teams या Prometheus Alert Manager जैसे संबंधित प्लेटफॉर्म पर प्रकाशित करें।

Flagger Control Loop

कंटेनर इमेज संस्करण को अपडेट करके कैनरी रिलीज़ ट्रिगर करें

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

Flagger पता लगाता है कि डिप्लॉयमेंट का एक नया संस्करण है और कैनरी विश्लेषण रिलीज़ का एक परीक्षण रन शुरू करेगा।

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

कैनरी रिलीज़ प्रक्रिया के दौरान, आप डोमेन नाम app.example.com के माध्यम से एप्लिकेशन तक पहुँचने पर अलग-अलग प्रतिक्रियाएँ प्राप्त करेंगे (उदाहरण में app.example.com को अपने वास्तविक डोमेन नाम से बदलें)।

featured-<version 2>.jpg

Flagger द्वारा स्वचालित रूप से बनाए गए Apache APISIX के ApisixRoute संसाधन podinfo-podinfo-canary को देखकर, आप पाएंगे कि सेवा podinfo-primary और सेवा podinfo-canary के वजन प्रकाशन प्रक्रिया के साथ बदलते हैं।

spec: http: - backends: - serviceName: podinfo-primary servicePort: 80 # Flagger द्वारा स्वचालित रूप से समायोजित weight: 80 - serviceName: podinfo-canary servicePort: 80 # Flagger द्वारा स्वचालित रूप से समायोजित weight: 20

जब अंतिम रिलीज़ पूरी हो जाएगी, तो आप नवीनतम स्थिर संस्करण देखेंगे।

featured-<version 3>.jpg

नोट: यदि आप कैनरी रिलीज़ के दौरान डिप्लॉयमेंट को फिर से बदलते हैं, तो Flagger कैनरी विश्लेषण को फिर से चलाएगा।

आप इस कमांड के साथ सभी कैनरी रिलीज़ का निरीक्षण कर सकते हैं:

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

रोलबैक

कैनरी रिलीज़ विश्लेषण के दौरान, आप Flagger का परीक्षण कर सकते हैं कि कैनरी रिलीज़ को निलंबित करें और पुराने संस्करण में वापस लौटें, HTTP 500 Bad Request उत्पन्न करके।

एक और कैनरी रिलीज़ ट्रिगर करें:

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

लोड टेस्टर कंटेनर में प्रवेश करें

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

HTTP 500 त्रुटि उत्पन्न करें:

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

सर्वर विलंब का अनुकरण करें:

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

जब पाई गई विफलताओं की संख्या कैनरी विश्लेषण के थ्रेशोल्ड तक पहुँच जाती है, तो ट्रैफ़िक स्वचालित रूप से मास्टर नोड पर वापस रूट हो जाता है, कैनरी नोड को शून्य तक स्केल किया जाता है, और कैनरी रिलीज़ प्रक्रिया को विफल के रूप में चिह्नित किया जाता है।

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"

कैनरी विश्लेषण के लिए कस्टम मेट्रिक्स

कैनरी विश्लेषण को Prometheus मेट्रिक्स को क्वेरी करके विस्तारित किया जा सकता है। हम वास्तविक व्यावसायिक परिदृश्यों के आधार पर कस्टमाइज़ करते हैं। एक मेट्रिक टेम्पलेट बनाएँ और इसे क्लस्टर में सबमिट करें।

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 # कैनरी रिलीज़ में विश्लेषण को संशोधित करें और ऊपर बनाए गए संकेतक टेम्पलेट को जोड़ें। analysis: metrics: - name: "404s percentage" templateRef: name: not-found-percentage thresholdRange: max: 5 interval: 1m

उपरोक्त कॉन्फ़िगरेशन कैनरी को यह जाँचकर मान्य करता है कि HTTP 404 अनुरोधों का QPS (प्रति सेकंड क्वेरी) कुल ट्रैफ़िक के 5% से अधिक है। यदि HTTP 404 अनुरोध 5% थ्रेशोल्ड से अधिक होते हैं, तो कैनरी रोलआउट विफल हो जाता है।

सारांश

उपरोक्त प्रक्रिया को अधिक कस्टम मेट्रिक्स जाँच, Webhook, मैन्युअल अनुमोदन और Slack या MS Teams सूचनाओं के साथ विस्तारित किया जा सकता है।

Apache APISIX और Flagger के एकीकरण के माध्यम से एक बहुत ही सुचारू कैनरी रिलीज़ प्राप्त की जाती है, जो रिलीज़ दक्षता में सुधार करती है और रिलीज़ जोखिम को कम करती है। भविष्य में, दोनों समुदाय और अधिक निकटता से सहयोग करेंगे ताकि Blue/Green Mirroring और A/B Testing जैसी अधिक प्रकाशन क्षमताओं को प्राप्त किया जा सके।

Tags: