تقسيم حركة المرور في Apache APISIX Ingress Controller

Fei Han

March 27, 2021

Products

تقسيم حركة المرور (Traffic Split) هي ميزة تقوم بتقسيم وتوجيه حركة المرور إلى عدة خدمات خلفية. توفر حلول مثل بوابة API (مثل Apache APISIX و Traefik)، وشبكة الخدمات (Service Mesh) (مثل Istio و Linkerd) القدرة على تقسيم حركة المرور وتنفيذ وظائف مثل الإصدار التدريجي (Canary Release) و النشر الأزرق-الأخضر (Blue-Green Deployment).

تقسيم حركة المرور هو أيضًا ميزة رئيسية في Ingress Controller. كطبقة دخول في مجموعة Kubernetes، يُراد تقليل المخاطر الناتجة عن إصدار نسخة جديدة من التطبيق عن طريق إعداد بعض قواعد تقسيم حركة المرور في وحدة التحكم في الدخول (Ingress Controller)، بحيث يتم توجيه كمية قابلة للتحكم من حركة المرور إلى الحالات التي تم إصدارها حديثًا. في هذه المقالة، سنقدم تقسيم حركة المرور (المعروف أيضًا باسم الإصدار التدريجي) في Ingress Nginx و Kong Ingress Controller، وفي النهاية سنشرح تقسيم حركة المرور في Apache APISIX Ingress Controller.

(ملاحظة: من أجل وصف أكثر إيجازًا، نستخدم مصطلح "التطبيق التدريجي (canary app)" لوصف خدمة الخلفية التي يتم توجيهها بعد تطبيق قواعد الإصدار التدريجي، ومصطلح "التطبيق المستقر (stable app)" لوصف خدمة الخلفية التي يتم توجيهها عند عدم تطبيق قواعد الإصدار التدريجي، على سبيل المثال، التطبيق التدريجي والمستقر هما "foo-canary" و "foo" على التوالي في الرسم التوضيحي التالي.)

1.png

Ingress Nginx

يدعم Ingress Nginx الإصدار التدريجي (Canary Release)، ويتم التحكم فيه عن طريق تعليق "nginx.ingress.kubernetes.io/canary"، ويدعم عدة تعليقات لتخصيص هذه الميزة.

  • nginx.ingress.kubernetes.io/canary-by-header

يتم تحديد الوجهة بناءً على قيمة الرأس (المشار إليها بواسطة nginx.ingress.kubernetes.io/canary-by-header)، سيتم توجيه التطبيق التدريجي إذا كانت القيمة "always"، وإلا سيتم توجيه التطبيق المستقر (إذا كانت قيمة الرأس "never").

  • nginx.ingress.kubernetes.io/canary-by-header-value

هذا التعليق يمتد لـ nginx.ingress.kubernetes.io/canary-by-header، حيث لم تعد قيمة الرأس بحاجة إلى أن تكون "always" أو "never".

  • nginx.ingress.kubernetes.io/canary-by-header-pattern

مشابه لـ nginx.ingress.kubernetes.io/canary-by-header، ولكن القيمة هي تعبير عادي متوافق مع PCRE.

  • nginx.ingress.kubernetes.io/canary-by-cookie

استخدام حقل البيانات في رأس Cookie لتحديد خدمة الخلفية.

  • nginx.ingress.kubernetes.io/canary-weight

تعيين قيمة وزن بين 0 و 100، سيتم توجيه حركة المرور وفقًا لهذا الوزن، وزن 0 يعني أن جميع حركة المرور سيتم توجيهها إلى التطبيق التدريجي ووزن 100 سيوجه جميع حركة المرور إلى التطبيق المستقر.

مقتطف YAML التالي يقوم بتوجيه الطلبات التي يكون مسار URI الخاص بها يبدأ بـ "/get" ويتطابق مع نمط ".Mozilla." إلى التطبيق التدريجي "foo-canary".

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
      kubernetes.io/ingress.class: nginx
      nginx.ingress.kubernetes.io/canary: "true"
      nginx.ingress.kubernetes.io/canary-by-header: "User-Agent"
      nginx.ingress.kubernetes.io/canary-by-header-pattern:
".*Mozilla.*"
  name: ingress-v1beta1

Kong

بوابة Kong لديها مكون إضافي للإصدار التدريجي وتعرض هذا المكون الإضافي إلى وحدة التحكم في الدخول الخاصة بها عن طريق مورد KongPlugin. يحتاج المسؤولون/المستخدمون إلى إنشاء كائن KongPlugin وملء قاعدة الإصدار التدريجي، وحقن تعليق "konghq.com/plugins" إلى خدمة Kubernetes المستهدفة. أو يمكنك إنشاء كائن KongClusterPlugin لجعل قاعدة الإصدار التدريجي فعالة في المجموعة بأكملها.

apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: foo-canary
config:
  percentage: 30
  upstream_host: foo.com
  upstream_fallback: false
  upstream_port: 80
plugin: canary
---
apiVersion: v1
kind: Service
metadata:
  name: foo-canary
  labels:
    app: foo
  annotations:
    konghq.com/plugins: foo-canary
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
      name: http
  selector:
    app: foo
    canary: true

الحالة أعلاه تعيّن الخدمة "foo-canary" كـ "canary"، وتنشئ قاعدة إصدار تدريجي لتوجيه 30% من حركة المرور إلى هذه الخدمة.

Apache APISIX

يقوم Apache APISIX بتقسيم حركة المرور باستخدام قواعد مخصصة عن طريق مكونه الإضافي traffic-split، وتنفذ وحدة التحكم في الدخول Apache APISIX ميزة تقسيم حركة المرور إلى ApisixRoute (كدعم من الدرجة الأولى، دون الاعتماد على التعليقات) عن طريق هذا المكون الإضافي وقدرات مطابقة المسارات المرنة في ApisixRoute.

التقسيم بناءً على الوزن

عن طريق تكوين عدة خدمات Kubernetes، يمكن تطبيق قاعدة الإصدار التدريجي بناءً على الوزن كما يلي:

apiVersion: apisix.apache.org/v2alpha1
kind: ApisixRoute
metadata:
  name: foo-route
spec:
  http:
    - name: rule1
      match:
        hosts:
          - foo.org
        paths:
          - /get*
      backends:
        - serviceName: foo-canary
          servicePort: 80
          weight: 10
        - serviceName: foo
          servicePort: 80
          weight: 5

الحالة أعلاه توجّه ⅔ من الطلبات التي يكون المضيف الخاص بها "foo.org" وتبدأ مسار URI بـ "/get" إلى خدمة "foo-canary" والباقي إلى "foo".

يمكن أن يكون الوزن لخدمة الإصدار التدريجي صغيرًا للتحقق على نطاق صغير، وزيادة الوزن عن طريق تعديل ApisixRoute حتى يتم توجيه جميع حركة المرور إلى خدمة الإصدار التدريجي، وبذلك يتم الانتهاء من الإصدار بالكامل.

التقسيم بناءً على القواعد

حقل Exprs في ApisixRoute يسمح للمستخدمين بتكوين قواعد مطابقة مسارات مخصصة، ومن ناحية أخرى، يمكن تجميع عدة قواعد مسارات في كائن ApisixRoute واحد، وبالتالي هناك طريقة سلسة لتنفيذ تقسيم حركة المرور بناءً على القواعد.

apiVersion: apisix.apache.org/v2alpha1
kind: ApisixRoute
metadata:
  name: foo-route
spec:
  http:
    - name: rule1
      priority: 1
      match:
        hosts:
          - foo.org
        paths:
          - /get*
      backends:
        - serviceName: foo
          servicePort: 80
    - name: rule2
      priority: 2
      match:
        hosts:
          - foo.org
        paths:
          - /get*
        exprs:
          - subject:
              scope: Query
              name: id
            op: In
            set:
              - "3"
              - "13"
              - "23"
              - "33"
      backends:
        - serviceName: foo-canary
          servicePort: 80

سيتم فصل الطلبات التي يكون المضيف الخاص بها "foo.org" وتبدأ مسار URI بـ "/get" إلى جزأين:

  • المعلمة id التي تكون قيمتها 3، 13، 23 أو 33 ستطابق rule2، وسيتم توجيهها إلى foo-canary؛
  • الباقي سيطابق rule1 وسيتم توجيهها إلى foo.

الخلاصة

تقسيم حركة المرور (الإصدار التدريجي) في Ingress Nginx يدعم المخططات بناءً على الوزن والقواعد بناءً على الرأس، ولكنه يعتمد على التعليقات، مما يجعل دلالتها ضعيفة؛ طريقة Kong تدعم فقط تكوين الإصدار التدريجي بناءً على الوزن، مما يجعل السيناريوهات محدودة نوعًا ما، والتكوين معقد (تحتاج إلى تكوين عدة موارد)؛ في المقابل، تقسيم حركة المرور في وحدة التحكم في الدخول Apache APISIX مرن وسهل التكوين، ويعمل بشكل جيد لكل من مخططات تقسيم حركة المرور بناءً على الوزن والقواعد.

Tags: