openshift ingress что такое
Обзор и сравнение контроллеров Ingress для Kubernetes
При запуске кластера Kubernetes для конкретного приложения следует понимать, какие требования представляет к этому ресурсу само приложение, бизнес и разработчики. При наличии этой информации можно приступать к принятию архитектурного решения и, в частности, к выбору конкретного Ingress-контроллера, коих на сегодняшний день уже большое количество. Чтобы составить базовое представление об имеющихся вариантах без необходимости изучать множество статей/документации и т.п., мы и подготовили этот обзор, включив в него основные (production ready) Ingress-контроллеры.
Надеемся, что он поможет коллегам в выборе архитектурного решения — по крайней мере, станет отправной точкой для получения более подробной информации и практических экспериментов. Предварительно мы изучили другие подобные материалы в сети и, как ни странно, не обнаружили ни одного более-менее полного, а главное — структурированного — обзора. Итак, заполним же этот пробел!
Критерии
Чтобы в принципе проводить сравнение и получить сколько-нибудь полезный результат, надо понимать не просто предметную область, но и иметь конкретный список критериев, которые и будут задавать вектор исследования. Не претендуя на анализ всех возможных случаев применения Ingress/Kubernetes, мы постарались выделить наиболее общие требования к контроллерам — будьте готовы, что всю свою специфику и частности в любом случае придётся изучать отдельно.
Но начну с характеристик, которые стали настолько привычными, что реализованы во всех решениях и не рассматриваются:
Поддерживаемые протоколы
Один из основополагающих критериев для выбора. Ваше ПО может работать не по стандартному 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’ами тоже.
Контроллеры Ingress
Список контроллеров был сформирован на основе официальной документации Kubernetes и этой таблицы. Некоторые из них мы исключили из обзора ввиду специфичности или малой распространенности (ранней стадии развития). Оставшиеся же рассмотрены ниже. Начнём с общего описания решений и продолжим сводной таблицей.
Ingress от Kubernetes
Это официальный контроллер для Kubernetes, который разрабатывается сообществом. Очевидно из названия, он основан на nginx и дополнен различным набором Lua-плагинов, применяемых для реализации дополнительных возможностей. Благодаря популярности самого nginx’а и минимальных модификаций над ним при использовании в качестве контроллера, этот вариант может быть самым простым и понятным в конфигурации среднестатистическим инженером (с опытом в web).
Ingress от NGINX Inc
Официальный продукт разработчиков nginx. Имеет платную версию, основанную на NGINX Plus. Основная идея — высокий уровень стабильности, постоянная обратная совместимость, отсутствие каких-либо посторонних модулей и заявленная повышенная скорость (в сравнении с официальным контроллером), достигнутая благодаря отказу от Lua.
Бесплатная версия существенно урезана, в том числе даже при сравнении с официальным контроллером (из-за отсутствия всё тех же Lua-модулей). Платная при этом имеет достаточно широкий дополнительный функционал: метрики в реальном времени, JWT-валидация, активные health check’и и другое. Важное преимущество перед NGINX Ingress — полноценная поддержка TCP/UDP-трафика (и в community-версии тоже!). Минус — отсутствие фич по распределению трафика, что, впрочем, «имеет максимальный приоритет для разработчиков», но требует времени на реализацию.
Kong Ingress
Продукт, разрабатываемый компанией Kong Inc. в двух вариантах: коммерческий и бесплатный. Основан на nginx, возможности которого расширены большим количеством модулей на Lua.
Изначально был ориентирован на обработку и маршрутизацию запросов API, т.е. как API Gateway, однако на данный момент стал полноценным Ingress-контроллером. Основные преимущества: множество дополнительных модулей (в том числе и от сторонних разработчиков), которые легко ставить и конфигурировать и с помощью которых реализуется широкий спектр дополнительных возможностей. Впрочем, встроенные функции уже предлагают многие возможности. Конфигурация работы производится с помощью CRD-ресурсов.
Важная особенность продукта — работа в рамках одного контура (вместо cross-namespaced) является спорной темой: кому-то покажется недостатком (приходится плодить сущности для каждого контура), а для кого-то — фича (больший уровень изоляции, т.к. если сломан один контроллер, то проблема ограничена одним только контуром).
Traefik
Прокси, который изначально создавался для работы с маршрутизацией запросов для микросервисов и их динамической среды. Отсюда и многие полезные возможности: обновление конфигурации совсем без перезагрузок, поддержка большого количества методов балансировки, веб-интерфейс, проброс метрик, поддержка различных протоколов, REST API, канареечные релизы и многое другое. Приятной особенностью также является поддержка сертификатов Let’s Encrypt из коробки. Недостаток — для организации высокой доступности (HA) у контроллера потребуется устанавливать и подключать собственное KV-хранилище.
HAProxy
HAProxy давно известен в качестве прокси и балансировщика трафика. В рамках кластера Kubernetes с ним предлагается «мягкое» обновление конфигурации (без потери трафика), service discovery на основе DNS, динамическая конфигурация с помощью API. Привлекательным может стать полная кастомизация шаблона конфигов с помощью замены CM’а, а также возможности использования в нём функций библиотеки Sprig. В целом же основной акцент решения делается на высокую скорость работы, его оптимизированность и эффективность в потребляемых ресурсах. Преимущество контроллера — поддержка рекордного числа различных способов балансировки.
Voyager
Основанный на HAproxy контроллер, который позиционируется как универсальное решение, поддерживающее широкие возможности на большом количестве провайдеров. Предлагается возможность для балансировки трафика на L7 и L4, а балансировку TCP L4-трафика в целом можно назвать одной из ключевых фич решения.
Contour
В основу этого решения не только лёг Envoy: оно разработано совместно с авторами этого популярного прокси. Важная особенность — возможность разделения управления ресурсами Ingress с помощью CRD-ресурсов IngressRoute. Для организаций со множеством команд разработки, использующих один кластер, это помогает максимально обезопасить работу с трафиком в соседних контурах и защитить их от ошибок при изменении ресурсов Ingress.
Также предлагается расширенный набор методов балансировки (присутствует зеркалирование запросов, автоповторы, ограничение по rate’у запросов и многое другое), детальный мониторинг потока трафика и сбоев. Возможно, для кого-то будет существенным недостатком отсутствие поддержки sticky sessions (хотя работы уже ведутся).
Istio Ingress
Комплексное service mesh-решение, которое является не только Ingress-контроллером, управляющим поступающим трафиком извне, но и контролирует весь трафик в рамках кластера. «Под капотом», в качестве sidecar-прокси для каждого сервиса, используется Envoy. В сущности это большой комбайн, который «может всё», а основная его идея — максимальная управляемость, расширяемость, безопасность и прозрачность. С его помощью вы можете в тонкостях настраивать маршрутизацию трафика, авторизацию доступа между сервисами, балансировку, мониторинг, канареечные релизы и многое другое. Подробнее об Istio читайте в серии статей «Назад к микросервисам с Istio».
Ambassador
Ещё одно решение на основе 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.
☸️ Учебное пособие по Ingress для начинающих в Kubernetes
Kubernetes Ingress – это ресурс для добавления правил маршрутизации трафика из внешних источников в службы в кластере kubernetes.
Кроме того, мы рассмотрим расширенную ingress маршрутизацию с использованием ingress шлюза службы ISTIO.
Как правило, пользовательская развертка Nginx или HAproxy kubernetes будет представлено как служба для перенаправления внешнего трафика во внутренние службы кластера, где правила маршрутизации будут закрепляться в поде и добавляться в виде configmap.
Ingress Kubenetes действует аналогичным образом, за исключением того, что правила маршрутизации будут поддерживаться как объект Ingress Kubernetes.
Он обладает огромным преимуществом конфигурации правил динамической маршрутизации без повторного развертывания подов прокси.
Учебное пособие по Kubernetes Ingress
Чтобы начать, вам нужно понять две ключевые вещи.
Давайте рассмотрим каждый из этих понятий.
Kubernetes Ingress:
Kubernetes Ingress – это собственный ресурс kubernetes, с которым вы можете создавать правила маршрутизации трафика от внешнего источника к конечным точкам различных служб, расположенных внутри кластера.
Для маршрутизации правил, указанных в объекте Ingress, требуется ingress controller.
Объект Ingress выглядит следующим образом.
Приведенная выше настройка означает, что все вызовы test.apps.example.com должны попадать в службу с именем hello-serviceresiding в пространстве имен dev.
Ключевые вещи, которые должны помочь понять объект ingress.
Kubernetes Ingress Controller
В этой серии руководств мы рассмотрим все типы ingress решений, поддерживаемых Kubernetes.
Как настроить Ingress на Kubernetes с помощью Nginx Controller
Есть два nginx ingress controller
Мы будем использовать контроллер Nginx от комьюнити kubernetes.
Ingress controller требует определенное пространство имен, учетную запись службы, cluster role bindings, конфигурацию и т. д.
Вы можете создать все упомянутые объекты kubernetes, используя файл yaml из официального Ingress репозитория.
Давайте развернем ingress controller, используя файл mandatory.yaml из официального репозитория.
Он содержит сводный список объектов kubernetes, необходимых для контроллера Nginx.
Настройка службы LoadBalancer для Ingress контроллера
Следующим шагом является создание службы типа Loadbalancer для предоставления развертывания контроллера nginx вне кластера.
Шаг 1: Создайте каталог проекта локально и переключитесь на этот каталог.
Шаг 2: Создайте файл с именем nginx-ingress.yaml
Шаг 3: Скопируйте следующее содержимое в файл.
Заметка:
Аннотации под Lables очень важны для интеграции с nginx controller deployment.
Сопоставьте доменное имя с IP-адресом Loadbalancer
Чтобы наши настройки Ingress работали, нам нужно сопоставить доменное имя с IP-адресом балансировщика нагрузки.
Вы можете сделать это двумя способами.
Вы можете сопоставить один домен напрямую как A запись с IP-адресом балансировщика нагрузки.
Используя этот вариант, вы можете иметь только один домен для Ingress контроллера и маршрутизацию трафика по нескольким путям.
Вы можете использовать базовую маршрутизацию, используя эту модель.
Если вы сопоставите подстановочный DNS с балансировщиком нагрузки, у вас могут быть динамические конечные точки DNS через Ingress.
Таким образом, вы можете иметь несколько динамических поддоменов через один Ingress Controller, и каждый DNS может иметь собственную маршрутизацию на основе базовой маршрутизации.
Настройка приложения A
В целях тестирования мы развернем демонстрационное приложение и добавим в него сервис ClusterIp.
Шаг 2: Создайте файл с именем hello-app.yaml
Шаг 3: Скопируйте следующее содержимое и сохраните файл.
Шаг 4. Создайте развертывание с помощью kubectl
Проверьте состояние развертывания.
Шаг 5: Создайте файл с именем hello-app-service.yaml
Шаг 6: Скопируйте следующее содержимое и сохраните файл.
Шаг 7: Создайте сервис, используя kubectl.
Проверьте статус сервиса
Создание объекта Ingress Kubernetes
Теперь давайте создадим Ingress объект для доступа к нашему приложению через DNS.
Объект Ingress – это не что иное, как настройка правил маршрутизации.
Шаг 1: Создайте файл с именем ingress.yaml
Шаг 2: Скопируйте следующее содержимое и сохраните файл.
Все об OpenShift Egress. Часть 1
Про управление входящим в OpenShift трафиком (оно же Ingress) написано много в документации и различных статьях по его настройке. Но, кроме контроля входящего в кластер трафика, в работе зачастую требуется контроль исходящего трафика (Egress). А на эту тему информации, систематизирующей подходы и технические решения, значительно меньше. Постараемся заполнить эту нишу серией постов.
Итак, в каких ситуациях нужен контроль исходящего из кластера трафика?
Можно выделить три типовых сценария использования.
Доступ к внешнему ресурсу контролируется извне кластера
Например, есть внешняя база данных, доступ к которой контролируется межсетевым экраном, и требуется предоставить доступ к этой БД только для определенных POD кластера. По умолчанию POD при взаимодействии с внешними ресурсами используют IP-адрес узла кластера, поэтому задача не решается «в лоб».
Можно выделить несколько узлов исключительно под эти POD, но это зачастую не выход. Узлов понадобится несколько (нам же нужна отказоустойчивость), а требуемых POD может быть совсем немного. Узлы могут получать IP адреса по DHCP, что также затрудняет решение проблемы. Ну и, наконец, таких внешних «зон безопасности» может быть много, и выделять под каждую по два узла совсем не хочется.
Для определенных POD в кластере требуется доступ в изолированные сегменты сети
Типичным случаем здесь является организация доступа определенных POD к сегментам сети, расположенным в другом VLAN (которого нет на узлах кластера) или вообще на другом оборудовании (например, по требованиям PCI DSS).
Создавать по кластеру в каждом таком сегменте — дорого и к тому же тяжело поддерживать. А заводить требуемый VLAN на узлы кластера не будут: его для этого и сделали, чтобы доступ получило только то ПО и оборудование, которое участвует в этом критичном с точки зрения ИБ бизнес-процессе.
К пропускной способности или задержкам сети определенных POD предъявляются особые требования
Например, приложение требует для нормальной работы выделенного соединения 10G Ethernet и полностью его утилизирует. В этом случае также непонятно, как обеспечить эти требования в условиях одновременной работы десятков или сотен POD на одном рабочем узле. Не выделять же полностью узел кластера под один подобный POD.
На все вышеописанные сценарии есть решения, которые связаны с управлением исходящего из кластера OpenShift трафика. Попробуем разобраться, в каком случае какое решение по Egress применять, и как оно работает.
Egress IP и Egress Router
В OpenShift, начиная с версии 3.7, появилась возможность выделить фиксированные адреса на namespace, и именно с этих адресов все POD в этом namespace будут обращаться к внешним ресурсам кластера. Реализовано это средствами OpenShift SDN.
Всё работает, но непонятно, как именно:) Например, контейнер, как мы видели ранее, работает на узле shift-worker1. На этот узел был назначен адрес Egress IP = 192.168.111.226. Так почему же мы выходим из кластера с Egress IP = 192.168.111.225?
Ответ на этот вопрос дает статья How to Enable Static Egress IP in OCP. Давайте с ее помощью выясним, что же происходит «под капотом» OpenShift при использовании Egress IP.
Принадлежность к проекту определяется его virtual network ID (VNID), в нашем случае 0xe28820 — это шестнадцатеричное значение VNID для проекта egress.
OpenShift SDN заворачивает все подобные пакеты в tunnel interface vxlan0 с указанием, что доставить пакет надо на хост shift-worker0:
Таким образом, OpenShift SDN выбирает «основной» Egress IP-адрес, и все пакеты с проекта помечает меткой и отправляет на хост, содержащий «основной» Egress IP. На этом хосте iptables выполняет Source NAT, и задача решена. Если хост с «основным» Egress IP становится недоступен, то пакеты перенаправляются на следующий в списке Egress IP-адресов хост (в нашем случае это будет shift-worker1).
Если мы выключим хост shift-worker0, то наш тестовый POD «наружу» будет выходить уже с адресом 192.168.111.226, который мы присвоили узлу shift-worker1:
192.168.111.226 — — [30/Oct/2020:15:28:38 +0300] «GET /test HTTP/1.1» 200 8 «-» «curl/7.29.0»
Именно поэтому нам нужно как минимум два IP-адреса при использовании Egress IP. В случае отказа одного узла кластера POD мы сможем получить доступ к внешним ресурсам с заданных IP.
Описанная здесь схема организации Egress хорошо подходит для первого сценария использования, когда доступ к внешним по отношению к кластеру ресурсам определяется межсетевым экраном или самим ресурсом. Применительно к нашему стенду все POD в проекте «egress» (POD2 – POD4) при обращении «наружу» получат заранее определенные адреса (192.168.111.225 или 192.168.111.225) вне зависимости от того, на каком узле кластера они находятся. Остальные POD кластера при обращении к внешним ресурсам получат IP-адрес узла кластера и будут отвергнуты либо МЭ, либо приложением.
Если нужно сделать фиксированные Egress-адреса для нескольких проектов, то использовать Egress IP неудобно. В этом случае узлам кластера можно указать, какую подсеть использовать, а проекту — какой IP адрес из этой подсети взять.
После этого указываем проекту, какой IP-адрес использовать для исходящего трафика:
Разумеется, egressCIDR должен быть в той же подсети, что и основной IP-адрес узла. И выделять два адреса на проект в данном случае не требуется — при отказе узла используемый адрес «переедет» на другой доступный узел с установленным egressCIDR (при условии, что этот адрес в него входит).
Egress Router
Рассказывая про Egress в OpenShift, важно также упомянуть про Egress router. Он применялся еще до того, как появилась возможность контролировать исходящий трафик средствами Openshift SDN. В качестве решения использовался специальный POD, у которого один адрес находился в кластерной сети OpenShift, а другой получал внешний IP-адрес и доступ к физическому интерфейсу узла через macvlan CNI plugin.
Этот POD выступал в роли маршрутизатора между внутренней сетью кластера и внешними сетями за пределами OpenShift. Пример управления исходящим трафиком через Egress router можно посмотреть на странице Red Hat OpenShift Blog. Но так как конфигурация на базе OpenShfit SDN проще в настройке и поддержке, описание решения на базе Egress router в OpenShift версии 4 удалено из документации.
Vanilla Kubernetes
А что с управлением Egress трафиком в «ванильном» Kubernetes? К сожалению, единого решения здесь нет. Все зависит от возможностей SDN, который используется в работе кластера. Например, Calico позволяет отключить Source NAT для определенного пула IP-адресов. Но в этом случае вопросы маршрутизации трафика между POD кластера и внешним миром придется решать самостоятельно.
Резюме
В OpenShift можно штатными средствами SDN организовать контроль IP-адресации исходящего трафика, чтобы обеспечить требования внешних систем контроля доступа. При этом необходимо понимать возникающие в работе кластера технические нюансы:
Подмена IP-адресов здесь никак не поможет. Решением является использование CNI «meta-plugin» Multus. Multus CNI plugin стал доступен в качестве поддерживаемого компонента в OpenShift 4.1 и фактически позволяет организовать подключение POD к нескольким сетям одновременно.
Настройке и использованию Multus CNI Plugin в OpenShift посвятим вторую часть этого поста.
Список литературы
Автор: Сергей Артемов, руководитель отдела DevOps-решений «Инфосистемы Джет»