Разделение трафика в Apache APISIX Ingress Controller

Fei Han

March 27, 2021

Products

Traffic Split — это функция, которая разделяет и направляет трафик на несколько серверных служб. Решения, такие как API Gateway (например, Apache APISIX и Traefik), Service Mesh (например, Istio и Linkerd), способны выполнять разделение трафика и реализовывать функциональность, такую как Canary Release и Blue-Green Deployment.

Разделение трафика также является ключевой функцией в Ingress Controller. Как слой ingress в кластере Kubernetes, он позволяет снизить риск при выпуске новой версии приложения, устанавливая правила разделения трафика в ingress controller, чтобы только контролируемый объем трафика направлялся на новые выпущенные экземпляры. В этой статье мы рассмотрим разделение трафика (также называемое canary release) в Ingress Nginx и Kong Ingress Controller, а в конечном итоге объясним разделение трафика в Apache APISIX Ingress Controller.

(Примечание: Для более лаконичного описания мы используем термин "canary app" для описания серверной службы, на которую направляется трафик после срабатывания canary-правил, и термин "stable app" для описания серверной службы, на которую направляется трафик, если canary-правила не срабатывают. Например, canary и 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). Canary app будет выбран, если значение заголовка равно "always", в противном случае будет выбран stable app (значение заголовка — "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 означает, что весь трафик будет направлен на canary app, а вес 100 — на stable app.

Следующий фрагмент YAML проксирует запросы, URI-путь которых начинается с "/get", а User-Agent соответствует шаблону ".Mozilla.", на canary app "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 Gateway имеет плагин для canary release и предоставляет этот плагин через ресурс KongPlugin в своем ingress controller. Администраторы/Пользователи должны создать объект KongPlugin и заполнить правило canary release, добавив аннотацию "konghq.com/plugins" к целевой Kubernetes Service. Или можно создать объект 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", и создано правило canary release, которое проксирует 30% трафика на эту службу.

Apache APISIX

Apache APISIX разделяет трафик с помощью пользовательских правил через плагин traffic-split, а Apache APISIX Ingress Controller реализует функцию разделения трафика в ApisixRoute (как встроенную поддержку, без использования аннотаций) с помощью этого плагина и гибких возможностей сопоставления маршрутов в ApisixRoute.

На основе веса

Путем настройки нескольких Kubernetes Services можно применить правило canary на основе веса:

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

В приведенном выше примере ⅔ запросов с Host "foo.org" и префиксом URI-пути "/get" направляются на службу "foo-canary", а остальные — на "foo".

Вес для canary-службы может быть небольшим для проверки в малом масштабе, а затем увеличиваться путем изменения ApisixRoute, пока весь трафик не будет направлен на canary-службу, завершая выпуск полностью.

На основе правил

Поле 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

Запросы с Host "foo.org" и префиксом URI-пути "/get" будут разделены на две части:

  • Параметр id со значением 3, 13, 23 или 33 попадет в rule2 и будет перенаправлен на foo-canary;
  • Остальные попадут в rule1 и будут направлены на foo.

Итог

Разделение трафика (Canary release) в Ingress Nginx поддерживает схемы на основе веса и правил заголовков, но оно зависит от аннотаций, что делает семантику слабой; Способ Kong поддерживает только настройку canary release по весу, что ограничивает сценарии использования и усложняет настройку (необходимо настраивать несколько ресурсов); В отличие от этого, разделение трафика в Apache APISIX Ingress Controller является гибким и простым в настройке, оно хорошо работает как для схем на основе веса, так и для схем на основе правил.

Tags: