العودة إلى الخدمات المصغرة مع Istio. الجزء 2

العودة إلى الخدمات المصغرة مع Istio. الجزء 2

ملحوظة. ترجمة.: الجزء الأول تم تخصيص هذه الدورة للتعرف على قدرات Istio وإثباتها في العمل. سنتحدث الآن عن جوانب أكثر تعقيدًا لتكوين شبكة الخدمة هذه واستخدامها ، وعلى وجه الخصوص حول التوجيه الدقيق وإدارة حركة مرور الشبكة.

نذكرك أيضًا أن المقالة تستخدم تكوينات (بيانات لـ Kubernetes و Istio) من المستودع إتقان istio.

إدارة المرور

مع Istio ، تمت إضافة ميزات جديدة إلى المجموعة لتوفير:

  • توجيه الطلب الديناميكي: الطرح الكناري ، اختبار أ / ب ؛
  • توزيع الحمل: بسيط ومتسق ، يعتمد على علامات التجزئة ؛
  • الشفاء بعد السقوط: المهلات ، المحاولات ، قواطع الدائرة ؛
  • مقدمة من الاعطال: التأخير ، وانقطاع الطلبات ، وما إلى ذلك.

مع استمرار المقالة ، سيتم عرض هذه الميزات باستخدام التطبيق المحدد كمثال ، وسيتم تقديم مفاهيم جديدة على طول الطريق. سيكون أول مفهوم من هذا القبيل DestinationRules (أي القواعد المتعلقة بمستلم حركة المرور / الطلبات - تقريبًا. الترجمة)، والتي نقوم من خلالها بتنشيط اختبار A / B.

اختبار أ / ب: قواعد الوجهة في الممارسة

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

لنشر الإصدار الثاني من الواجهة الأمامية المطلوبة للعرض التوضيحي لاختبار A / B ، قم بتشغيل الأمر التالي:

$ kubectl apply -f resource-manifests/kube/ab-testing/sa-frontend-green-deployment.yaml
deployment.extensions/sa-frontend-green created

يختلف بيان نشر "النسخة الخضراء" في مكانين:

  1. الصورة مبنية على علامة مختلفة - istio-green,
  2. القرون لها ملصق version: green.

لأن كلتا عمليتي النشر لهما التسمية app: sa-frontend، الطلبات الموجهة بواسطة الخدمة الافتراضية sa-external-services للخدمة sa-frontend، سيتم إعادة توجيهها إلى جميع مثيلاتها وسيتم توزيع الحمل بواسطة خوارزمية جولة روبنالأمر الذي سيؤدي إلى الحالة التالية:

العودة إلى الخدمات المصغرة مع Istio. الجزء 2
الملفات المطلوبة غير موجودة

لم يتم العثور على هذه الملفات بسبب حقيقة أنه تم تسميتها بشكل مختلف في إصدارات مختلفة من التطبيق. دعونا التحقق من ذلك:

$ curl --silent http://$EXTERNAL_IP/ | tr '"' 'n' | grep main
/static/css/main.c7071b22.css
/static/js/main.059f8e9c.js
$ curl --silent http://$EXTERNAL_IP/ | tr '"' 'n' | grep main
/static/css/main.f87cd8c9.css
/static/js/main.f7659dbb.js

هذا يعني أن index.htmlيمكن إرسال طلب إصدار واحد من الملفات الثابتة بواسطة موازن التحميل إلى البودات التي لها إصدار مختلف ، حيث لا توجد مثل هذه الملفات لأسباب واضحة. لذلك ، لكي يعمل التطبيق ، نحتاج إلى وضع قيد: "يجب أن يخدم الإصدار نفسه من التطبيق الذي قام بإرجاع index.html الطلبات اللاحقة".

سنحقق هدفنا من خلال موازنة تحميل متسقة قائمة على التجزئة. (موازنة تحميل تجزئة متسقة). في هذه الحالة يتم إرسال الطلبات من نفس العميل إلى نفس النسخة الخلفية، والتي يتم استخدام خاصية محددة مسبقًا - على سبيل المثال ، رأس HTTP. تم التنفيذ باستخدام DestinationRules.

الوجهة القواعد

بعد الخدمة الافتراضية أرسل طلبًا إلى الخدمة المطلوبة ، باستخدام DestinationRules ، يمكننا تحديد السياسات التي سيتم تطبيقها على حركة المرور المخصصة لمثيلات هذه الخدمة:

العودة إلى الخدمات المصغرة مع Istio. الجزء 2
إدارة حركة المرور مع موارد Istio

لاحظ: يتم عرض تأثير موارد Istio على حركة مرور الشبكة هنا في شكل مبسط للفهم. على وجه الدقة ، يتخذ المبعوث القرار بشأن المثيل الذي سيتم إرسال الطلب إليه في بوابة الدخول المكونة في CRD.

باستخدام قواعد الوجهة ، يمكننا إعداد موازنة الحمل لاستخدام تجزئات متسقة والتأكد من أن مثيل الخدمة نفسه يستجيب لنفس المستخدم. التكوين التالي يحقق هذا (DestinationRule-sa-frontend.yaml):

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: sa-frontend
spec:
  host: sa-frontend
  trafficPolicy:
    loadBalancer:
      consistentHash:
        httpHeaderName: version   # 1

1 - سيتم إنشاء التجزئة بناءً على محتويات رأس HTTP version.

قم بتطبيق التكوين باستخدام الأمر التالي:

$ kubectl apply -f resource-manifests/istio/ab-testing/destinationrule-sa-frontend.yaml
destinationrule.networking.istio.io/sa-frontend created

الآن قم بتشغيل الأمر أدناه وتأكد من حصولك على الملفات الصحيحة عند تحديد العنوان version:

$ curl --silent -H "version: yogo" http://$EXTERNAL_IP/ | tr '"' 'n' | grep main

لاحظ: لإضافة قيم مختلفة في العنوان واختبار النتائج مباشرة في المتصفح ، يمكنك استخدام هذا التمديد إلى Chrome (أو مع هذا لمتصفح Firefox - تقريبًا. ترجمة.).

بشكل عام ، تحتوي DestinationRules على المزيد من الميزات في مجال موازنة التحميل - تحقق من التفاصيل في الوثائق الرسمية.

قبل استكشاف VirtualService بشكل أكبر ، دعنا نزيل "الإصدار الأخضر" من التطبيق والقاعدة المقابلة لاتجاه حركة المرور عن طريق تنفيذ الأوامر التالية:

$ kubectl delete -f resource-manifests/kube/ab-testing/sa-frontend-green-deployment.yaml
deployment.extensions “sa-frontend-green” deleted
$ kubectl delete -f resource-manifests/istio/ab-testing/destinationrule-sa-frontend.yaml
destinationrule.networking.istio.io “sa-frontend” deleted

الانعكاس: الخدمات الافتراضية في الممارسة

التظليل ("حماية") أو الانعكاس ("انعكاس") تُستخدم في الحالات التي نرغب فيها في اختبار تغيير في الإنتاج دون التأثير على المستخدمين النهائيين: للقيام بذلك ، نقوم بتكرار الطلبات ("مرآة") إلى مثيل ثان حيث يتم إجراء التغييرات اللازمة ، والنظر في العواقب. ببساطة ، عندما يختار زميلك القضية الأكثر أهمية ويطلب سحب كرة ضخمة من الأوساخ بحيث لا يمكن لأحد أن يراجعها بالفعل.

لاختبار هذا السيناريو عمليًا ، دعنا ننشئ مثيلًا ثانيًا لـ SA-Logic مع الأخطاء (buggy) عن طريق تشغيل الأمر التالي:

$ kubectl apply -f resource-manifests/kube/shadowing/sa-logic-service-buggy.yaml
deployment.extensions/sa-logic-buggy created

والآن لنقم بتشغيل أمر للتأكد من أن جميع المثيلات بها app=sa-logic لديهم أيضًا تسميات بالإصدارات المقابلة:

$ kubectl get pods -l app=sa-logic --show-labels
NAME                              READY   LABELS
sa-logic-568498cb4d-2sjwj         2/2     app=sa-logic,version=v1
sa-logic-568498cb4d-p4f8c         2/2     app=sa-logic,version=v1
sa-logic-buggy-76dff55847-2fl66   2/2     app=sa-logic,version=v2
sa-logic-buggy-76dff55847-kx8zz   2/2     app=sa-logic,version=v2

خدمة sa-logic أهداف القرون مع التسمية app=sa-logic، لذلك سيتم توزيع جميع الطلبات على جميع المثيلات:

العودة إلى الخدمات المصغرة مع Istio. الجزء 2

... لكننا نريد توجيه الطلبات إلى مثيلات v1 ونسخها إلى مثيلات v2:

العودة إلى الخدمات المصغرة مع Istio. الجزء 2

نحقق ذلك من خلال VirtualService بالاشتراك مع DestinationRule ، حيث تحدد القواعد المجموعات الفرعية ومسارات VirtualService لمجموعة فرعية معينة.

تحديد مجموعات فرعية في قواعد الوجهة

مجموعات فرعية (مجموعات فرعية) المحددة من خلال التكوين التالي (مجموعات فرعية sa-logic-destinationrule.yaml):

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: sa-logic
spec:
  host: sa-logic    # 1
  subsets:
  - name: v1        # 2
    labels:
      version: v1   # 3
  - name: v2
    labels:
      version: v2

  1. يستضيف (host) يحدد أن هذه القاعدة تنطبق فقط على الحالات التي يتجه فيها المسار نحو الخدمة sa-logic;
  2. الأسماء (name) تستخدم المجموعات الفرعية عند التوجيه إلى مثيلات المجموعة الفرعية ؛
  3. ملصق (label) يحدد أزواج المفتاح والقيمة التي يجب أن تتطابق معها المثيلات لتصبح جزءًا من مجموعة فرعية.

قم بتطبيق التكوين باستخدام الأمر التالي:

$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-destinationrule.yaml
destinationrule.networking.istio.io/sa-logic created

الآن بعد أن تم تحديد المجموعات الفرعية ، يمكننا المضي قدمًا وتكوين VirtualService لتطبيق القواعد على طلبات sa-logic بحيث:

  1. تم توجيهه إلى مجموعة فرعية v1,
  2. انعكاس لمجموعة فرعية v2.

يسمح لك البيان التالي بتحقيق أهدافك (مجموعات فرعية sa-logic- التظليل مقابل yaml):

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: sa-logic
spec:
  hosts:
    - sa-logic          
  http:
  - route:
    - destination:
        host: sa-logic  
        subset: v1      
    mirror:             
      host: sa-logic     
      subset: v2

لا حاجة إلى شرح هنا ، لذلك دعونا نراه في العمل:

$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-shadowing-vs.yaml
virtualservice.networking.istio.io/sa-logic created

دعنا نضيف حمولة عن طريق استدعاء الأمر التالي:

$ while true; do curl -v http://$EXTERNAL_IP/sentiment 
    -H "Content-type: application/json" 
    -d '{"sentence": "I love yogobella"}'; 
    sleep .8; done

لنلقِ نظرة على النتائج في Grafana ، حيث يمكنك أن ترى أن الإصدار الذي يحتوي على أخطاء (buggy) يفشل في ما يقرب من 60٪ من الطلبات ، ولكن لا تؤثر أي من هذه الإخفاقات على المستخدمين النهائيين حيث يتم الرد عليهم من خلال خدمة قيد التشغيل.

العودة إلى الخدمات المصغرة مع Istio. الجزء 2
نجاح استجابات الإصدارات المختلفة لخدمة منطق sa

هذا هو المكان الذي رأينا فيه لأول مرة كيفية تطبيق VirtualService على خدمتنا Envoys: متى sa-web-app يقدم طلبًا إلى sa-logic، يمر عبر المبعوث الجانبي ، والذي - من خلال VirtualService - تم تكوينه لتوجيه الطلب إلى المجموعة الفرعية v1 وعكس الطلب إلى المجموعة الفرعية v2 من الخدمة sa-logic.

أعلم: لقد كان لديك بالفعل وقت للاعتقاد بأن الخدمات الافتراضية بسيطة. في القسم التالي ، سنوسع هذا الرأي بالقول إنها رائعة حقًا.

Canary Rollouts

Canary Deployment هي عملية طرح إصدار جديد من التطبيق لعدد صغير من المستخدمين. يتم استخدامه للتأكد من عدم وجود مشاكل في الإصدار ، وبعد ذلك فقط ، وبعد التأكد بالفعل من جودته الكافية (الإصدار) ، قم بتوزيعه علىоجمهور أكبر.

لإثبات عمليات إطلاق الكناري ، سنستمر بمجموعة فرعية buggy у sa-logic.

دعونا لا نضيع الوقت في تفاهات ونرسل على الفور 20٪ من المستخدمين إلى الإصدار الذي به أخطاء (سيمثل طرح الكناري لدينا) ، و 80٪ المتبقية إلى خدمة عادية. للقيام بذلك ، قم بتطبيق VirtualService (مجموعات فرعية sa-logic-canary-vs.yaml):

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: sa-logic
spec:
  hosts:
    - sa-logic    
  http:
  - route: 
    - destination: 
        host: sa-logic
        subset: v1
      weight: 80         # 1
    - destination: 
        host: sa-logic
        subset: v2
      weight: 20 # 1

1 هو الوزن (weight) يحدد النسبة المئوية للطلبات التي سيتم توجيهها إلى المستلم ، أو مجموعة فرعية من المستلم.

قم بتحديث تكوين VirtualService السابق لـ sa-logic بالأمر التالي:

$ kubectl apply -f resource-manifests/istio/canary/sa-logic-subsets-canary-vs.yaml
virtualservice.networking.istio.io/sa-logic configured

.. وسنرى على الفور أن بعض الطلبات تؤدي إلى فشل:

$ while true; do 
   curl -i http://$EXTERNAL_IP/sentiment 
   -H "Content-type: application/json" 
   -d '{"sentence": "I love yogobella"}' 
   --silent -w "Time: %{time_total}s t Status: %{http_code}n" 
   -o /dev/null; sleep .1; done
Time: 0.153075s Status: 200
Time: 0.137581s Status: 200
Time: 0.139345s Status: 200
Time: 30.291806s Status: 500

تقوم VirtualServices بتشغيل عمليات إطلاق canary: في هذه الحالة ، قمنا بتضييق نطاق التأثير المحتمل للمشكلات إلى 20٪ من قاعدة المستخدمين. رائع! الآن ، في كل حالة عندما لا نكون متأكدين من الكود الخاص بنا (بمعنى آخر ، دائمًا ...) ، يمكننا استخدام النسخ المتطابق والكناري.

المهلات وإعادة المحاولة

لكن الأخطاء لا تنتهي دائمًا في الكود. في قائمة من8 مفاهيم خاطئة في الحوسبة الموزعة"في المقام الأول هو الرأي الخاطئ بأن" الشبكة موثوقة ". في الواقع الشبكة لا موثوق بها ، ولهذا السبب نحتاج إلى مهلات (المهلات) وإعادة المحاولة (يعيد المحاولة).

للتوضيح ، سنستمر في استخدام نفس إصدار المشكلة sa-logic (buggy) ، وسيتم محاكاة عدم موثوقية الشبكة من خلال حالات فشل عشوائية.

دع خدمة عربات التي تجرها الدواب لديها فرصة 1/3 للاستجابة لفترة طويلة جدًا ، و 1/3 للانتهاء بخطأ داخلي في الخادم ، و 1/3 من عرض الصفحة بنجاح.

للتخفيف من تأثير هذه المشكلات وتحسين حياة مستخدمينا ، يمكننا:

  1. أضف مهلة إذا كانت الخدمة تستجيب لفترة أطول من 8 ثوانٍ ،
  2. أعد المحاولة إذا فشل الطلب.

للتنفيذ ، نستخدم تعريف المورد التالي (sa-logic-retries-timeouts- مقابل yaml):

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: sa-logic
spec:
  hosts:
    - sa-logic
  http:
  - route: 
    - destination: 
        host: sa-logic
        subset: v1
      weight: 50
    - destination: 
        host: sa-logic
        subset: v2
      weight: 50
    timeout: 8s           # 1
    retries:
      attempts: 3         # 2
      perTryTimeout: 3s # 3

  1. تم ضبط مهلة الطلب على 8 ثوانٍ ؛
  2. تتم إعادة محاولة الطلبات 3 مرات ؛
  3. وتعتبر كل محاولة غير ناجحة إذا تجاوز زمن الاستجابة 3 ثوانٍ.

هذا تحسين لأن المستخدم لا يضطر إلى الانتظار أكثر من 8 ثوانٍ وسنقوم بثلاث محاولات جديدة للحصول على استجابة في حالة الفشل ، مما يزيد من فرصة الاستجابة الناجحة.

قم بتطبيق التكوين المحدث باستخدام الأمر التالي:

$ kubectl apply -f resource-manifests/istio/retries/sa-logic-retries-timeouts-vs.yaml
virtualservice.networking.istio.io/sa-logic configured

وتحقق في مخططات Grafana من أن عدد الردود الناجحة قد انتهى:

العودة إلى الخدمات المصغرة مع Istio. الجزء 2
تحسينات في إحصائيات النجاح بعد إضافة المهلات وإعادة المحاولة

قبل الانتقال إلى القسم التالي (بتعبير أدق - بالفعل في الجزء التالي من المقالة ، لأنه في هذه التجارب العملية لن يكون هناك المزيد - الترجمة تقريبًا.)، يمسح sa-logic-buggy و VirtualService عن طريق تشغيل الأوامر التالية:

$ kubectl delete deployment sa-logic-buggy
deployment.extensions “sa-logic-buggy” deleted
$ kubectl delete virtualservice sa-logic
virtualservice.networking.istio.io “sa-logic” deleted

قواطع دوائر وأنماط الحاجز

نحن نتحدث عن نمطين مهمين في بنية الخدمات المصغرة التي تسمح لك بتحقيق استعادة الذات. (شفاء ذاتي) خدمات.

قواطع دوائر ("قاطع دائرة") تُستخدم لإيقاف الطلبات الواردة إلى مثيل خدمة يعتبر غير صحي واستعادته أثناء إعادة توجيه طلبات العميل إلى مثيلات سليمة لتلك الخدمة (مما يزيد من معدل النجاح). (ترجمة. ملاحظة: يمكن العثور على وصف أكثر تفصيلاً للنمط ، على سبيل المثال ، هنا.)

الحاجز ("تقسيم") يعزل حالات الفشل في الخدمات عن هزيمة النظام بأكمله. على سبيل المثال ، الخدمة B معطلة ، وتقوم خدمة أخرى (عميل الخدمة B) بتقديم طلب للخدمة B ، مما يتسبب في استخدام مجموعة مؤشرات الترابط الخاصة بها وعدم قدرتها على خدمة الطلبات الأخرى (حتى لو لم تكن تنتمي إلى الخدمة ب). (ترجمة. ملاحظة: يمكن العثور على وصف أكثر تفصيلاً للنمط ، على سبيل المثال ، هنا.)

سأحذف تفاصيل تنفيذ هذه الأنماط لأنه من السهل العثور عليها الوثائق الرسمية، وأريد حقًا إظهار المصادقة والترخيص ، والتي ستتم مناقشتها في الجزء التالي من المقالة.

PS من المترجم

اقرأ أيضًا على مدونتنا:

المصدر: www.habr.com

إضافة تعليق