Всестороннее сравнение API Gateways, Kubernetes Gateways и Service Meshes

Navendu Pottekkat

Navendu Pottekkat

June 9, 2023

Technology

До сих пор существует много путаницы вокруг API-шлюзов, Kubernetes-шлюзов и сервисных сетей. Это связано с несколькими причинами:

  1. Люди часто упоминают эти технологии с использованием одинаковых ключевых слов, таких как канареечные развертывания, ограничение скорости и обнаружение сервисов.
  2. Все эти технологии используют обратные прокси.
  3. Некоторые API-шлюзы имеют свои собственные Kubernetes-шлюзы и сервисные сети, и наоборот.
  4. Существует множество статей/видео, которые сравнивают эти три технологии и делают выводы о том, почему одна из них лучше другой.

В этой статье я постараюсь объяснить эти технологии и рассказать, как они принципиально отличаются и подходят для разных сценариев использования.

API-шлюзы

API-шлюз находится между вашими клиентскими приложениями и вашими API. Он принимает все клиентские запросы, перенаправляет их на необходимые API и возвращает ответ клиентам в объединенном пакете.

По сути, это обратный прокси с множеством возможностей.

API-шлюз

Кроме того, API-шлюз может иметь такие функции, как аутентификация, безопасность, детализированное управление трафиком и мониторинг, что позволяет разработчикам API сосредоточиться только на бизнес-задачах.

Существует много решений для API-шлюзов. Некоторые из популярных бесплатных и открытых решений:

  • Apache APISIX: Высокопроизводительный, расширяемый, облачный API-шлюз, построенный на основе Nginx.
  • Gloo Edge: API-шлюз, построенный на основе Envoy proxy.
  • Kong: Плагинный API-шлюз, также построенный на Nginx.
  • Tyk: API-шлюз, написанный на Go, поддерживающий протоколы REST, GraphQL, TCP и gRPC.

Облачные платформы, такие как GCP, AWS и Azure, также имеют свои собственные проприетарные API-шлюзы.

API-шлюзы, Kubernetes-шлюзы и сервисные сети поддерживают канареечные развертывания — постепенное внедрение новой версии программного обеспечения для небольшой группы пользователей перед тем, как сделать его общедоступным.

Пример ниже показывает, как настроить канареечное развертывание в Apache APISIX.

Канареечные развертывания с API-шлюзом

Вы можете отправить запрос к APISIX Admin API с следующей конфигурацией:

curl http://127.0.0.1:9180/apisix/admin/routes/1 \ -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { "uri":"/*", "plugins":{ "traffic-split":{ "rules":[ { "weighted_upstreams":[ { "upstream":{ "name":"api-v1", "type":"roundrobin", "nodes":{ "api-v1:8080":1 } }, "weight":95 }, { "weight":5 } ] } ] } }, "upstream":{ "type":"roundrobin", "nodes":{ "api-v2:8080":1 } } }'

Теперь APISIX будет направлять 95% трафика на сервис api-v1 и 5% на сервис api-v2.

Kubernetes-шлюзы

Kubernetes-шлюзы — это просто API-шлюзы, которые являются нативными для Kubernetes. То есть, вы можете управлять этими API-шлюзами с помощью Kubernetes API, аналогично тому, как вы управляете подом, сервисом или развертыванием в Kubernetes.

В Kubernetes ваши API — это поды и сервисы, развернутые в кластере. Затем вы используете Kubernetes-шлюз для направления внешнего трафика в ваш кластер.

Kubernetes предоставляет два API для этого: Ingress API и Gateway API.

Kubernetes-шлюз

Kubernetes Ingress API

Ingress API был создан для преодоления ограничений типов сервисов по умолчанию, таких как NodePort и LoadBalancer, путем введения таких функций, как маршрутизация и SSL-терминация. Он также стандартизировал способ, которым вы предоставляете доступ к сервисам Kubernetes для внешнего трафика.

Он состоит из двух компонентов: Ingress и Ingress controller.

Объект Ingress в Kubernetes определяет набор правил, как внешний трафик может получить доступ к вашим сервисам.

Этот пример конфигурации показывает маршрутизацию трафика на основе пути URI с использованием объекта Kubernetes Ingress:

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: api-routes spec: ingressClassName: apisix rules: - http: paths: - backend: service: name: api-v1 port: number: 8080 path: /v1 pathType: Exact - backend: service: name: api-v2 port: number: 8080 path: /v2 pathType: Exact

Ingress controller реализует эти правила и направляет трафик в ваш кластер с использованием обратного прокси.

Существует более 20 реализаций Ingress controller. APISIX имеет Ingress controller, который оборачивает API-шлюз APISIX для работы в качестве Kubernetes Ingress.

APISIX Ingress

Ingress controller APISIX преобразует объект Kubernetes Ingress в конфигурацию APISIX.

Ingress controller APISIX преобразует конфигурацию

Затем APISIX реализует эту конфигурацию.

Канареечные развертывания с Kubernetes Ingress API

Вы можете заменить APISIX на любой другой Ingress controller, так как Ingress API не привязан к какой-либо конкретной реализации.

Эта независимость от поставщика хорошо работает для простых конфигураций. Но если вы хотите выполнить сложную маршрутизацию, такую как канареечное развертывание, вам придется полагаться на аннотации, специфичные для поставщика.

Пример ниже показывает, как настроить канареечное развертывание с использованием Nginx Ingress. Пользовательские аннотации, используемые здесь, специфичны для Nginx:

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-weight: "5" name: api-canary spec: rules: - http: paths: - backend: serviceName: api-v2 servicePort: 8080 path: /

Эта конфигурация будет направлять 5% трафика на сервис api-v2.

В дополнение к аннотациям, Ingress controller, такие как APISIX, имеют пользовательские Kubernetes CRD для преодоления ограничений Ingress API.

Пример ниже использует CRD APISIX, ApisixRoute, для настройки канареечного развертывания:

