Привет, Хабр!
Каждый человек рано или поздно сталкивается с выбором, какой ingress‑контроллер использовать для маршрутизации трафика. Помнится, раньше многие думали, что достаточно взять Nginx и не париться. Но реальность, как это обычно бывает, сложнее. Есть по меньшей мере три мощных игрока: NGINX, Traefik и HAProxy. И у каждого свои фичи и проблемы.
Зачем вообще нужен ingress-контроллер?
Если вы уже используете Kubernetes, вероятно знаете, что опубликовать приложение наружу можно разными способами. Можно, например, прокинуть NodePort или создать LoadBalancer Service. Однако наиболее адекватный вариант — использовать Ingress.
Ingress‑объект описывает правила маршрутизации (какие внешние URL или хосты направлять на какие сервисы внутри кластера), а Ingress‑контроллер сам по себе специальный компонент, который эти правила читает и исполняет.
В Kubernetes есть несколько реализаций ingress‑контроллеров. Каждая реализована на базе проверенных решений: Nginx, Traefik, HAProxy, Envoy и так далее Мы сегодня сфокусируемся на трёх китах: Nginx Ingress Controller, Traefik и HAProxy Ingress.
Nginx Ingress Controller
Nginx такой уже ветеран в мире веб‑серверов и прокси. Запущен ещё в 2004 году как высокопроизводительный веб‑сервер. Nginx нынче умеет всё понемногу, и статику раздавать, и как обратный прокси работать, и балансировать нагрузку, и кешировать контент. Неудивительно, что для Kubernetes был создан ingress‑контроллер на базе Nginx.
Что он собой представляет?
Nginx Ingress Controller — это под, внутри которого крутится instance Nginx. Этот контроллер следит за ресурсами типа Ingress в Kubernetes API и динамически генерирует конфигурацию Nginx на их основе. ingress‑nginx стал фактически де‑факто стандартом для ingress и поставляется под все популярные Managed Kubernetes.
Nginx способен обрабатывать тысячи и даже миллионы соединений на скромном железе. Кроме того, у Nginx самая богатая экосистема модулей и настроек. Можно реализовать практически любую логику маршрутизации: гео‑балансировку, переписывание URL, sticky‑сессии, HTTP/2 и gRPC туннелирование, всё это у Nginx есть.
Обратная сторона медали — сложность. Настройка Nginx — дело не то что бы легкое. У него свой собственный синтаксис конфигов, к которому нужно приноровиться Ingress‑контроллер, конечно, предлагает Kubernetes‑стиль конфигурации через Ingress‑манифесты и аннотации. Но как только требуется что‑то нестандартное, может быть непросто. Плюс, Nginx не такой динамичный, при изменении конфигурации контроллер генерирует новый конфиг файл и перегружает процесс Nginx. Нет автоматического auto‑discovery сервисов, только то, что явно описано в Ingress. Да и в целом, богатство возможностей Nginx иногда избыточно для простых задач.
Небольшой пример Ingress‑правила под Nginx‑контроллер. Допустим, есть сервис my-app на 80 порту, и хочется отдавать его по внешнему пути /app без суффикса, а также включить сжатие для экономии трафика:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: "/" # переписываем все запросы /app/** на /
nginx.ingress.kubernetes.io/enable-access-log: "true" # включаем access log для примера
nginx.ingress.kubernetes.io/proxy-body-size: 10m # пример лимита размера запроса
spec:
rules:
- host: example.com
http:
paths:
- path: /app
pathType: Prefix
backend:
service:
name: my-app
port:
number: 80
В аннотациях задали переписывание пути, включили access‑log и ограничили размер тела запроса 10 МБ. Ingress‑контроллер Nginx эти аннотации распарсит и добавит нужные директивы в конфиг Nginx. Например, rewrite-target "/" превратится в правило rewrite ^/app/(.*)$ /$1 break; внутри Nginx.
Traefik
Traefik — относительно молодой игроК, сразу созданный с оглядкой на облачные и контейнерные среды. Он славится автообнаружением сервисов и минимальными требуемыми настройками для старта.
Traefik выступает скорее как роутер, который сам узнаёт о новых сервисах. Подключили вы новый сервис в кластер, Traefik узнает об этом через API Kubernetes и начнёт на него пускать трафик, без рестарта и переконфигурации. Он постоянно следит за эндпоинтами и обновляет маршруты на лету.
Traefik поддерживает Kubernetes Ingress, но у него также есть свои CRD, например, IngressRoute для HTTP, Middleware для фильтров, TraefikService и др. Эти CRD дают больше реализаций, чем стандартный Ingress. Можно сконфигурировать цепочки middlewares: аутентификацию, перезапись урлов, ретраи запросов и прочее, всё декларативно в YAML.
При желании, можно вообще не писать YAML, Traefik умеет вычитывать настройки из Docker‑лейблов, Consul, etcd, в общем, из множества источников, и потому его называют маршрутизатором без конфигов.
Traefik имеет встроенную панель мониторинга, показывающую какие маршруты и сервисы он знает. Также поддерживаются метрики и трейсинг. Ещё еще встроенная поддержка Lets Encrypt, Traefik может автоматом получать и обновлять SSL‑сертификаты, нужно лишь указать пару настроек.
За простоту приходится платить ограниченной функциональностью в некоторых местах. Многие вещи, которые в Nginx реализуются модулем или парой строк Lua, в Traefik могут быть недоступны вовсе. Например, Traefik долго не умел делать канареечный деплой (traffic splitting) без костылей, хотя сейчас уже завезли через middlewares.
Кроме того, некоторые возможности отданы в Traefik Enterprise, коммерческую версию. Кластерная синхронизация Let's Encrypt сертификатов, встроенная авторизация OAuth2, UI для мультикластера, в open‑source их нет.. Впрочем, для 90% кейсов OSS‑версии хватает с головой.
Если у вас стартап или вообще небольшой проект с микросервисами — Traefik позволит быстро раскатать ingress и не заморачиваться.
Ниже пример, как можно настроить маршрут в Traefik с помощью его CRD IngressRoute. Мы хотим направлять трафик с хоста example.com пути /api на сервис my-api в 80-й порт. Плюс предположим, что хочется прикрутить базовую авторизацию (Basic Auth) как middleware:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: my-api-route
spec:
entryPoints:
- web
routes:
- match: Host(`example.com`) && PathPrefix(`/api`)
kind: Rule
services:
- name: my-api
port: 80
middlewares:
- name: auth-basicauth # заранее определенный Middleware с Basic Auth
Дополнительно должен быть определён объект типа Middleware с именем auth-basicauth, который содержит данные для базовой аутентификации (список пользователей/паролей). В результате Traefik сам следит за сервисом my-api — если поды добавляются/удаляются, он обновит балансировку автоматически. А Basic Auth применится ко всем запросам на /api. Подобную же конфигурацию на Nginx пришлось бы делать через аннотации и создавать Secret с паролями.
HAProxy Ingress Controller
HAProxy — ещё один легендарный игрок, заслуживший репутацию самого быстрого программного балансировщика. HAProxy с 2000х известных тем, что может проксировать десятки тысяч RPS на одном ядре с минимальным потреблением ресурсов.
HAProxy Ingress Controller менее известен широкому кругу, но вполне зрелый проект. Он также читает ресурсы Ingress и Service из API и генерирует конфигурацию haproxy.cfg.
Формат конфигов у HAProxy свой, более низкоуровневый, чем у Nginx. С помощью HAProxy можно настроить нестандартные алгоритмы балансировки, настроить health‑check бекендов, играть с TTL, приоритетами серверов и пр.
Если вам нужны экзотические настройки балансировки или требуется выжать последние миллисекунды latency — HAProxy очень даже неплохое решение. Есть поддержка L4 и L7 режимов, может работать и как TCP/UDP прокси, не только HTTP. Имеет встроенные возможности по лимитам соединений, приоритетам трафика, сжатию, TLS offloading, и всё это с минимальной нагрузкой на CPU. В новых версиях HAProxy добавили поддержку HTTP/3, улучшили многопоточность на многоядерных системах. Также, разумеется, HAProxy Ingress уже умеет работу с CRD Gateway API.
Выбор
Итак, мы пробежались по основным характеристикам каждого претендента. Теперь давайте сведём всё в кучу и сравним по параметрам, а заодно попробуем дать для конкретных ситуаций.
1. Производительность и нагрузка. Если вам нужен максимум RPS и минимальный overhead — HAProxy явный лидер по сырым метрикам. Nginx тоже очень быстр, но на пике нагрузки, особенно с большим количеством коннектов, HAProxy часто обходит его. Traefik в ранних версиях чуть уступал по производительности, да и были случаи, когда под экстремальной нагрузкой он выдавал ошибки. Если нагрузка средняя и нет задачи выжать сотни тысяч RPS, то все трое справятся, и разница будет не столь важна.
2. Возможности L7 и гибкость настроек. Здесь Nginx впереди, у него самый богатый набор функций, от ограничений по IP/подсети до тонкого кеширования и сжатия, поддержка HTTP/3 (в Dev Preview) и масса модулей. HAProxy догоняет: HTTP/3 уже тоже поддерживается, алгоритмов балансировки больше всех, тонкая настройка SSL/TLS, есть встроенный WAF (в enterprise‑версии). Traefik дает наиболее распространённые возможности (маршрутизация по хосту/пути, заголовки, Middlewares типа аутентификации, rate limiting, переадресации). Но каких‑то очень специфичных штук (например, GeoIP роутинг или сложные rewrite‑правила) в Traefik может не оказаться. Зато Traefik поддерживает gRPC, WebSockets и другие современные штуки, тут он не отстаёт, просто иногда требует чуть больше танцев с бубном (например, gRPC в Traefik проксируется по HTTP/2 без проблем, а вот в старых версиях Nginx для gRPC требовался отдельный ingress‑директив).
3. Простота внедрения и поддержки. Здесь Traefik явно впереди. Его философия — минимальная конфигурация вручную, максимум автоматизации. Для старта зачастую достаточно дефолтного helm install traefik, и ingress уже работает.
Все три контроллера поддерживают вынос TLS терминатора наружу, но если так нужна прямая интеграция с аппаратными балансировщиками или облачными LB , чаще используются Nginx/HAProxy, так как Traefik обычно сам выступает как крайний приемник TLS.
Возможно, через пару лет появится новый крутой ingress, какой‑нибудь на базе Envoy, кстати, уже есть Istio Ingress Gateway на Envoy, и NGINX Gateway на основе Gateway API.
В общем, выбирайте с умом.

А дальше обычно прилетает самое неприятное: база — это не статика, а точка отказа. Если MySQL-репликация уже не спасает от ночных алертов и «а что будет при фейловере?», заходите на открытый вебинар про Percona XtraDB Cluster: соберём живой PXC с синхронной репликацией и разберём, где у него реальные ограничения, чтобы не наступить на них в проде. Записаться
Этот урок пройдет 27 января в рамках курса «Инфраструктура высоконагруженных систем». Пройдите бесплатное тестирование по курсу, чтобы оценить свои знания и навыки для поступления на курс.
Heggi
Nginx Ingress Controller поддержка прекращается в марте месяце. https://www.securitylab.ru/news/566786.php
Рекомендуется уже переходить на Gateway API, а не мучать бедный Ingress. Но переход будет не то чтобы легким, это да. Новое API мозги заставляет напрячься, чтобы реализовать тоже самое, что и на Ingress было.