Почему AISpeech выбирает Apache APISIX вместо NGINX в качестве Ingress Controller для k8s

Wei Jin

May 7, 2020

Case Study

Предисловие

Привет всем, я Цзинь Вэй из компании AISpeech, которая специализируется на распознавании и анализе компьютерной речи, и сегодня я расскажу о интеграции Apache APISIX с Kubernetes вместо использования нативного ingress.

На момент написания Apache APISIX уже применяется в нашей производственной среде и обрабатывает часть входящего трафика. Мы постепенно переносим трафик с нативного ingress, как показано на рисунке ниже.

Архитектурная схема

Фактически, APISIX-ingress-controller регистрирует IP-адрес pod в качестве узла upstream, что позволяет бизнес-трафику напрямую обращаться к pod, минуя kube DNS. На основе этого можно реализовать определенные политики балансировки нагрузки с помощью плагинов. Таким образом, с одной стороны, мы полагаемся на динамические возможности маршрутизации Apache APISIX для распределения трафика. С другой стороны, мы добавляем некоторые пользовательские плагины для удовлетворения бизнес-потребностей.

Из схемы выше видно, что APISIX-ingress-controller выглядит избыточным по сравнению с нативным ingress. В этой статье мы кратко объясним, почему мы отказались от нативного ingress и создали собственный ingress-контроллер на основе Apache APISIX.

Что такое Ingress

Коротко говоря, Ingress — это способ обработки внешнего трафика в Kubernetes.

Какую проблему решает Ingress

Поскольку сервисы внутри кластера Kubernetes представляют собой виртуальные сети, внешнему трафику требуется как минимум публичный IP-адрес и правильно сопоставленный порт для доступа к внутренним сервисам кластера.

Kubernetes предлагает различные способы (NodePort, LoadBalancer, Ingress, …) для предоставления доступа к внутренним сервисам. В сравнении, Ingress — это более экономичный способ реализации обратного прокси, предоставляя ограниченное количество публичных IP-адресов.

Говоря об обратном прокси, мы также можем напрямую настроить NGINX для этой цели, но поддерживать синхронизацию изменяющегося состояния сервисов в Kubernetes с NGINX значительно сложнее.

Хорошая новость заключается в том, что Kubernetes официально предоставляет и поддерживает NGINX ingress-контроллер, который помогает решить задачу обратного прокси. С этим NGINX ingress-контроллером мы можем проксировать весь трафик, который хочет получить доступ к Kubernetes, и направлять его на соответствующие сервисы.

Проблемы с нативным Ingress-контроллером Kubernetes

NGINX ingress-контроллер помогает нам поддерживать синхронизацию состояния между кластером Kubernetes и NGINX, а также предоставляет базовые возможности обратного прокси. Так почему же мы создали собственный ingress? Мы ожидаем большего от ingress-контроллера, чтобы удовлетворить больше бизнес-потребностей.

После использования нативного ingress-контроллера Kubernetes мы обнаружили следующие проблемы:

  1. Проблема с перезагрузкой

    Нативный ingress Kubernetes предназначен для передачи YAML-конфигураций в ingress-контроллер, их преобразования в конфигурации NGINX и последующей перезагрузки для применения изменений.

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

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

  2. Написание скриптов и заполнение параметров в аннотациях

    Нативный ingress-контроллер поддерживает фрагменты скриптов, определенные в аннотациях YAML-файла, что выглядит как временное решение для поддержки расширенных функций и, честно говоря, крайне неудобно в управлении. Большое количество скриптов в аннотациях создает проблемы для DevOps-специалистов.

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

  3. Отсутствие поддержки stateful балансировки нагрузки

    Расширенные политики балансировки нагрузки, такие как "постоянство сессии", не поддерживаются. Kubernetes — это система управления контейнеризированными приложениями, ориентированная на операции, что может быть связано с тем, что Kubernetes продвигает подход к развертыванию без сохранения состояния. Поэтому Kubernetes в ближайшее время официально не будет поддерживать эти противоречивые политики балансировки нагрузки. Фактически, Google уже пытался решить эти проблемы с помощью своего решения для сервисной сетки (Istio). Архитектура Istio идеальна, но за счет производительности, что может быть решено с помощью mixer v2.

    Поскольку Kubernetes поддерживает масштабирование, мы также можем расширить Apache APISIX для удовлетворения наших потребностей в расширенной балансировке нагрузки, так как Apache APISIX не только поддерживает "постоянство сессии" и другие методы балансировки нагрузки, но и имеет возможность масштабировать фазу балансировки.

  4. Динамические веса

    Бизнес-сервисы часто нуждаются в управлении трафиком по процентам, что становится проблемой в Kubernetes.

    Хотя Kubernetes поддерживает IPVS (IP Virtual Server) после версии 1.8, ни стартовые параметры "kube-proxy", ни аннотации "kube-route" не так удобны в использовании, как Apache APISIX, который внутренне абстрагирует маршруты, сервисы, потребителей, upstream, плагины и другие основные объекты. Настройка весов таких операций естественно поддерживается, достаточно просто изменить "вес узла" в "upstream".

  5. Негибкие возможности расширения

    Хотя Ingress изначально был разработан для обработки внешнего трафика, потребности во внешнем трафике не меньше, чем во внутреннем.

    Поэтапный выпуск на уровне сервиса, разрыв цепи, управление потоком, аутентификация, управление трафиком и другие требования чаще реализуются на Ingress.

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

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

Ingress-контроллер Apache APISIX

Благодаря мощным возможностям маршрутизации и расширяемости Apache APISIX, использование Apache APISIX в качестве реализации Ingress позволяет легко решить вышеупомянутые проблемы и предоставить сообществу дополнительный вариант ingress-контроллера. Диаграмма времени выглядит следующим образом:

Диаграмма времени

Для реализации ingress-контроллера Apache APISIX нам необходимо решить два типа фундаментальных проблем: одна — это синхронизация состояния между кластером Kubernetes и Apache APISIX; другая — определение объектов в Apache APISIX в Kubernetes (CRD).

Для быстрой интеграции Apache APISIX и использования его преимуществ мы создали проект Apache APISIX ingress controller (все желающие могут принять участие), который в настоящее время реализует первую базовую проблему: синхронизацию информации о pod Kubernetes с upstream Apache APISIX, а также реализует основное резервирование для решения проблем собственной высокой доступности.

Поскольку Kubernetes использует YAML для декларативного определения состояния кластера, нам необходимо определить CRD (Custom Resource Definitions) для объектов (маршрут/сервис/upstream/плагин) в Apache APISIX, чтобы интегрировать их в Kubernetes.

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

Эти функции станут целью наших следующих усилий, и мы приветствуем ваше участие.

Tags: