أتمتة قرارات Canary Release في Kubernetes Cluster الخاص بك

Chao Zhang

Chao Zhang

December 30, 2022

Technology

الخلفية

في الوقت الحاضر، أصبحت هندسة البرمجيات الدقيقة (microservices) نمطًا معماريًا برمجيًا نموذجيًا ومستخدمًا على نطاق واسع. تكون الخدمات مترابطة بشكل فضفاض وتتعاون عبر واجهات برمجة التطبيقات (APIs). يجعل نمط الخدمات الدقيقة كل تطبيق قابلاً للنشر والصيانة بشكل مستقل، مما يجعل الإصدارات أكثر تكرارًا. كما نعلم جميعًا، فإن الإصدار محفوف بالمخاطر؛ فأنت لا تعرف أبدًا ما إذا كانت هناك أية أخطاء في الإصدار الجديد. لهذا السبب يستخدم الناس استراتيجيات مثل الإصدار التدريجي (Canary Release) والنشر الأزرق-الأخضر (Blue-Green Deployment) لنشر أحدث إصدار بشكل تدريجي وتقليل المخاطر.

يقوم الإصدار التدريجي بتقسيم حركة المرور إلى مجموعتين من الخدمة المستهدفة، المجموعة المستقرة والمجموعة التدريجية. تعرض بوابة API مثل Apache APISIX بنية الخدمات الدقيقة بشكل فعال وآمن إلى واجهات برمجة التطبيقات. وهي مجهزة بميزة الإصدار التدريجي. عادةً ما تكون هناك طريقتان لتحديد كيفية تقسيم حركة المرور: الطريقة القائمة على الوزن وطريقة التعبير الشرطي.

الطريقة القائمة على الوزن

الطريقة القائمة على الوزن

يحتاج المستخدمون إلى تحديد نسبة حركة المرور التي ستصل إلى المجموعة التدريجية. في الصورة أعلاه، 95% من حركة المرور ستوجه إلى الخدمة المستقرة بينما الـ 5% الأخرى ستوجه إلى الخدمة التدريجية.

طريقة التعبير الشرطي

الطريقة القائمة على التعبيرات الشرطية

تشير طريقة التعبير الشرطي للطلب إلى أن حركة المرور التي تتوافق مع الخصائص المحددة فقط ستصل إلى المجموعة التدريجية. على سبيل المثال، فقط طلبات HTTP التي تحتوي على رأس الطلب X-Debug وقيمته الفعلية ستصل إلى الخدمة التدريجية.

أتمتة الإصدار التدريجي

عندما تقوم بتشغيل بوابة API عن طريق استدعاء واجهة برمجة التطبيقات أو لوحة التحكم، سيكون هناك تأخر زمني في تعديل نسبة حركة المرور (للطريقة القائمة على الوزن) أو التعبيرات الشرطية (للطريقة القائمة على التعبير الشرطي). في الوقت الحاضر، يستخدم المزيد والمزيد من المستخدمين Kubernetes لتنظيم خدماتهم الدقيقة. هل يمكن للناس بدء الإصدار التدريجي بمجرد إنشاء إصدار الخدمة الجديد؟ في هذه المقالة، سأوضح لك كيفية استخدام API7 Cloud لأتمتة الإصدار التدريجي في مجموعة Kubernetes الخاصة بك.

ما هو API7 Cloud

API7 Cloud هو منصة SaaS متعددة المواقع لأي سحابة لنشر ومراقبة ومراقبة ومراقبة واجهات برمجة التطبيقات على نطاق واسع. قم بتشغيل واجهات برمجة التطبيقات الخاصة بك في أي مكان ولكن قم بإدارتها في مكان واحد فقط. يستخدم API7 Cloud Apache APISIX كبوابة API لعرض واجهات برمجة التطبيقات الخاصة بك بشكل فعال وآمن.

API7 Cloud

لاستخدام API7 Cloud، يجب عليك نشر Apache APISIX على بنيتك التحتية، مثل Docker و Kubernetes. يمكنك استخدام Cloud CLI لتسهيل النشر.

# قم بتكوين رمز وصول من وحدة تحكم API7 Cloud.
cloud-cli configure --token {YOUR TOKEN}

# نشر Apache APISIX (الإصدار 2.15.1) إلى مساحة الاسم apisix، مع نسخة واحدة فقط.
cloud-cli deploy kubernetes \
  --name my-apisix \
  --namespace apisix \
  --replica-count 1 \
  --apisix-image apache/apisix:2.15.1-centos

الإصدار التدريجي هو إحدى الميزات المدمجة في API7 Cloud. يمكن للمستخدمين تكوين قواعد الإصدار التدريجي عبر وحدة التحكم أو استدعاء واجهة برمجة التطبيقات المفتوحة لـ API7 Cloud. هدفنا هو أتمتة قرارات الإصدار التدريجي، لذلك سنستخدم الطريقة الأخيرة.

السيناريو

لنفترض في مجموعة Kubernetes الخاصة بنا، هناك تطبيق بسيط لصفحة الأخطاء، والذي يعيد دائمًا رسالة خطأ. نحن ننشر الإصدار 2.0 ونريد استخدام استراتيجية الإصدار التدريجي لتقليل مخاطر الإصدار. علاوة على ذلك، نريد أيضًا جعل العملية بأكملها تلقائية. لذلك، نقوم بإنشاء وحدة تحكم للإصدار التدريجي، والتي تراقب التغييرات في موارد خدمة Kubernetes، ثم تقوم بإنشاء / تعديل الإصدارات التدريجية على API7 Cloud عبر SDK Go الخاص بـ API7 Cloud. نستخدم فقط الطريقة القائمة على الوزن لتقسيم حركة المرور. سيتم نشر جميع المكونات، بما في ذلك بوابة Apache APISIX API، على Kubernetes بحيث يكون الرسم التخطيطي كالتالي:

الرسم التخطيطي

تراقب وحدة تحكم الإصدار التدريجي تغييرات الخدمة وتتفاعل وفقًا لبعض التعليقات التوضيحية، على وجه التحديد:

  • إذا كانت الخدمة تحتوي على التعليق التوضيحي api7.cloud/published-service، فستحاول وحدة تحكم الإصدار التدريجي إنشاء تطبيق على API7 Cloud.
  • إذا كانت الخدمة تحتوي على التعليق التوضيحي api7.cloud/published-canary-service، فستحاول وحدة تحكم الإصدار التدريجي إعداد قاعدة الإصدار التدريجي على API7 Cloud وسيحدد التعليق التوضيحي api7.cloud/published-service-canary-percentage النسبة المئوية.

لاحظ أن هذه الوحدة التحكم ليست مكتفية ذاتيًا (لا تقوم بحذف التطبيق إذا تم حذف الخدمة)، ولكنها كافية لإظهار عملية الإصدار التدريجي التلقائي.

هيا بنا!

لنبدأ بنشر Apache APISIX ووحدة تحكم الإصدار التدريجي. كما ذكرنا أعلاه، نستخدم Cloud CLI لنشر Apache APISIX. لدينا أيضًا ملفين YAML (error-page/manifest-v1.yaml و controller/manifest.yaml) لنشر تطبيق صفحة الأخطاء ووحدة تحكم الإصدار التدريجي.

  1. يرجى تحضير مجموعة Kubernetes متاحة إذا كنت ترغب في تنفيذ الأوامر التالية.
  2. تحتاج وحدة تحكم الإصدار التدريجي إلى رمز وصول لاستدعاء واجهة برمجة التطبيقات الخاصة بـ API7 Cloud. نحصل على الرمز وفقًا لهذا المستند ونخزن الرمز في سر K8s.
kubectl create namespace canary-release-demo
# نشر الإصدار v1 من تطبيق صفحة الأخطاء.
kubectl apply -f https://raw.githubusercontent.com/tokers/canary-release-automation-demo/main/error-page/manifest-v1.yaml -n canary-release-demo

# إنشاء سر K8s لحفظ رمز وصول API7 Cloud.
kubectl create secret generic api7-cloud --namespace canary-release-demo --from-literal token={Your Access Token}

# نشر وحدة تحكم الإصدار التدريجي.
kubectl apply -f https://raw.githubusercontent.com/tokers/canary-release-automation-demo/main/controller/manifest.yaml -n canary-release-demo

# التحقق من أن جميع أعباء العمل طبيعية.
kubectl get all -n canary-release-demo

التحقق من الوكيل

لننشر هذه الخدمة عن طريق إضافة تعليق توضيحي.

kubectl annotate service -n canary-release-demo error-page-v1 "api7.cloud/published-service=error-page"

ستراقب وحدة تحكم الإصدار التدريجي هذا التغيير وتنشئ تطبيقًا على API7 Cloud. الآن لنصل إلى Apache APISIX لمعرفة ما إذا كان الوكيل يعمل بشكل طبيعي.

kubectl port-forward -n canary-release-demo service/apisix-gateway 10080:80
curl http://127.0.0.1:10080/api/error_page -H 'Host: error-page' -s

إذا كان كل شيء على ما يرام، سترى {"error": "injected by error_page service", "version": "v1"}.

حاليًا، تقوم وحدة تحكم الإصدار التدريجي بإنشاء واجهة برمجة تطبيقات "تطابق كل شيء" في التطبيق، واسم المضيف هو نفس اسم التطبيق (error-page).

نشر الإصدار V2

نريد نشر الإصدار 2 لتطبيق صفحة الأخطاء. أولاً، نقوم بنشر الإصدار 2 عن طريق تطبيق ملف manifest-v2.yaml. نقوم بإضافة التعليقات التوضيحية للإصدار التدريجي لخدمة error-page-v2.

kubectl apply -f https://raw.githubusercontent.com/tokers/canary-release-automation-demo/main/error-page/manifest-v2.yaml -n canary-release-demo

# إخبار وحدة تحكم الإصدار التدريجي أننا نمكن الإصدار التدريجي لـ error-page-v2، والنسبة المئوية هي 10%.
kubectl annotate service -n canary-release-demo error-page-v2 "api7.cloud/published-canary-service=true" "api7.cloud/published-service-canary-percentage=10"

# بدء الإصدار التدريجي.
kubectl annotate service -n canary-release-demo error-page-v2 "api7.cloud/published-service=error-page"

الآن لنرسل 100 طلب إلى Apache APISIX مرة أخرى ونرى ما إذا كانت بعض الطلبات قد تم توجيهها إلى الخدمة التدريجية error-page-v2.

kubectl port-forward -n canary-release-demo service/apisix-gateway 10080:80
for ((i=0; i<100; i++)); do
  curl http://127.0.0.1:10080/api/error_page -H 'Host: error-page' -s
done

سيصل حوالي 10% من الطلبات إلى error-page-v2 (ليس بالضبط 10% بسبب الاستراتيجية الداخلية التي يختارها Apache APISIX للخلفية) إذا كان كل شيء على ما يرام.

التراجع

لقد وجدنا أن الإصدار 2 غير مستقر ونريد التراجع عنه. قبل أن نفعل ذلك، سنوقف الإصدار التدريجي أولاً، لذلك نقوم بتغيير النسبة المئوية إلى 0. ثم نرسل الطلبات إلى Apache APISIX مرة أخرى.

kubectl annotate service -n canary-release-demo error-page-v2 "api7.cloud/published-service-canary-percentage=0" --overwrite
for ((i=0; i<100; i++)); do
  curl http://127.0.0.1:10080/api/error_page -H 'Host: error-page' -s
done

سترى أن جميع الطلبات الآن تذهب إلى error-page-v1.

الإصدار

بعد فترة طويلة، نعتقد أن الإصدار 2 مستقر بما فيه الكفاية، ونريد أن تصل جميع الطلبات إلى الإصدار 2. ثم يمكننا إيقاف تشغيل تطبيق صفحة الأخطاء الإصدار 1. لذلك نقوم بتغيير النسبة المئوية إلى 100%.

kubectl annotate service -n canary-release-demo error-page-v2 "api7.cloud/published-service-canary-percentage=100" --overwrite
for ((i=0; i<100; i++)); do
  curl http://127.0.0.1:10080/api/error_page -H 'Host: error-page' -s
done

الآن يتم توجيه جميع الطلبات إلى error-page-v2. ويمكن إيقاف تشغيل error-page-v1 بأمان.

الخلاصة

الإصدار التدريجي هو سلاح فعال للإصدار. ومع ذلك، قد يكون تعديل استراتيجية الإصدار التدريجي متأخرًا. تظهر هذه المقالة كيفية تشغيل الإصدارات التدريجية بشكل إعلاني وأتمتة الإصدار التدريجي إلى حد ما. قد يسعى بعض الأشخاص إلى تحقيق الإصدار التدريجي التلقائي بالكامل بمساعدة مكونات GitOps. على سبيل المثال، باستخدام Argo Rollouts، يمكن للمرء الترويج للخدمات أو التراجع عنها تلقائيًا. يقوم Argo Rollouts بطلب مقاييس الخدمة ودمجها مع وحدات تحكم المدخلات لتغيير CRDs الخاصة بها. في النهاية، ستقوم بوابة API بتوجيه الطلبات بالنسب الصحيحة إلى الإصدار التدريجي.

المرجع

الكود المصدري لتطبيق صفحة الأخطاء ووحدة تحكم الإصدار التدريجي: https://github.com/tokers/canary-release-automation-demo.

Tags: