Що таке Ingress в Kubernetes
Головне концептуальне розділення, яке потрібно розуміти:
🟢 Junior Level
30-секундна відповідь
Ingress — це спеціалізований API-об’єкт Kubernetes, який керує вхідним зовнішнім HTTP/HTTPS трафіком (L7 рівня моделі OSI), забезпечуючи єдину точку входу в кластер, маршрутизацію за доменними іменами та URL-шляхами, а також централізовану термінацію SSL/TLS сертифікатів.
Головне концептуальне розділення, яке потрібно розуміти:
Ingress Resource(Маніфест): це декларативний YAML-файл, у якому описані правила маршрутизації: «Запити наapi.company.com/ordersнадсилати на сервісorder-service». Сам по собі цей YAML пасивний і нічого не перенаправляє.Ingress Controller(Виконавець): це реальний застосунок (Nginx, Traefik, HAProxy, Envoy), що працює в кластері як зворотний проксі (Reverse Proxy). Контролер безперервно читає маніфести Ingress з API-сервера та динамічно налаштовує свої таблиці маршрутизації.
Наочна аналогія з життя
Ingress — це ресепшн у великому офісному бізнес-центрі:
- У будівлі є одна спільна вхідна адреса та один телефонний номер.
- Відвідувач заходить на ресепшн і каже: «Мені в бухгалтерію» (запит до
/billing) або «Мені у відділ кадрів» (запит до/hr). - Адміністратор на ресепшн (Ingress Controller) скеровує людину на потрібний поверх і в конкретний кабінет (внутрішній
ClusterIPсервіс).
Базовий маніфест Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: main-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx # Зв'язка з конкретним Ingress-контролером
tls:
- hosts:
- api.company.com
secretName: company-tls-cert # SSL-сертифікат із K8s Secret
rules:
- host: api.company.com
http:
paths:
- path: /orders
pathType: Prefix
backend:
service:
name: order-service
port:
number: 8080
- path: /users
pathType: Prefix
backend:
service:
name: user-service
port:
number: 8080
🟡 Middle Level
Економіка та архітектура: Ingress vs Service LoadBalancer
[ Без Ingress: Дорого та не масштабовано ]
Client ──► Cloud LoadBalancer 1 ($25/міс) ──► Order Service
Client ──► Cloud LoadBalancer 2 ($25/міс) ──► User Service
Client ──► Cloud LoadBalancer 3 ($25/міс) ──► Payment Service
[ З Ingress: Дешево, безпечно та централізовано ]
Client ──► ЄДИНИЙ Cloud LoadBalancer ($25/міс) ──► [ Ingress Controller (Nginx) ]
│
┌─────────────────────────┼─────────────────────────┐
▼ ▼ ▼
Order Service User Service Payment Service
(ClusterIP:8080) (ClusterIP:8080) (ClusterIP:8080)
- L4 vs L7: Звичайний
Service type: LoadBalancerпрацює на 4 рівні моделі OSI (TCP/UDP) — він не розуміє HTTP-заголовків, cookies, URL-шляхів та доменних імен. - Ingress працює на 7 рівні OSI (HTTP/HTTPS): він уміє розбирати HTTP-пакет, термінувати TLS, виконувати rewrite URL, перевіряти JWT-токени, обмежувати rate-limit та балансувати запити за префіксами шляхів.
Типи зіставлення шляхів (pathType)
Специфікація networking.k8s.io/v1 вимагає явного зазначення алгоритму зіставлення шляхів:
Exact: строгий точний збіг з урахуванням регістру (наприклад, шлях/ordersспрацює строго на/orders, але запит/orders/123буде відхилений із помилкою 404).Prefix: збіг за префіксом URL із розділенням за слешами./ordersперенаправить і/orders, і/orders/123/items, але проігнорує/orders-archive.ImplementationSpecific: зіставлення віддається логіці конкретного контролера (наприклад, підтримка регулярних виразів regex у Nginx Ingress).
Автоматизація TLS-сертифікатів з Cert-Manager
У продакшені сертифікати оновлюються автоматично зв’язкою Cert-Manager + Let’s Encrypt:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: secure-ingress
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod" # Замовлення безкоштовного TLS-сертифіката
spec:
ingressClassName: nginx
tls:
- hosts:
- shop.example.com
secretName: shop-tls-secret # Cert-Manager сам створить цей Secret
🔴 Senior Level
Проблема «Nginx Reload Storm» та перевага Envoy (Contour / Istio)
Найпопулярніший контролер — Nginx Ingress Controller — має архітектурну ваду на великих кластерах:
[ Nginx Ingress Controller ]
Подія зміни Pod/Service ──► Генерація нового nginx.conf ──► nginx -s reload (50-250ms)
│
Падіння активних з'єднань ◄─────┴──► Сплеск затримки (Latency Spike)
- Як працює Nginx: при кожному масштабуванні подів (HPA scale up/down) або зміні Endpoints контролер запускає шаблонізатор на Go, наново збирає гігантський файл конфігурації
nginx.confі надсилає сигнал процесуnginx -s reload. - Reload Storm: якщо в кластері сотні сервісів безперервно деплояться або масштабуються, релоад Nginx відбувається раз на 2–3 секунди. У цей момент робочі процеси скидають кеші, затримують вхідні HTTP/2 та WebSocket з’єднання, викликаючи стрибки затримки (Latency Spikes) та помилки 502/504.
- Рішення (Envoy xDS API): сучасні контролери на базі Envoy (Contour, Envoy Gateway, Istio IngressGateway) використовують потоковий gRPC протокол xDS (EDS/CDS/LDS). Envoy динамічно оновлює списки IP-адрес бекендів в оперативній пам’яті на льоту за 2–5 мілісекунд БЕЗ перезавантаження процесу та без розриву мережевих сокетів!
Kubernetes Gateway API (Заміна Ingress у K8s 1.28+ GA)
Специфікація Ingress створювалася у 2015 році та має критичні недоліки: хаос невалідованих анотацій (nginx.ingress..., traefik.ingress...), відсутність підтримки gRPC/TCP/UDP та змішування зон відповідальності.
Gateway API розділяє ролі та ресурси:
GatewayClass: визначає тип контролера (керує інфраструктурний інженер або хмарний провайдер).Gateway: визначає точку входу, IP та відкриті порти 80/443 (керує DevOps / кластерний адміністратор).HTTPRoute/GRPCRoute: описують правила маршрутизації конкретного мікросервісу (керує команда бекенд-розробників):
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: order-route
spec:
parentRefs:
- name: internal-gateway # Посилання на кластерний шлюз
hostnames:
- "api.company.com"
rules:
- matches:
- path:
type: PathPrefix
value: /orders
backendRefs:
- name: order-service
port: 8080
weight: 90
- name: order-service-canary
port: 8080
weight: 10 # Вбудована нативна підтримка Canary без vendor-анотацій!
4 Tricky Questions
1. Що станеться, якщо створити об’єкт Ingress у кластері, де не розгорнуто жодного Ingress Controller?
Відповідь:
Маніфест Ingress буде успішно прийнятий kube-apiserver і збережений у базі даних etcd (команда kubectl apply відпрацює без помилок).
Проте жодної мережевої маршрутизації відбуватися не буде:
- Стовпчик
ADDRESSу виводіkubectl get ingressзалишиться порожнім назавжди. - Жодних хмарних балансувальників навантаження створено не буде.
- Об’єкт залишиться пасивним записом у базі даних доти, доки в кластері не з’явиться контролер (наприклад,
ingress-nginx), який прочитає цей ресурс і прив’яже до нього свою зовнішню IP-адресу.
2. Як Nginx Ingress Controller реалізує канаркове розгортання (Canary Deployment), і що станеться при поєднанні відсоткової ваги (canary-weight) та збігу заголовка (canary-by-header)?
Відповідь:
Канарковий Ingress створюється як дублюючий маніфест з анотацією nginx.ingress.kubernetes.io/canary: "true".
- Контролер не змінює Kubernetes Endpoints, а генерує в блоці
serverNginx спеціальнийupstream, у який відправляє частину запитів. - Пріоритет правил при їх спільному використанні:
canary-by-header: найвищий пріоритет. Якщо запит містить заголовок (наприклад,X-Canary: always), він завжди спрямовується на canary, незалежно від відсоткової ваги.canary-by-cookie: середній пріоритет (за значенням cookie).canary-weight: найнижчий пріоритет. Застосовується методом рандомізації лише до запитів, які не потрапили під правила заголовків або cookie.
3. Чому для реалізації WebSocket через Nginx Ingress потрібні спеціальні налаштування таймаутів, і що відбувається за замовчуванням?
Відповідь: Протокол WebSocket починається з HTTP Upgrade, після чого з’єднання перетворюється на довгоживучий двонаправлений TCP-тунель:
- За замовчуванням у Nginx Ingress параметри
proxy-read-timeoutтаproxy-send-timeoutдорівнюють60s. - Якщо між клієнтом і сервером немає безперервного обміну повідомленнями протягом 60 секунд, Nginx примусово обриває TCP-з’єднання з клієнтом.
- Для стабільної роботи WebSocket у маніфест Ingress обов’язково додають анотації:
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"а також налаштовують відправку Ping/Pong фреймів на рівні Java-сервера (Netty / Spring WebSocket).
4. У чому полягає загроза безпеки при використанні анотації configuration-snippet у Nginx Ingress, і чому багато хмарних провайдерів відключають її за замовчуванням?
Відповідь:
Анотація nginx.ingress.kubernetes.io/configuration-snippet дозволяє вставляти довільний синтаксис директив Nginx прямо в тіло конфігураційного файлу.
- Вразливість (CVE-2021-25742 / CVE-2023-5043): розробник, який має права на створення Ingress у своєму обмеженому namespace, може впровадити довільний код на Lua або директиви Nginx, що дозволяють прочитати приватні SSL-сертифікати інших орендарів кластера, отримати токени сервісних акаунтів контролера з файлової системи
/var/run/secrets/або здійснити Server-Side Request Forgery (SSRF). - У сучасних версіях фреймворку опція
allow-snippet-annotationsза замовчуванням відключена в ConfigMap контролера з міркувань безпеки.
🎯 Шпаргалка для інтерв’ю
Головне про Ingress
- Суть: L7 (HTTP/HTTPS) зворотний проксі для маршрутизації зовнішнього трафіку за доменами та шляхами.
- Ingress Resource vs Controller: YAML-маніфест пасивний; трафік проксіює активний процес (Ingress Controller — Nginx, Traefik, Envoy).
- Економія: 1 хмарний балансувальник перед контролером обслуговує десятки й сотні сервісів
ClusterIP. - TLS Termination: сертифікати зберігаються в K8s Secret і автоматично перевипускаються через Cert-Manager.
- Проблема Nginx Reload: часті деплої викликають шторм перезавантажень Nginx; альтернатива — Envoy з динамічним xDS API.
- Майбутнє: Kubernetes Gateway API (GA в K8s 1.28+) замінює Ingress завдяки типізованому рольовому API.
Ingress vs Service LoadBalancer
| Параметр | Service (type: LoadBalancer) | Ingress |
| :— | :— | :— |
| Рівень OSI | L4 (TCP / UDP) | L7 (HTTP / HTTPS / gRPC) |
| Маршрутизація | Тільки за портами | За доменами (host), шляхами (path), заголовками |
| Керування SSL | На рівні хмари або подів | Централізована термінація на вході |
| Вартість у хмарі | Плата за кожен сервіс | Плата за один зовнішній балансувальник |
Червоні прапорці на співбесіді (Чого говорити не можна)
- ❌ «Ingress — це балансувальник четвертого рівня для TCP з’єднань» — Ingress працює виключно на прикладному рівні L7 (HTTP/HTTPS).
- ❌ «Якщо застосувати маніфест Ingress, він сам почне скеровувати трафік без будь-яких контролерів» — без запущеного Ingress Controller маніфест абсолютно марний.
- ❌ «Для кожного мікросервісу в кластері ми створюємо окремий хмарний LoadBalancer» — антипатерн, що веде до величезних необґрунтованих витрат.