company_banner

Обзор и сравнение контроллеров Ingress для Kubernetes



    При запуске кластера 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.


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

    Флант
    252,00
    Специалисты по DevOps и Kubernetes
    Поделиться публикацией

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

      0
      Неплохо было бы добавить skipper
        0
        Хмм, интересно, спасибо — посмотрим на этот контроллер тоже.
        +1
        В рамках кластера Kubernetes с ним предлагается «мягкое» обновление конфигурации (без потери трафика), service discovery на основе DNS, динамическая конфигурация с помощью API


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

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

            0
            Вы не правы. По умолчанию в haproxy-ingress есть релоад при обновлении конфига и даже можно включить добавление-удаление сервисов вообще без релоада, через сокет. Вот тут подробнее github.com/jcmoraisjr/haproxy-ingress#dynamic-scaling
              0
              Весь вопрос как 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 в докере (по принципу один контейнер-один процесс)

              Впрочем на практике при больших загрузках я это не пробовал у меня их просто нет. Возможно все не так уж и страшно. Просто не лишним было бы представлять как это работает.
            0
            И еще один новенький в этом зоопарке («can function as a feature-rich ingress controller») — Gloo
              0

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

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

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

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

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

                      0

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

                    0
                    Istio в комбинации с:
                    • Jaeger
                    • Zipkin/OpenZipkin
                    • LightStep [x]PM
                    • kiali
                    +1
                    А где обзор какой тип балансировки они поддерживают L7 или L4. Так же сравнение кто умеет HTTP2, GRPC проксировать кто нет.
                      +1
                      Поддерживаемые протоколы есть в таблице, также обычно все кто поддерживает tcp в полной мере, имеют полноценную l4 балансировку.
                      Про http2 это упущение (там действительно есть нюансы, например не все ингрессы умеют проксировать http2, а только терминировать), которые к сожалению, скорее всего будут еще обнаруживаться, уж слишком большой объем обзора :(.

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

                    Самое читаемое