apiVersion: apisix.apache.org/v2 kind: ApisixRoute metadata: name: api-canary spec: http: - name: route match: paths: - /* backends: - serviceName: api-v1 servicePort: 8080 weight: 95 - serviceName: api-v2 servicePort: 8080 weight: 5

Эти пользовательские CRD значительно упрощают настройку Ingress и позволяют использовать все возможности API-шлюза, но за счет переносимости.

Kubernetes Gateway API

Gateway API — это новый объект Kubernetes, который призван "исправить" Ingress API.

Он вдохновлен пользовательскими CRD, разработанными Ingress controller, чтобы добавить такие функции, как маршрутизация на основе HTTP-заголовков, взвешенное разделение трафика и другие возможности, которые требуют пользовательских аннотаций с Ingress API.

Пример ниже показывает настройку канареечного развертывания с использованием Kubernetes Gateway API:

apiVersion: gateway.networking.k8s.io/v1alpha2 kind: HTTPRoute metadata: name: api-canary spec: rules: - backendRefs: - name: api-v1 port: 8080 weight: 95 - name: api-v2 port: 8080 weight: 5

Любой Ingress controller (который реализует Gateway API) теперь может реализовать эту конфигурацию.

Gateway API также вносит много улучшений по сравнению с Ingress API, но он все еще находится в стадии альфа, и реализации Gateway API постоянно меняются.

Сервисные сети

API-шлюзы и Kubernetes-шлюзы работают на границах приложений, решая задачи на уровне края сети, абстрагируя ваши API.

Сервисные сети решают другую задачу.

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

Обычно это достигается путем развертывания sidecar-прокси вместе с API/сервисами.

Сервисная сеть

Здесь sidecar-прокси обрабатывают взаимодействие между сервисами, вместо того чтобы разработчику приходилось кодировать логику сети в сервисах.

Существует множество сервисных сетей. Некоторые из популярных:

  • Istio: На данный момент самая популярная сервисная сеть. Она построена на основе Envoy proxy, который используют многие сервисные сети.
  • Linkerd: Легковесная сервисная сеть, использующая linkerd2-proxy, написанный на Rust специально для Linkerd.
  • Consul Connect: Сервисная сеть, акцентирующая внимание на безопасности и наблюдаемости. Она может работать как со встроенным прокси, так и с Envoy.

Новые предложения сервисных сетей, такие как Cilium, предлагают альтернативы sidecar-сервисным сетям, используя сетевые возможности напрямую из ядра через eBPF.

Сервисная сеть без sidecar

Типичная сервисная сеть требует 8 прокси для 8 сервисов, тогда как сервисные сети на основе eBPF, такие как Cilium, не требуют. Адаптировано из Cilium Service Mesh – Everything You Need to Know.

Сервисные сети также имеют базовые ingress/egress шлюзы для обработки север-южного трафика к сервисам и от них. Ingress шлюзы — это точки входа внешнего трафика в сервисную сеть, а egress шлюзы позволяют сервисам внутри сети получать доступ к внешним сервисам.

Ingress и egress шлюзы с сервисной сетью

Apache APISIX также имеет реализацию сервисной сети под названием Amesh. Она работает с плоскостью управления Istio, используя протокол xDS, заменяя стандартный Envoy proxy в sidecar.

Сервисная сеть позволяет вам настраивать канареечные развертывания. Например, вы можете разделить запросы от одного сервиса между двумя версиями другого сервиса.

Канареечные развертывания с сервисной сетью

Пример ниже показывает настройку канареечного развертывания с сервисной сетью Istio:

apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: api-virtual-service spec: hosts: - api http: - route: - destination: host: api subset: v1 weight: 80 - destination: host: api subset: v2 weight: 20
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: api-destination-rule spec: host: api subsets: - name: v1 labels: version: "1.0" - name: v2 labels: version: "2.0"

Эти конфигурации специфичны для Istio. Чтобы перейти на другую сервисную сеть, вам нужно создать другую, но аналогично зависящую от поставщика конфигурацию.

Спецификация Service Mesh Interface (SMI) была создана для решения этой проблемы переносимости.

Спецификация SMI — это набор Kubernetes CRD, которые пользователь сервисной сети может использовать для определения приложений без привязки к реализациям сервисных сетей.

Попытка стандартизации будет работать только в том случае, если все проекты будут участвовать. Но этого не произошло с SMI, и только несколько проектов активно участвовали.

Недавно Kubernetes SIG Network развивает Gateway API для поддержки сервисных сетей.

Инициатива GAMMA (Gateway API for Mesh Management and Administration) — это специальная группа в рамках проекта Gateway API с целями "исследовать, проектировать и отслеживать ресурсы Gateway API, семантику и другие артефакты, связанные с технологиями сервисных сетей и сценариями использования."

Gateway API — это естественный следующий шаг после Ingress API, но нам нужно подождать, чтобы увидеть, как он будет работать для сервисных сетей. Istio объявил о намерении использовать Gateway API в качестве стандартного API для управления всем трафиком и продолжает продвигать проект вперед.

Пример ниже показывает настройку канареечного развертывания в Istio с использованием Gateway API. Основная идея заключается в использовании parentRefs для привязки к другим сервисам вместо шлюза:

apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: api-canary spec: parentRefs: - kind: Service name: api-a port: 8080 rules: - backendRefs: - name: api-b-v1 port: 8080 weight: 95 - name: api-b-v2 port: 8080 weight: 5

Существуют некоторые опасения, что проект GAMMA может стать предвзятым в пользу одного конкретного проекта, чем в интересах более широкого сообщества, что в конечном итоге приведет к тому, что другие проекты будут использовать свои собственные API, аналогично сценарию с пользовательскими CRD после Kubernetes Ingress API.

Но проект Gateway API стал лучшей попыткой стандартизации управления трафиком в сервисных сетях. Проект SMI также присоединился к инициативе GAMMA с общей целью и будет помогать в продвижении согласованных реализаций Gateway API проектами сервисных сетей.

Другие проекты, такие как Flagger и Argo Rollouts, также интегрировались с Gateway API.

Что использовать?

Единственный правильный ответ на этот вопрос: "это зависит."

Если вы разрабатываете API и вам нужна аутентификация, безопасность, маршрутизация или метрики, вам лучше использовать API-шлюз, чем самостоятельно реализовывать это в ваших API.

Если вы хотите сделать что-то подобное в среде Kubernetes, вам следует использовать Kubernetes-шлюз, а не пытаться адаптировать ваш API-шлюз для работы в Kubernetes. К счастью, многие API-шлюзы также работают с нативными конфигурациями Kubernetes.

Но иногда функции, предлагаемые API-шлюзом + Ingress controller, могут быть избыточными для среды Kubernetes, и вам может потребоваться вернуться к простому управлению трафиком.

Сервисные сети, с другой стороны, решают совершенно другой набор задач. Они также предоставляют свои собственные шлюзы для обработки север-южного трафика (обычно этого достаточно), но также позволяют использовать ваши собственные шлюзы с большим количеством функций.

Конвергенция API-шлюза и сервисной сети через Kubernetes Gateway API должна упростить разработчикам приложений сосредоточиться на решении задач, а не беспокоиться о базовой реализации.

Проекты, такие как Apache APISIX, используют одну и ту же технологию для создания API-шлюзов и сервисных сетей и хорошо интегрируются с этими спецификациями, что стимулирует выбор, независимый от поставщика.

Также возможно, что вам не понадобится ни одна из этих технологий. Возможно, вам даже не нужны микросервисы или распределенная архитектура, но когда они вам понадобятся, шлюзы и сети могут значительно облегчить вашу жизнь.

Tags: