Що таке Ingress в Kubernetes?
Ingress -- це L7 (HTTP) маршрутизатор. На відміну від Service (L4, IP:порт), Ingress маршрутизує по доменах, URL-шляхах, headers. Один Ingress = безліч сервісів.
🟢 Junior Level
Просте визначення
Ingress — це API-об’єкт Kubernetes, який керує зовнішнім HTTP/HTTPS трафіком, направляючи його до потрібних сервісів всередині кластера. Це “єдина точка входу” — одна адреса для всього кластера, а Ingress вирішує, якому сервісу дістанеться кожен запит.
Ingress – це L7 (HTTP) маршрутизатор. На відміну від Service (L4, IP:порт), Ingress маршрутизує по доменах, URL-шляхах, headers. Один Ingress = безліч сервісів.
Аналогія
Ingress — це ресепшн у великій офісній будівлі. Усі дзвінки йдуть через один номер. Ресепшн питає: “Вам бухгалтерія?” — направляє на 3 поверх. “Вам IT?” — на 5 поверх. Один телефонний номер, багато напрямків.
Приклад YAML
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: api-v1
port:
number: 8080
- path: /v2
pathType: Prefix
backend:
service:
name: api-v2
port:
number: 8080
tls:
- hosts:
- api.example.com
secretName: api-tls-secret
Приклад kubectl
# Подивитися усі Ingress ресурси
kubectl get ingress
# Детальна інформація
kubectl describe ingress my-ingress
# Перевірити, чи працює Ingress Controller
kubectl get pods -n ingress-nginx
Коли використовувати
- Кілька сервісів, доступних ззовні кластера по одному IP
- Потрібна маршрутизація по доменним іменам (api.example.com, web.example.com)
- Потрібна маршрутизація по шляхах (/v1, /v2, /static)
- Централізоване управління SSL/TLS сертифікатами
🟡 Middle Level
Як це працює
Ingress складається з двох окремих компонентів:
-
Ingress Resource — YAML-маніфест з правилами роутингу (хости, шляхи, TLS). Це просто запис в etcd, сам по собі він нічого не робить.
-
Ingress Controller — реальний додаток (Nginx, HAProxy, Traefik, Envoy), який читає Ingress Resources з API Server і налаштовує себе як reverse proxy. Без контроллера Ingress Resource марний.
Ingress ресурс – це тільки правила маршрутизації. Ingress Controller – це процес (nginx, Traefik, HAProxy), який ці правила застосовує. Без Controller Ingress марний.
Ланцюжок запиту:
Client → Cloud LoadBalancer (зовнішній IP) → Ingress Controller Pod → Service → Backend Pod
Ingress Controller зазвичай працює через Service типу LoadBalancer або NodePort. Він отримує зовнішній IP від хмарного провайдера і приймає увесь вхідний трафік.
Практичні сценарії
Сценарій 1: Path-based routing для мікросервісів
rules:
- host: api.example.com
http:
paths:
- path: /users
pathType: Prefix
backend:
service:
name: user-service
port:
number: 8080
- path: /orders
pathType: Prefix
backend:
service:
name: order-service
port:
number: 8080
Сценарій 2: TLS з Cert-Manager (автоматичні Let’s Encrypt сертифікати)
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: api-tls
spec:
secretName: api-tls-secret
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- api.example.com
Сценарій 3: Canary deployment через Ingress
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10"
10% трафіку йде на canary-версію, 90% — на стабільну.
Таблиця поширених помилок
| Помилка | Наслідок | Рішення |
|---|---|---|
| Створення Ingress без Ingress Controller | Ingress Resource існує, але трафік не йде | Встановити nginx-ingress, traefik або інший контроллер |
| Забутий ingressClassName | Використовується контроллер за замовчуванням або помилка | Завжди вказувати ingressClassName: nginx |
| Неправильний pathType | Exact не матчить /v1/extra, Prefix матчить занадто багато |
Використовувати Prefix з rewrite-target або ImplementationSpecific |
| TLS Secret не існує | Ingress працює, але без HTTPS | Створити Secret з tls.crt та tls.key до створення Ingress |
| Один контроллер на весь кластер — single point of failure | При падінні контроллера увесь зовнішній трафік недоступий | Запускати контроллер як DaemonSet або репліки з anti-affinity |
| Анотації контроллера не задокументовані | Складно підтримувати, невідомо що робить кожна анотація | Документувати анотації, використовувати IngressClass з parameters |
Порівняльна таблиця: Ingress vs LoadBalancer vs NodePort
| Характеристика | NodePort | LoadBalancer | Ingress |
|---|---|---|---|
| Рівень OSI | L4 (TCP/UDP) | L4 (TCP/UDP) | L7 (HTTP/HTTPS) |
| Вартість | Безкоштовно | $15-50/міс за кожен LB | $15-50/міс за ОДИН LB на усі сервіси |
| Маршрутизація | По порту | По порту | По хосту, шляху, заголовкам |
| TLS | Ні (на рівні Pod) | Ні (на рівні Pod) | Централізоване |
| Масштабованість | Один сервіс на порт | Один сервіс на LB | Сотні сервісів на одному LB |
| Rate Limiting | Ні | Залежить від хмари | Так (через анотації) |
| WebSocket | Так | Так | Так (з налаштуваннями) |
Коли НЕ використовувати
- TCP/UDP трафік без HTTP — Ingress працює тільки на L7. Для TCP/UDP використовуйте Service типу LoadBalancer або TCP/UDP ConfigMap в nginx-ingress
- Один сервіс — якщо у вас тільки один API, простіше використовувати LoadBalancer Service
- Потрібен L4 балансировщик з TLS termination — використовуйте Gateway API (наступне покоління Ingress) або Service Mesh
- Внутрішня комунікація між мікросервісами — для цього використовуйте звичайні Services, не Ingress
🔴 Senior Level
Глибинна механіка: Ingress Controller, Nginx, та Controller Reconciliation
Ingress Controller Architecture: Ingress Controller — це Kubernetes Controller, який працює за стандартним pattern reconciliation:
1. Watch: Підписується на Ingress Resources через API Server (watcher)
2. List: Отримує повний список Ingress, Services, Endpoints, Secrets
3. Reconcile: Порівнює бажаний стан (Ingress YAML) з поточним (nginx.conf)
4. Update: Генерує нову nginx.conf і виконує `nginx -s reload`
5. Loop: Повторює при кожній зміні (через Informer)
Nginx Ingress Controller (найпопулярніший):
- Використовує Go-бібліотеку
k8s.io/client-goдля informer’ів - При зміні Ingress/Service/Endpoint перегенерує
nginx.confчерез Go templates - Виконує
nginx -s reload(graceful reload, без downtime) - При великій кількості Ingress (1000+) reload nginx стає bottleneck — nginx повинен перезавантажити конфігурацію, що займає 50-200ms
Contour (Envoy-based):
- Замість nginx використовує Envoy Proxy
- Envoy використовує xDS API для динамічної конфігурації — без перезавантаження
- При 1000+ Ingress Contour стабільніший, оскільки немає reload overhead
Gateway API (майбутнє Ingress):
- Більш виразний API: підтримка TCP/UDP, gRPC, header-based routing
- Role-based: окремі ресурси для Gateway (infra-команда) та HTTPRoute (dev-команда)
- Поступово замінює Ingress, але поки не всі контроллери підтримують
Gateway API – GA з K8s v1.28. Більш гнучкий, підтримує TCP/UDP, не тільки HTTP. Поступово замінює Ingress.
Trade-offs
| Аспект | Trade-off |
|---|---|
| Nginx vs Envoy | Nginx простіше і звичніше, але reload при великих конфігураціях = latency spike. Envoy без reload, але складніший в експлуатації |
| Один vs багато контроллерів | Один контроллер дешевше і простіше, але single point of failure. Багато контроллерів = ізоляція по командах, але дорожче |
| Ingress vs Gateway API | Ingress зрілий і підтримується скрізь. Gateway API більш виразний, але менш зрілий |
| Annotations vs CRD | Annotations простіше, але не валідуються. CRD (Kong, Gloo) дають валідацію та документування, але вимагають встановлення CRD |
| TLS termination: Ingress vs Pod | Termination на Ingress = централізоване управління, але Ingress бачить увесь трафік. Termination в Pod = end-to-end TLS, але складніше управління сертифікатами |
Edge Cases (6+)
Edge Case 1: Ingress Controller reload storm При 1000+ Ingress Resources та частих деплоях (100+ в день), nginx controller постійно перегенерує конфігурацію. Кожен reload = 50-200ms latency spike для активних з’єднань. Рішення: batching updates, або перехід на Envoy-based контроллер (Contour, Istio Gateway).
Edge Case 2: Sticky Sessions з IPVS Nginx Ingress підтримує sticky sessions через cookie. Але якщо kube-proxy працює в IPVS mode, а не iptables, балансування на рівні Service може конфліктувати з nginx sticky sessions. Клієнт зі sticky cookie потрапляє на потрібний Pod через nginx, але nginx forward’ить на Service IP, і IPVS може перенаправити на інший Pod.
Edge Case 3: TLS Secret в іншому namespace
Ingress Resource може посилатися на TLS Secret тільки в своєму namespace. Якщо команда A керує Ingress в namespace prod, а сертифікати зберігаються в namespace cert-manager, потрібен механізм копіювання Secret’ів (наприклад, cert-manager + secretTemplate або external-secrets operator).
Edge Case 4: WebSocket через Ingress WebSocket вимагає upgrade з’єднання HTTP → WS. Nginx Ingress за замовчуванням закриває idle з’єднання через 60 секунд. Для довготривалих WebSocket потрібно:
annotations:
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
Edge Case 5: Ingress та NetworkPolicy
Ingress Controller повинен мати доступ до усіх Backend Pod’ів. Якщо ви налаштували NetworkPolicy, що забороняє вхідний трафік на Backend namespace, Ingress Controller не зможе forward’ити запити. Рішення: NetworkPolicy має дозволяти трафік від ingress-nginx namespace.
Edge Case 6: Multiple Ingress Controllers
В кластері може бути кілька Ingress Controller’ів (nginx для зовнішніх сервісів, istio для внутрішніх). Ingress Resource має явно вказувати ingressClassName. Якщо не вказано — використовується контроллер з анотацією ingressclass.kubernetes.io/is-default-class. Конфлікт контроллерів = непередбачуваний роутинг.
Edge Case 7: Ingress з headless Service
Ingress вимагає Service з ClusterIP. Headless Service (clusterIP: None) не підтримується як backend для Ingress — nginx не може резольвити headless Service в upstream’и. Рішення: створити окремий ClusterIP Service для Ingress.
Performance Numbers
| Метрика | Значення |
|---|---|
| Nginx reload latency | 50-200ms (залежить від розміру конфігурації) |
| Envoy xDS update latency | 1-10ms (без перезавантаження) |
| Ingress Controller→Backend latency | 1-5ms (всередині кластера) |
| Max Ingress Resources per Controller | ~1000-2000 (nginx), ~5000+ (Envoy) |
| TLS handshake overhead | 5-15ms (TLS 1.3), 15-30ms (TLS 1.2) |
| Rate limiting overhead | 0.1-1ms на запит (nginx limit_req) |
| Cloud LoadBalancer cost | $15-50/міс (один LB для всього кластера) |
Security
- TLS termination на Ingress — трафік між Ingress та Pod’ами йде без шифрування. Для compliance (PCI-DSS, HIPAA) потрібен end-to-end TLS: Ingress → Pod через HTTPS з internal cert
- Rate Limiting — захистіть backend від DDoS через анотації:
nginx.ingress.kubernetes.io/limit-rps: "100" nginx.ingress.kubernetes.io/limit-connections: "50" - WAF (Web Application Firewall) — nginx-ingress підтримує ModSecurity для захисту від OWASP Top 10:
nginx.ingress.kubernetes.io/enable-modsecurity: "true" nginx.ingress.kubernetes.io/modsecurity-snippet: | SecRuleEngine On - IP Whitelisting — обмежте доступ до внутрішніх API:
nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/8,172.16.0.0/12" - HSTS headers — enforce HTTPS:
nginx.ingress.kubernetes.io/use-hsts: "true" nginx.ingress.kubernetes.io/hsts-max-age: "31536000" - Ingress Controller в окремому namespace — запускати в
ingress-nginxз обмеженим RBAC та NetworkPolicy
Production War Story
Ситуація: SaaS-платформа, 200 мікросервісів, один Nginx Ingress Controller на весь кластер (репліка 2). Під час Black Friday кількість деплоїв зросла з 50 до 500 в день. Кожен деплой створював/оновлював Ingress Resource, і nginx controller перегенерував конфігурацію.
Проблема:
- Nginx reload відбувався кожні 2-3 секунди
- Кожен reload викликав 100-200ms latency spike для 30% активних з’єднань
- p99 latency зріс з 200ms до 2 секунд
- Клієнти почали отримувати timeout’и
- HPA масштабував Pod’и, що створювало ще більше Ingress updates → feedback loop
Post-mortem та fix:
- Розділили Ingress Controller’и по критичності:
ingress-external(публічні API),ingress-internal(B2B сервіси) - Перейшли на Contour (Envoy-based) — xDS updates без reload, latency spike зникли
- Впровадили
batchingIngress updates — контроллер чекає 5 секунд перед reload, збираючи пакетні зміни - Обмежили кількість деплоїв в годину через CI/CD pipeline throttling
- Додано моніторинг
nginx_ingress_controller_reload_duration_seconds
Моніторинг після fix:
# Alert: Nginx reload latency зростає
histogram_quantile(0.99, nginx_ingress_controller_config_last_reload_duration_seconds_bucket) > 0.1
# Alert: Ingress Controller pod restart
rate(kube_pod_container_status_restarts_total{namespace="ingress-nginx"}[5m]) > 0
# Alert: 5xx помилки на Ingress
rate(nginx_ingress_controller_requests{status=~"5.."}[5m]) > 10
Monitoring (Prometheus/Grafana)
Ключові метрики:
# Request rate по статусах
rate(nginx_ingress_controller_requests[5m])
# Latency p50/p95/p99
histogram_quantile(0.99, nginx_ingress_controller_request_duration_seconds_bucket)
# 5xx error rate
sum(rate(nginx_ingress_controller_requests{status=~"5.."}[5m])) by (ingress)
# Ingress Controller reload latency
histogram_quantile(0.99, nginx_ingress_controller_config_last_reload_duration_seconds_bucket)
# Open connections (для WebSocket/long-polling)
nginx_ingress_controller_nginx_metric_connections{state="active"}
# Rate limiting events
rate(nginx_ingress_controller_requests{status="429"}[5m])
Grafana Dashboard панелі:
- Request rate (RPS) по Ingress/Service — зелена/червона лінія по статусах
- Latency p50/p95/p99 — кореляція з деплоями
- 5xx error rate — alert при > 1% від загального трафіку
- Nginx reload count та duration — детекція reload storm
- Active connections — моніторинг WebSocket/long-polling
- Rate limiting events — детекція DDoS або misconfigured limits
Highload Best Practices
- Використовуйте Envoy-based контроллер (Contour, Istio Gateway) при 1000+ Ingress — nginx reload latency стає критичною
- Розділяйте Ingress Controller’и по критичності — публічні API та внутрішні сервіси на різних контроллерах
- Налаштовуйте rate limiting —
limit-rps,limit-connectionsдля захисту від DDoS та abuse - Використовуйте Cert-Manager для автоматизації TLS — ручне управління сертифікатами не масштабується
- Batch Ingress updates в CI/CD — не створюйте 50 Ingress одночасно, групуйте деплої
- Моніторьте reload duration — alert при p99 > 100ms
- Anti-affinity для Ingress Controller Pod’ів — розкидайте репліки по різних нодах:
affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchLabels: app: ingress-nginx topologyKey: kubernetes.io/hostname - Використовуйте Gateway API для нових проектів — Ingress поступово застаріває, Gateway API — майбутнє
- End-to-end TLS для compliance — internal mTLS між Ingress та Pod’ами через Service Mesh або cert-manager internal CA
- Canary через Ingress annotations —
canary: "true"+canary-weight: "10"для безпечного деплою
🎯 Шпаргалка для інтерв’ю
Обов’язково знати:
- Ingress — L7 (HTTP/HTTPS) маршрутизація: по домену, шляху, headers; один IP для багатьох сервісів
- Ingress Resource (YAML правила) ≠ Ingress Controller (nginx, Traefik, Envoy — реальний proxy)
- Без Controller Ingress Resource марний — це просто запис в etcd
- Ingress економить гроші: один LoadBalancer на усі HTTP-сервіси замість LB на кожен
- TLS termination централізоване на Ingress; Cert-Manager для авто-сертифікатів (Let’s Encrypt)
- Nginx reload (50-200ms) при 1000+ Ingress → latency spike; Envoy (xDS) без перезавантаження
- Gateway API (GA з K8s v1.28) — майбутнє; підтримує TCP/UDP, не тільки HTTP
Часті уточнюючі запитання:
- «Ingress без Controller працює?» — Ні, Controller — реальний процес (nginx/Envoy), що читає правила
- «Ingress vs LoadBalancer?» — Ingress = L7 HTTP маршрутизація, LoadBalancer = L4 TCP/UDP
- «Nginx vs Envoy Controller?» — Nginx простіше, але reload overhead; Envoy без reload, але складніше
- «WebSocket через Ingress?» — Потрібні спеціальні анотації (proxy-read-timeout: 3600), інакше 60s timeout
Червоні прапорці (НЕ говорити):
- «Ingress — це балансировщик» (це L7 маршрутизатор; балансування робить Service)
- «Ingress працює без Controller» (Controller обов’язковий)
- «Ingress для TCP/UDP» (тільки HTTP/HTTPS; для TCP — LoadBalancer Service)
- «Один Controller на весь кластер — ОК» (single point of failure; потрібні репліки)
Пов’язані теми:
- [[Які типи Service існують (ClusterIP, NodePort, LoadBalancer)]] — L4 vs L7
- [[Що таке Service в Kubernetes]] — Service vs Ingress
- [[Як організувати rolling update в Kubernetes]] — canary через Ingress