Модуль 22. Ingress и балансировка
В Kubernetes публикация сервисов во внешний мир строится слоями:
- Service (L3/L4): ClusterIP/NodePort/LoadBalancer — базовая связность и балансировка на уровне IP/портов.
- Ingress / Gateway API (L7): HTTP(S)-маршрутизация по доменам/путям, TLS-терминация, политики.
- Ingress Controller: реальный прокси/балансировщик, который читает объекты Ingress/Route и программирует dataplane (Nginx, HAProxy, Traefik и т.д.).
- TLS и PKI: cert-manager/ACME/Vault для выпуска/ротации сертификатов.
- Внешний LB: L4 (cloud LB/MetalLB/HAProxy/F5) «поднимает» Ingress-поды наружу.
Типовая прод-схема:
Internet/CorpNet
|
[L4 Load Balancer] — TCP:443/80 (externalTrafficPolicy: Local для реального client IP)
|
[Ingress Controller] — NGINX/HAProxy/Traefik (несколько реплик, HPA/PDB)
|
[Services] — ClusterIP/Headless
|
[Pods] — приложения/BI
Выбор Ingress-контроллера
NGINX Ingress Controller (ingress-nginx)
- Сильные стороны: зрелость, широкая экосистема, аннотации на все случаи, ModSecurity/OWASP CRS, хорошие метрики Prometheus.
- Где блестит: типовой HTTP/S трафик, богатые L7-политики, WAF, canary (через аннотации/Argo Rollouts).
- Нюансы: конфигурация через аннотации + ConfigMap требует дисциплины (легко «рассыпать» настройки).
HAProxy Ingress
- Сильные стороны: высокая производительность, низкая задержка, сильные L4/L7 ACL, PROXY Protocol, продвинутая «наблюдаемость» (stick-tables, counters).
- Где блестит: нагруженные порталы, WebSocket/gRPC, TCP/SSL-passthrough, сложные ACL.
- Нюансы: меньше «how-to» в рунете, но всё необходимое есть в документации и метриках.
Traefik
- Сильные стороны: простая модель, «middleware» (rate-limit, basic auth, rewrite), HTTP/3/QUIC, собственный ACME клиент.
- Где блестит: быстрый старт, dev/stage, edge-сценарии, когда хочется встроенных «middleware».
- Нюансы: для предприятия обычно выбирают cert-manager вместо встроенного ACME, чтобы унифицировать PKI.
Критерии выбора: требования к WAF, пропускной способности, TCP/UDP, gRPC/WebSocket, опыту команды, наличию корпоративной PKI. В сомнениях — начните с NGINX Ingress (де-факто стандарт), для «очень быстрого» трафика рассмотрите HAProxy Ingress, для «middleware-ориентированного» — Traefik.
HTTPS: терминация, ротация, mTLS
Где терминировать TLS
- На Ingress (edge-termination) — стандарт: Ingress держит публичный сертификат, к backend ходит по http или re-encrypt (https).
- SSL-passthrough/SNI-routing — нужен, если приложение само управляет TLS (обычно избегаем, сложнее диагностика и политика безопасности).
- Re-encrypt — Ingress → backend по mTLS (для регуляторных сред).
cert-manager (общая схема)
- Создаём Issuer/ClusterIssuer (ACME/HTTP-01 или DNS-01; либо Vault/CA).
- В Ingress указываем tls.hosts и secretName.
- cert-manager сам создаёт Challenge, верифицирует домен, кладёт секрет и автоматически продлевает сертификат.
Мини-фрагменты (идея; адаптируйте под свою среду):
# ClusterIssuer для Let's Encrypt (staging, HTTP-01)
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata: { name: letsencrypt-staging }
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: ops@example.org
privateKeySecretRef: { name: le-account-key }
solvers:
- http01:
ingress:
class: nginx
# Ingress с TLS и аннотациями
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-staging
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
tls:
- hosts: [ "app.example.org" ]
secretName: app-tls
rules:
- host: app.example.org
http:
paths:
- path: /
pathType: Prefix
backend: { service: { name: app-svc, port: { number: 80 } } }
DNS-01: для wildcard-сертов и когда HTTP-01 невозможен (корп-прокси, закрытые периметры). Нужны креды на DNS-провайдера.
Внутренняя PKI: Issuer типа Vault или «обычный CA» (root/intermediate), чтобы Ingress получал «корпоративные» сертификаты.
Автопродление: cert-manager обновляет секрет заранее (по умолчанию ~30 дней до истечения). Важно мониторить события Certificate/Order и сроки.
mTLS: в NGINX/HAProxy настраивается проверка клиентских сертификатов (CRL/OCSP); в re-encrypt режиме задействуйте отдельный CA и verify на бэкенд-TLS.
Настройки, которые «делают погоду»
- externalTrafficPolicy: Local на Service Ingress-контроллера — сохраняет реальный client IP; требуются достаточные реплики и readiness на нодах-входах.
- Пулы соединений/keepalive: включить keepalive к backend, следить за пределами max_conns у приложений.
- Таймауты: proxy-read-timeout, send-timeout, client-body-timeout — важны при долгих отчётах/экспортах BI.
- Размеры тел: proxy-body-size/client_max_body_size — иначе «413 Request Entity Too Large» при загрузках/экспортах.
- Sticky-сессии: cookie-based (если приложение stateful по сессии). По возможности проектируйте stateless.
- HTTP/2 и gRPC: включить ALPN, проверить h2c при необходимости.
- HSTS/CSP: базовая гигиена безопасности на фронте.
- Access-лог/корреляция: добавляйте X-Request-ID, пишите комбинированные логи в JSON (аккуратно с PII).
Частые ошибки и как их лечить
|
Симптом |
Причина |
Что сделать |
|---|---|---|
|
Петля редиректов |
Двойной редирект http→https: и на Ingress, и в приложении; неверный X-Forwarded-Proto |
Оставьте редирект где-то одном; убедитесь, что контроллер проставляет X-Forwarded-Proto: https |
|
Истёк TLS |
Нет auto-renew (нет cert-manager/сломались права/креды DNS) |
Включить cert-manager, проверить события Certificate, исправить solver, поставить алерты «до истечения < 14 дней» |
|
Потерялся реальный IP |
L4 LB делает SNAT, externalTrafficPolicy: Cluster |
Включить Local и/или PROXY Protocol; правильно парсить X-Forwarded-For |
|
502/504 |
Таймауты к backend, не хватает воркеров/коннектов, keepalive не настроен |
Увеличить таймауты, включить keepalive, проверить лимиты у backend (DB/HTTP-пул) |
|
WebSocket/Streaming обрывается |
Неверные таймауты/протокол |
Включить соответствующие опции (upgrade, timeouts) |
|
Нечитаемые тела > N МБ |
Ограничение размера в контроллере |
Поднять client_max_body_size/аналог |
|
Горячие ноды-входы |
externalTrafficPolicy: Local без равномерного трафика |
Балансировать L4 по нодам с Ready endpoints; HPA и DaemonSet-модель по необходимости |
Масштабирование и эксплуатация
- Модель развёртывания: Deployment (2–4+ реплики) либо DaemonSet (каждая нода — точка входа; полезно в приватных сетях/edge).
- Service Ingress-контроллера: тип LoadBalancer (в облаке) или NodePort (on-prem с внешним LB/MetalLB).
- HPA: по RPS/latency/CPU (Prometheus-adapter метрик контроллера).
- PDB и Pod Anti-Affinity: чтобы апгрейды/аварии не обрушили весь вход.
- Метрики и логи: latency p50/p95/p99, 4xx/5xx, коннекты, очереди, saturation у воркеров; алерты на рост 5xx и p95.
- WAF: ModSecurity/OWASP CRS в NGINX, ACL/спуф-защиты/limit-rate в HAProxy, middleware в Traefik.
Практика (лабораторка)
- Поднять Ingress-контроллер (любой из тройки) с 2–3 репликами, Service типа LoadBalancer/NodePort, externalTrafficPolicy: Local.
-
Выпустить сертификат через cert-manager:
- поставить ClusterIssuer (staging),
- завести Ingress с аннотацией cert-manager.io/cluster-issuer,
- дождаться Certificate Ready, проверить авто-обновление (посмотреть NotAfter).
- Протестировать таймауты и размер тел: увеличить лимиты для большого экспорта (BI кейс), проверить отсутствие 413/504.
- Проверить client IP: в логах приложения увидеть реальный адрес; при необходимости включить PROXY Protocol.
- Сымитировать редирект-петлю: включить https-redirect и в приложении, и в Ingress; найти, устранить, зафиксировать правило в плейбуке.
- Собрать метрики/дашборды: p95 latency, 5xx, conncurrent, saturations; алерты на «истёкнет TLS < 14 дней».
Безопасность «на краю»
- TLS 1.2+/современные шифры, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy.
- Rate-limit (per IP/route), базовая защита от брутфорса/сканеров.
- WAF (режим обнаружения → блокировка после обучения).
- mTLS (клиентские сертификаты) для внутренних порталов/админок.
- Логи без PII, корреляция по Request-ID; опционально — псевдонимизация.
Риски и анти-паттерны
|
Риск |
Проявление |
Контрмера |
|---|---|---|
|
Разброс настроек аннотациями |
«зоопарк» per-Ingress, никто не знает финал |
Больше общесистемных настроек через ConfigMap/CRD/Policy; шаблоны |
|
Один Ingress-контроллер на всё |
Single point для входа |
2–3 реплики, PDB, anti-affinity, HPA; разные ingressClass для внешнего/внутреннего |
|
Отсутствие мониторинга cert-manager |
Внезапно истёк TLS |
Алерт «до истечения <14 дней», аудит событий Certificate/Order |
|
Неверный разбор X-Forwarded-For |
Потеря клиентского IP/безопасности |
externalTrafficPolicy: Local, PROXY Protocol, жёсткие доверенные источники |
|
Слишком малые таймауты |
502/504 на отчётах/экспорт |
Увеличить таймауты и keepalive, убедиться, что backend готов их выдержать |
|
WAF «в бою с первого дня» |
Ложные блокировки |
Сначала detection-mode + тюнинг, затем блокировки |
Чек-лист «готово к продакшену (Ingress)»
- 2–4 реплики Ingress-контроллера, PDB, anti-affinity, HPA.
- Service Ingress-контроллера с externalTrafficPolicy: Local (где нужен реальный IP).
- cert-manager с ClusterIssuer (prod + staging), алерты на истечение TLS.
- Единые политики таймаутов/размеров тел; middleware/аннотации по шаблонам.
- Логи и метрики (p95/5xx/conntrack/воркеры), дашборды и алерты.
- WAF/Rate-limit включены там, где нужно; HSTS/CSP.
- Документирован runbook: «петля редиректов», «истёк TLS», «потерян client IP», «502/504».
Вопрос-ответ
В: Что выбрать для предприятия: NGINX, HAProxy или Traefik?
О: Если нужен максимально распространённый стек, WAF и масса инструкций — NGINX Ingress. Если важна низкая задержка и мощные ACL — HAProxy Ingress. Если нужен простой старт и middleware — Traefik. Все три годятся для продакшена.
В: Где лучше терминировать TLS — на Ingress или в приложении?
О: На Ingress. Это централизует шифрование/политики и упрощает ротацию сертов. Исключения — редкие (специальные протоколы или особая криптополитика).
В: Нужен wildcard-сертификат?
О: Для множества поддоменов — да, делайте DNS-01 в cert-manager. Учтите риски: один компрометированный хост → весь домен под угрозой.
В: Как избежать петли редиректов?
О: Включайте https-redirect только в одном месте (обычно в Ingress). Убедитесь, что приложение корректно доверяет X-Forwarded-Proto: https.
В: Как логировать реальный IP клиента за облачным LB?
О: externalTrafficPolicy: Local + доверяйте только заголовкам от L4 LB или используйте PROXY Protocol и соответствующий парсер в Ingress.
В: Что с TCP/UDP (не HTTP)?
О: У NGINX/HAProxy есть режимы stream/TCP/UDP (через отдельные CRD/ConfigMap). В мире Gateway API это проще. Оцените, не лучше ли вынести чистый L4 на внешний LB.
В: Стоит ли включать HTTP/3 (QUIC)?
О: Для публичных фронтов — да, Traefik поддерживает, для NGINX/HAProxy возможны варианты. Проверьте обратную совместимость и метрики.
В: Как делать канареечные релизы через Ingress?
О: Аннотации canary в NGINX/Traefik или трафик-сплиттер в Argo Rollouts/Gateway API. Мониторьте p95/5xx, держите «красную кнопку» отката.
Ingress — это «край» вашей платформы: надёжность входа, TLS, производительность и безопасность начинаются здесь. Выберите контроллер осознанно, централизуйте TLS через cert-manager, зафиксируйте таймауты/лимиты, включите метрики и WAF там, где нужно. Самые частые сбои — редирект-петли, потеря client IP и просроченные сертификаты — лечатся дисциплиной конфигурации и простыми алертами. Когда «край» в порядке, всё внутри кластера живёт спокойнее.



