При запуске кластера Kubernetes для конкретного приложения следует понимать, какие требования представляет к этому ресурсу само приложение, бизнес и разработчики. При наличии этой информации можно приступать к принятию архитектурного решения и, в частности, к выбору конкретного Ingress-контроллера, коих на сегодняшний день уже большое количество. Чтобы составить базовое представление об имеющихся вариантах без необходимости изучать множество статей/документации и т.п., мы и подготовили этот обзор, включив в него основные (production ready) Ingress-контроллеры.

Надеемся, что он поможет коллегам в выборе архитектурного решения — по крайней мере, станет отправной точкой для получения более подробной информации и практических экспериментов. Предварительно мы изучили другие подобные материалы в сети и, как ни странно, не обнаружили ни одного более-менее полного, а главное — структурированного — обзора. Итак, заполним же этот пробел!

Критерии


Чтобы в принципе проводить сравнение и получить сколько-нибудь полезный результат, надо понимать не просто предметную область, но и иметь конкретный список критериев, которые и будут задавать вектор исследования. Не претендуя на анализ всех возможных случаев применения Ingress/Kubernetes, мы постарались выделить наиболее общие требования к контроллерам — будьте готовы, что всю свою специфику и частности в любом случае придётся изучать отдельно.

Но начну с характеристик, которые стали настолько привычными, что реализованы во всех решениях и не рассматриваются:

  • динамическое обнаружение сервисов (service discovery);
  • SSL-терминирование;
  • работа с websocket'ами.

Теперь — о пунктах сравнения:

Поддерживаемые протоколы


Один из основополагающих критериев для выбора. Ваше ПО может работать не по стандартному HTTP или же требовать работу сразу по множеству протоколов. Если ваш случай — нестандартный, обязательно берите в расчет этот фактор, дабы не пришлось потом перенастраивать кластер. У всех контроллеров список поддерживаемых протоколов варьируется.

ПО в основе


Есть несколько вариантов приложений, на которых основан контроллер. Популярные — это nginx, traefik, haproxy, envoy. В общем случае, возможно, не слишком влияет на то, как принимается и передается трафик, однако всегда полезно знать потенциальные нюансы и особенности того, что «под капотом».

Маршрутизация трафика


На основе чего можно принимать решение о направлении трафика в тот или иной сервис? Обычно это host и path, но бывают и дополнительные возможности.

Пространство имен в рамках кластера


Пространство имён (namespace) — возможность логически разбивать ресурсы в Kubernetes (например, на stage, production и т.п.). Есть Ingress-контроллеры, которые надо ставить отдельно в каждый namespace (и тогда он может направлять трафик только в pod'ы этого пространства). А есть такие (и их явное большинство), что работают глобально на весь кластер — в них трафик направляется в любой pod кластера, независимо от пространства имён.

Пробы для upstream'ов


Каким образом обеспечивается направление трафика в здоровые экземпляры приложения, сервисов? Есть варианты с активными и пассивными проверками, повторными попытками (retries), circuit breakers (подробнее о них см., например, в статье про Istio), собственными реализациями проверок состояния (custom health checks) и т.п. Весьма важный параметр, если у вас высокие требования к доступности и своевременному выводу из балансировки отказавших сервисов.

Алгоритмы балансировки


Тут множество вариантов: от традиционных round-robin до экзотических вроде rdp-cookie, а также отдельные возможности вроде sticky sessions.

Аутентификация


Какие схемы авторизации поддерживает контроллер? Basic, digest, oauth, external-auth — думаю, что эти опции должны быть знакомы. Это важный критерий, если используется много контуров для разработчиков (и/или просто закрытых), доступ к которым осуществляется через Ingress.

Распределение трафика


Поддерживает ли контроллер такие часто применяемые механизмы для распределения трафика, как канареечные выкаты (canary), A/B-тестирование, зеркалирование трафика (mirroring/shadowing)? Это по-настоящему больная тема для приложений, которые требуют аккуратного и точного управления трафика для продуктивного тестирования, отладки продуктовых ошибок не на бою (или с минимальными потерями), анализа трафика и т.п.

Платная подписка


Есть ли платный вариант у контроллера, с расширенными функциональными возможностями и/или технической поддержкой?

Графический интерфейс (Web UI)


Имеется ли какой-либо графический интерфейс для управления конфигурацией контроллера? В основном для «сподручности» и/или для тех, кому требуется вносить какие-то изменения в конфигурацию Ingress’а, но работать с «сырыми» шаблонами неудобно. Может пригодится в случае, если разработчики хотят налету проводить какие-либо эксперименты с трафиком.

JWT-валидация


Наличие встроенной проверки JSON web-токенов для авторизации и валидации пользователя конечному приложению.

Возможности для кастомизации конфига


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

Базовые механизмы защиты от DDOS


Простые алгоритмы rate limit или же более сложные варианты отсеивания трафика на основе адресов, белых списков, стран и т.д.

Трассировка запросов


Возможности наблюдения, отслеживания и отладки запросов от Ingress'ов к конкретным сервисам/pod'ам, а в идеале — и между сервисами/pod'ами тоже.

WAF


Поддержка прикладного firewall'а.

Контроллеры Ingress


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

Ingress от Kubernetes


Сайт: github.com/kubernetes/ingress-nginx
Лицензия: Apache 2.0

Это официальный контроллер для Kubernetes, который разрабатывается сообществом. Очевидно из названия, он основан на nginx и дополнен различным набором Lua-плагинов, применяемых для реализации дополнительных возможностей. Благодаря популярности самого nginx’а и минимальных модификаций над ним при использовании в качестве контроллера, этот вариант может быть самым простым и понятным в конфигурации среднестатистическим инженером (с опытом в web).

Ingress от NGINX Inc


Сайт: github.com/nginxinc/kubernetes-ingress
Лицензия: Apache 2.0

Официальный продукт разработчиков nginx. Имеет платную версию, основанную на NGINX Plus. Основная идея — высокий уровень стабильности, постоянная обратная совместимость, отсутствие каких-либо посторонних модулей и заявленная повышенная скорость (в сравнении с официальным контроллером), достигнутая благодаря отказу от Lua.

Бесплатная версия существенно урезана, в том числе даже при сравнении с официальным контроллером (из-за отсутствия всё тех же Lua-модулей). Платная при этом имеет достаточно широкий дополнительный функционал: метрики в реальном времени, JWT-валидация, активные health check’и и другое. Важное преимущество перед NGINX Ingress — полноценная поддержка TCP/UDP-трафика (и в community-версии тоже!). Минус — отсутствие фич по распределению трафика, что, впрочем, «имеет максимальный приоритет для разработчиков», но требует времени на реализацию.

Kong Ingress


Сайт: github.com/Kong/kubernetes-ingress-controller
Лицензия: Apache 2.0

Продукт, разрабатываемый компанией Kong Inc. в двух вариантах: коммерческий и бесплатный. Основан на nginx, возможности которого расширены большим количеством модулей на Lua.

Изначально был ориентирован на обработку и маршрутизацию запросов API, т.е. как API Gateway, однако на данный момент стал полноценным Ingress-контроллером. Основные преимущества: множество дополнительных модулей (в том числе и от сторонних разработчиков), которые легко ставить и конфигурировать и с помощью которых реализуется широкий спектр дополнительных возможностей. Впрочем, встроенные функции уже предлагают многие возможности. Конфигурация работы производится с помощью CRD-ресурсов.

Важная особенность продукта — работа в рамках одного контура (вместо cross-namespaced) является спорной темой: кому-то покажется недостатком (приходится плодить сущности для каждого контура), а для кого-то — фича (больший уровень изоляции, т.к. если сломан один контроллер, то проблема ограничена одним только контуром).

Traefik


Сайт: github.com/containous/traefik
Лицензия: MIT

Прокси, который изначально создавался для работы с маршрутизацией запросов для микросервисов и их динамической среды. Отсюда и многие полезные возможности: обновление конфигурации совсем без перезагрузок, поддержка большого количества методов балансировки, веб-интерфейс, проброс метрик, поддержка различных протоколов, REST API, канареечные релизы и многое другое. Приятной особенностью также является поддержка сертификатов Let's Encrypt из коробки. Недостаток — для организации высокой доступности (HA) у контроллера потребуется устанавливать и подключать собственное KV-хранилище.

HAProxy


Сайт: github.com/jcmoraisjr/haproxy-ingress
Лицензия: Apache 2.0

HAProxy давно известен в качестве прокси и балансировщика трафика. В рамках кластера Kubernetes с ним предлагается «мягкое» обновление конфигурации (без потери трафика), service discovery на основе DNS, динамическая конфигурация с помощью API. Привлекательным может стать полная кастомизация шаблона конфигов с помощью замены CM'а, а также возможности использования в нём функций библиотеки Sprig. В целом же основной акцент решения делается на высокую скорость работы, его оптимизированность и эффективность в потребляемых ресурсах. Преимущество контроллера — поддержка рекордного числа различных способов балансировки.

Voyager


Сайт: github.com/appscode/voyager
Лицензия: Apache 2.0

Основанный на HAproxy контроллер, который позиционируется как универсальное решение, поддерживающее широкие возможности на большом количестве провайдеров. Предлагается возможность для балансировки трафика на L7 и L4, а балансировку TCP L4-трафика в целом можно назвать одной из ключевых фич решения.

Contour


Сайт: github.com/heptio/contour
Лицензия: Apache 2.0

В основу этого решения не только лёг Envoy: оно разработано совместно с авторами этого популярного прокси. Важная особенность — возможность разделения управления ресурсами Ingress с помощью CRD-ресурсов IngressRoute. Для организаций со множеством команд разработки, использующих один кластер, это помогает максимально обезопасить работу с трафиком в соседних контурах и защитить их от ошибок при изменении ресурсов Ingress.

Также предлагается расширенный набор методов балансировки (присутствует зеркалирование запросов, автоповторы, ограничение по rate'у запросов и многое другое), детальный мониторинг потока трафика и сбоев. Возможно, для кого-то будет существенным недостатком отсутствие поддержки sticky sessions (хотя работы уже ведутся).

Istio Ingress


Сайт: istio.io/docs/tasks/traffic-management/ingress
Лицензия: Apache 2.0

Комплексное service mesh-решение, которое является не только Ingress-контроллером, управляющим поступающим трафиком извне, но и контролирует весь трафик в рамках кластера. «Под капотом», в качестве sidecar-прокси для каждого сервиса, используется Envoy. В сущности это большой комбайн, который «может всё», а основная его идея — максимальная управляемость, расширяемость, безопасность и прозрачность. С его помощью вы можете в тонкостях настраивать маршрутизацию трафика, авторизацию доступа между сервисами, балансировку, мониторинг, канареечные релизы и многое другое. Подробнее об Istio читайте в серии статей «Назад к микросервисам с Istio».

Ambassador


Сайт: github.com/datawire/ambassador
Лицензия: Apache 2.0

Ещё одно решение на основе Envoy. Имеет бесплатную и коммерческую версии. Позиционируется как «полностью родное для Kubernetes», что приносит соответствующие преимущества (тесная интеграция с методами и сущностями кластера K8s).

Сравнительная таблица


Итак, кульминация статьи — эта огромная таблица:



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

Подведём итоги


Цель статьи — предоставить более полное понимание (впрочем, совершенно не исчерпывающее!) того, какой выбор сделать в вашем конкретном случае. Как обычно бывает, каждый контроллер имеет свои достоинства и недостатки…

Классический Ingress от Kubernetes хорош своей доступностью и проверенностью, достаточно богатыми возможностями — в общем случае его должно «хватить за глаза». Однако, если есть повышенные требования к стабильности, уровню фич и разработки, стоит обратить внимание на Ingress с NGINX Plus и платной подпиской. Kong имеет богатейший набор плагинов (и, соответственно, обеспечиваемых ими возможностей), причём в платной версии их даже больше. У него широкие возможности по работе в качестве API Gateway, динамического конфигурирования на основе CRD-ресурсов, а также базовых сервисов Kubernetes.

При повышенных требованиях к балансировке и методам авторизации присмотритесь к Traefik и HAProxy. Это Open Source-проекты, проверенные годами, очень стабильные и активно развивающиеся. Contour появился уже пару лет как на свет, но выглядит всё еще слишком молодо и имеет лишь базовые возможности, добавленные поверх Envoy. Если есть требования по наличию/встраиванию WAF перед приложением, стоит обратить внимание на тот же Ingress от Kubernetes или HAProxy.

А самые богатые по функциям — это продукты, построенные на базе Envoy, в особенности Istio. Он представляется комплексным решением, который «может всё», что, впрочем, означает и значительно более высокий порог вхождения по конфигурации/запуску/администрированию, чем у других решений.

Нами в качестве стандартного контроллера был выбран и до сих пор используется Ingress от Kubernetes, который покрывает 80—90% потребностей. Он вполне надёжен, легко конфигурируется, расширяется. В общем случае, при отсутствии специфичных требований, он должен подойти большинству кластеров/приложений. Из таких же универсальных и относительно простых продуктов можно порекомендовать Traefik и HAProxy.

P.S.


Читайте также в нашем блоге:

Комментарии (16)


  1. badrazor
    09.04.2019 18:28

    Неплохо было бы добавить skipper


    1. andreios Автор
      09.04.2019 19:12

      Хмм, интересно, спасибо — посмотрим на этот контроллер тоже.


  1. apapacy
    09.04.2019 20:21

    В рамках кластера Kubernetes с ним предлагается «мягкое» обновление конфигурации (без потери трафика), service discovery на основе DNS, динамическая конфигурация с помощью API


    Мягкое обновление HAProxy, которое стало доступно сравнительно недавно, работет весьма специфично. Рядом с работающим HAProxy поднимается еще один экземпляр на который переключается трафик. То есть всегда нужно иметь практически двойной запас ресурсов чтобы было места где стартануть второй экземпляр HAProxy. Все это связано с тем что HAProxy не умеет перечитывать конфиги. Я бы упомянул это как недостаток.


    1. andreios Автор
      09.04.2019 20:54

      Спасибо за информацию, я о таком нюансе не знал!
      Посмотрим, проверим по возможности.


    1. nesoneg
      11.04.2019 19:10

      Вы не правы. По умолчанию в haproxy-ingress есть релоад при обновлении конфига и даже можно включить добавление-удаление сервисов вообще без релоада, через сокет. Вот тут подробнее github.com/jcmoraisjr/haproxy-ingress#dynamic-scaling


      1. apapacy
        12.04.2019 16:00

        Весь вопрос как haproxy релизует перегрузку конфигов «без релоада». Это описано здесь.
        github.com/neo4j/docker-library-docs/tree/master/haproxy#reloading-config
        Подробности в этом документе п.4
        www.haproxy.org/download/1.7/doc/management.txt

        В момент когда отправляется сигнал на перегрузку конфигов haproxy там некоторое аремя работают два инстанса.
        Это лучше чем hard restart т.к. не теряются коннекты которые в работе.
        Но хуже т.к. может привести к повышенному расходованию ресурсов системы.

        И т.к. процесс реально второй это не будет работать если запускать haproxy в докере (по принципу один контейнер-один процесс)

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


  1. maslakov
    09.04.2019 22:16

    И еще один новенький в этом зоопарке («can function as a feature-rich ingress controller») — Gloo


  1. ferocactus
    10.04.2019 02:48

    Удивительно, что многие контроллеры, судя по таблице, не имеют трассировки запросов. Как же их при этом использовать в настоящем бою, где за каждый запрос нужно ручаться головой? Как отвечать на вопросы руководства: почему часть запросов тормозит, часть отваливается по таймауту, а часть возвращает ошибку?


    1. ProFfeSsoRr
      10.04.2019 10:15

      И какое решение вы выбрали, чтобы с трассировкой?


      1. ferocactus
        10.04.2019 14:28

        Не выбрали, пока остались на Openshift, в котром HAProxy.


    1. andreios Автор
      10.04.2019 11:27

      Обычно это решается частично со стороны приложения, с помощью apm, типа NewRelic.


      1. ferocactus
        10.04.2019 14:31

        Но что если в приложении всё хорошо (и с его логами тоже), а вот с сервисом в целом всё равно какие-то проблемы?


        1. andreios Автор
          10.04.2019 22:26

          Ниже вот ответили, ставить istio с трейсером. Но по опыту, в 90% случаев, проблема в сети между нодами. В случае с тем же flannel, ломаться обычно просто нечему. Не говорю конечно о крайних случаях, когда что-то сложное — огромные нагрузки, огромные кластера, тысячи сервисов и так далее, но если это ваш кейс, совершенно непонятно как вы ещё живёте без чего-то вроде istio :)


    1. MMik
      10.04.2019 20:24

      Istio в комбинации с:

      • Jaeger
      • Zipkin/OpenZipkin
      • LightStep [x]PM
      • kiali


  1. varyumin
    10.04.2019 11:25

    А где обзор какой тип балансировки они поддерживают L7 или L4. Так же сравнение кто умеет HTTP2, GRPC проксировать кто нет.


    1. andreios Автор
      10.04.2019 13:02

      Поддерживаемые протоколы есть в таблице, также обычно все кто поддерживает tcp в полной мере, имеют полноценную l4 балансировку.
      Про http2 это упущение (там действительно есть нюансы, например не все ингрессы умеют проксировать http2, а только терминировать), которые к сожалению, скорее всего будут еще обнаруживаться, уж слишком большой объем обзора :(.