Модуль 3.4: Інгрес
Складність:
[СЕРЕДНЯ]— маршрутизація HTTP/HTTPSЧас на проходження: 45–55 хвилин
Передумови: Модуль 3.1 (Сервіси), Модуль 3.3 (DNS)
Що ви зможете зробити
Розділ «Що ви зможете зробити»Після цього модуля ви зможете:
- Спроєктувати маршрутизацію Інгресу на основі шляху та хоста, яка спрямовує HTTP-трафік до правильного Сервісу Kubernetes.
- Налаштувати термінацію TLS за допомогою Secret’ів типу TLS у Kubernetes та пояснити обмеження, пов’язані з просторами імен.
- Оцінити Інгрес-контролери, вибір IngressClass та компроміси переходу на Gateway API для кластерів Kubernetes 1.35+.
- Діагностувати збої маршрутизації, аналізуючи статус Інгресу, логи контролера, Сервіси, Endpoint’и та правила шляхів.
Чому цей модуль важливий
Розділ «Чому цей модуль важливий»Гіпотетичний сценарій: платформна команда перенесла п’ятнадцять внутрішніх вебзастосунків у Kubernetes, і перед запуском кожна команда застосунку просить публічний доступ через HTTPS. Якщо кластер відкриває кожне робоче навантаження окремим Сервісом типу LoadBalancer, команда отримує п’ятнадцять зовнішніх балансувальників навантаження, п’ятнадцять публічних точок входу, дубльовану роботу з TLS і жодного спільного місця, де можна було б виразити політику хостів чи шляхів. Застосунки, можливо, працюватимуть, але операційна модель стає дорогою, і нею важко керувати під тиском.
Інгрес існує, щоб розв’язати цю проблему маршрутизації на рівні 7 (Layer 7). Сервіс дає стабільний доступ до Pod’ів усередині кластера, тоді як Інгрес описує правила HTTP та HTTPS, які контролер перетворює на реальну конфігурацію проксі. Поширена ментальна модель — це стійка реєстрації в готелі: гості заходять через одні передні двері, адміністратор зчитує ім’я або запит щодо номера, і гостя спрямовують до правильного номера так, що жодному номеру не потрібен власний вхід з вулиці.
Для CKA вам потрібно вміти швидко створювати Інгрес, пояснювати, чому сам по собі ресурс Інгресу нічого не робить, і налагоджувати ситуацію, коли запит провалюється до неправильного бекенду. Для проєктування промислових систем вам також потрібен ширший контекст: API Інгресу залишається підтримуваним у Kubernetes 1.35+, але спільнотний контролер ingress-nginx був виведений з експлуатації в березні 2026 року, тож для нових розгортань варто розглядати підтримувані контролери та Gateway API, а не сприймати старіші приклади як рекомендацію для нової архітектури платформи.
Архітектура Інгресу та межі відповідальності
Розділ «Архітектура Інгресу та межі відповідальності»Перша пастка з Інгресом — це припущення, що мережевим компонентом є сам YAML-ресурс. Це не так. Ресурс Інгресу — це документ із бажаним станом, що зберігається в API Kubernetes, а Інгрес-контролер — це запущене програмне забезпечення, яке стежить за цими документами, програмує проксі та відкриває цей проксі через власний Сервіс. Без контролера API-сервер залюбки збереже ваш Інгрес, але жоден компонент площини даних не прийматиме зовнішній трафік і не заповнить поле ADDRESS.
┌────────────────────────────────────────────────────────────────┐│ Ingress Architecture ││ ││ External Traffic ││ │ ││ ▼ ││ ┌─────────────────────────────────────────────────────────┐ ││ │ Load Balancer / NodePort │ ││ │ (Ingress Controller's Service) │ ││ └────────────────────────┬────────────────────────────────┘ ││ │ ││ ▼ ││ ┌─────────────────────────────────────────────────────────┐ ││ │ Ingress Controller │ ││ │ (nginx, traefik, etc.) │ ││ │ │ ││ │ Reads Ingress resources and configures routing │ ││ └─────────────────────────┬────────────────────────────────┘ ││ │ ││ ┌─────────────┼─────────────┐ ││ │ │ │ ││ ▼ ▼ ▼ ││ ┌──────────┐ ┌──────────┐ ┌──────────┐ ││ │ Service │ │ Service │ │ Service │ ││ │ /api │ │ /web │ │ /docs │ ││ └────┬─────┘ └────┬─────┘ └────┬─────┘ ││ │ │ │ ││ ▼ ▼ ▼ ││ ┌──────┐ ┌──────┐ ┌──────┐ ││ │ Pods │ │ Pods │ │ Pods │ ││ └──────┘ └──────┘ └──────┘ ││ │└────────────────────────────────────────────────────────────────┘Архітектуру легше налагоджувати, коли ви відокремлюєте площину управління від площини даних. API Kubernetes зберігає об’єкти Ingress, Service, EndpointSlice, Secret та IngressClass. Контролер читає ці об’єкти й переписує конфігурацію свого проксі. Потім проксі приймає пакети від Сервісу контролера, застосовує правила HTTP-маршрутизації та перенаправляє трафік до бекенд-Сервісів, які своєю чергою добирають Pod’и.
| Характеристика | NodePort | LoadBalancer | Ingress |
|---|---|---|---|
| Рівень | L4 (TCP/UDP) | L4 (TCP/UDP) | L7 (HTTP/HTTPS) |
| Маршрутизація за шляхом | Ні | Ні | Так |
| Віртуальні хости | Ні | Ні | Так |
| Термінація TLS | Ні | Обмежена | Так |
| Вартість | Безкоштовно | $ за кожен LB | Один контролер на багато сервісів |
| Зовнішня IP | IP вузла:Порт | IP хмарного LB | IP контролера |
NodePort і LoadBalancer досі корисні, але вони розв’язують задачу відкриття доступу на нижчому рівні. Сервіс типу LoadBalancer може поставити один застосунок за хмарним балансувальником навантаження, і це часто правильна відповідь для TCP-сервісу, ендпоінта бази даних у приватній мережі або виділеного робочого навантаження апаратного типу. Інгрес підходить краще, коли рішення залежить від HTTP-імен хостів, шляхів, сертифікатів TLS та спільної політики маршрутизації.
| Компонент | Призначення | Хто створює |
|---|---|---|
| Інгрес-контролер | Власне маршрутизує трафік | Адміністратор кластера |
| Ресурс Інгресу | Визначає правила маршрутизації | Розробник |
| Бекенд-Сервіси | Цільові сервіси | Розробник |
| Secret типу TLS | Сертифікати HTTPS | Розробник / cert-manager |
Зупиніться й передбачте: якщо ви застосуєте дійсний маніфест Інгресу до кластера без встановленого Інгрес-контролера, який об’єкт Kubernetes прийме маніфест, а яке видиме поле зазвичай залишиться порожнім? API-сервер приймає об’єкт, оскільки схема дійсна, але статус, що належить контролеру, не оновлюється, бо жоден контролер не узгоджує цей ресурс.
Контролери, IngressClass та ландшафт після виведення з експлуатації
Розділ «Контролери, IngressClass та ландшафт після виведення з експлуатації»Контролер — це вибір реалізації, а не властивість самого API Інгресу. У старіших посібниках nginx часто фігурує як стандартний контролер, тому що ingress-nginx став спільнотним прикладом, який багато кластерів використовували роками. У 2026 році безпечніша навчальна позиція точніша: Інгрес лишається стабільним API, спільнотний контролер ingress-nginx досяг кінця життєвого циклу, а промислові кластери мають використовувати підтримуваний контролер або переносити нову роботу з HTTP-маршрутизації на Gateway API, коли платформа це підтримує.
| Контролер | Опис | Найкраще підходить для |
|---|---|---|
| nginx | Найпоширеніший, багатий на можливості | Загального використання |
| traefik | Автовиявлення, сучасний | Динамічних середовищ |
| haproxy | Висока продуктивність | Високонавантажених сайтів |
| contour | На основі Envoy | Користувачів сервісної сітки |
| AWS ALB | Нативна інтеграція з AWS | Середовищ AWS |
Для підготовки до іспиту та локальних лабораторних робіт ви все ще бачитимете приклади у стилі NGINX, бо вони роблять зв’язок між ресурсом, класом, контролером і бекендом легким для спостереження. Сприймайте ці приклади як навчальну ціль, а не як загальну рекомендацію для промислового застосування. Коли реальна організація обирає контролер для Kubernetes 1.35+, у рішенні слід враховувати статус підтримки, підтримку Gateway API, інтеграцію з хмарою, підтримку політик безпеки, спостережуваність і те, як пізніше переноситимуться анотації, специфічні для контролера.
# For kind# retired controller — lab/learning use only; see Sources for maintained alternativeskubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
# For minikubeminikube addons enable ingress
# Verify installationkubectl get pods -n ingress-nginxkubectl get svc -n ingress-nginxЦей блок встановлення корисний для контрольованих навчальних середовищ, бо дає вам конкретний контролер для дослідження. Важлива операційна деталь — не сама команда; це той факт, що контролер працює як Pod’и, відкриває Сервіс і реєструє або використовує IngressClass. Якщо учень здатен знайти ці об’єкти, він може міркувати про те, чи має кластер цикл управління та площину даних, потрібні для роботи Інгресу.
# Check podskubectl get pods -n ingress-nginx
# Check servicekubectl get svc -n ingress-nginx
# Check IngressClasskubectl get ingressclassingressClassName — це рукостискання між ресурсом Інгресу та контролером, який має його обробляти. У кластерах з одним стандартним класом пропущений клас усе ще може спрацювати, але ця звичка стає крихкою, коли на платформі є кілька контролерів. У кластері може бути один контролер для публічного інтернет-трафіку, інший — для приватного внутрішнього трафіку, а ще один — для хмарного балансувальника навантаження застосунків; некласифікований Інгрес можуть проігнорувати, його може перехопити неправильний стандартний контролер, або його відхилить політика допуску.
Проєктування маршрутизації за шляхом і хостом
Розділ «Проєктування маршрутизації за шляхом і хостом»Простий Інгрес маршрутизує один або кілька HTTP-шляхів до бекенд-Сервісів. Бекенд — це ім’я Сервісу та порт Сервісу, а не IP Pod’а, тому що Kubernetes хоче, щоб правило маршрутизації переживало заміну Pod’ів і події масштабування. Така конструкція тримає Інгрес зосередженим на рішеннях рівня 7, тоді як Сервіси продовжують виконувати стабільну роботу з балансування навантаження, про яку ви дізналися раніше в напрямку про мережі.
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: simple-ingressspec: ingressClassName: nginx # Which controller to use rules: - http: paths: - path: / pathType: Prefix backend: service: name: web-service # Target service port: number: 80 # Service portНайпростіший маршрут вище навмисно банальний: кожен HTTP-запит, який обробляє цей Інгрес, спрямовується до web-service на порт Сервісу 80. Це не заміна для селектора Сервісу або порту контейнера Pod’а. Це останній стрибок у ланцюжку: клієнт до контролера, контролер до Сервісу, Сервіс до ендпоінтів, а ендпоінти до Pod’ів.
Маршрутизація за шляхом стає корисною, коли один хост або зовнішня адреса стоїть перед кількома застосунками. Поширений патерн — поставити /api перед API-Сервісом, /web перед вебсервісом і / перед стандартним фронтендом чи цільовою сторінкою. Хитрість у тому, що правила шляхів не оцінюються як список фаєрвола згори донизу; Kubernetes визначає правила пріоритетності так, що перемагає найбільш специфічний збіг.
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: path-ingressspec: ingressClassName: nginx rules: - http: paths: - path: /api pathType: Prefix backend: service: name: api-service port: number: 80 - path: /web pathType: Prefix backend: service: name: web-service port: number: 80 - path: / pathType: Prefix backend: service: name: default-service port: number: 80┌────────────────────────────────────────────────────────────────┐│ Path-Based Routing ││ ││ Request: http://mysite.com/api/users ││ │ ││ ▼ ││ ┌────────────────────────────────────────────────────────┐ ││ │ Ingress │ ││ │ │ ││ │ /api/* ──────────► api-service │ ││ │ /web/* ──────────► web-service │ ││ │ /* ──────────► default-service │ ││ │ │ ││ └────────────────────────────────────────────────────────┘ ││ │└────────────────────────────────────────────────────────────────┘| PathType | Поведінка | Приклад |
|---|---|---|
Exact | Лише точний збіг | /api збігається з /api, але не з /api/ |
Prefix | Збіг за префіксом | /api збігається з /api, /api/users |
ImplementationSpecific | Вирішує контролер | Залежить від контролера |
Prefix зазвичай зручний вибір для CKA, бо він покриває і базовий шлях, і дочірні шляхи. Exact цінний, коли один ендпоінт треба ізолювати від сусідніх шляхів, наприклад /healthz або callback-маршрут, який не повинен збігатися з /healthz/debug. ImplementationSpecific може відкрити поведінку, специфічну для контролера, зокрема збіги в стилі регулярних виразів у деяких контролерах, але він обмінює переносність на потужність, і його варто використовувати лише тоді, коли ви знаєте, який контролер оброблятиме ресурс.
Зупиніться й передбачте: у вас є два правила шляхів Інгресу — /api з pathType: Prefix і /api/v1 з pathType: Exact. Надходить запит на /api/v1/users, а другий запит надходить на /api/v1; яке правило обробляє кожен запит? Довший точний шлях обробляє лише /api/v1, тоді як /api/v1/users повертається до префікса /api, який у цьому прикладі є єдиним префіксом, що збігається з /api/v1/users.
Маршрутизація за хостом, яку також називають віртуальним хостингом, використовує HTTP-заголовок Host для вибору бекенду. Це та сама ідея, що дозволяє одному вебсерверу розміщувати кілька вебсайтів на одній IP-адресі. У Kubernetes вона дозволяє одному Сервісу контролера приймати трафік для api.example.com та web.example.com, спрямовуючи кожне ім’я хоста до іншого внутрішнього Сервісу.
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: virtual-host-ingressspec: ingressClassName: nginx rules: - host: api.example.com http: paths: - path: / pathType: Prefix backend: service: name: api-service port: number: 80 - host: web.example.com http: paths: - path: / pathType: Prefix backend: service: name: web-service port: number: 80┌────────────────────────────────────────────────────────────────┐│ Host-Based Routing ││ ││ api.example.com ──────────► api-service ││ web.example.com ──────────► web-service ││ *.example.com ──────────► default-service (if configured) ││ │└────────────────────────────────────────────────────────────────┘Правила за хостом і за шляхом чисто компонуються, коли вам потрібна форма реального застосунку. Одне ім’я хоста може маршрутизувати /api до бекенд-API, а / — до фронтенду, тоді як інше ім’я хоста маршрутизує все до адміністративного застосунку. Саме тут Інгрес починає відчуватися як невеликий HTTP-маршрутизатор, а не як проста ручка для відкриття доступу.
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: combined-ingressspec: ingressClassName: nginx rules: - host: app.example.com http: paths: - path: /api pathType: Prefix backend: service: name: api-service port: number: 80 - path: / pathType: Prefix backend: service: name: web-service port: number: 80 - host: admin.example.com http: paths: - path: / pathType: Prefix backend: service: name: admin-service port: number: 80Перед запуском цього в лабораторній роботі, який вивід ви очікуєте від kubectl describe ingress, якщо імена бекенд-Сервісів існують, але жоден Pod не збігається з селекторами Сервісів? Правило Інгресу все ще може виглядати дійсним, бо воно вказує на Сервіси, тоді як власне шлях запиту зазнає невдачі пізніше, тому що Сервіси не мають ендпоінтів.
Термінація TLS та поведінка, специфічна для контролера
Розділ «Термінація TLS та поведінка, специфічна для контролера»Термінація TLS — це точка, де зашифрований HTTPS-трафік стає розшифрованим HTTP-трафіком. За типового налаштування Інгресу клієнт спілкується з контролером через HTTPS, контролер пред’являє сертифікат із Secret’а типу TLS у Kubernetes, а контролер перенаправляє звичайний HTTP до бекенд-Сервісу всередині кластера. Деякі середовища також шифрують стрибок до бекенду, але це не частина базового контракту Інгресу й залежить від можливостей контролера чи політики сервісної сітки.
# Generate self-signed certificate (for testing)# self-signed, no SAN — modern curl needs --insecure (lab/testing only)openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout tls.key -out tls.crt \ -subj "/CN=example.com"
# Create secretkubectl create secret tls example-tls --cert=tls.crt --key=tls.keyЦей Secret має перебувати в тому самому просторі імен, що й Інгрес. Це правило простору імен — не примха контролера; це частина того, як API Інгресу посилається на Secret’и. Якщо ви створите example-tls у default, а Інгрес у production, контролер не зможе використати цей Secret через посилання в Інгресі, і ви можете побачити стандартний сертифікат або помилку TLS — залежно від контролера.
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: tls-ingressspec: ingressClassName: nginx tls: - hosts: - example.com - www.example.com secretName: example-tls # TLS secret name rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: web-service port: number: 80┌────────────────────────────────────────────────────────────────┐│ TLS Termination ││ ││ Client (HTTPS) ││ │ ││ │ TLS/SSL encrypted ││ ▼ ││ ┌─────────────────────────────────────────────────────────┐ ││ │ Ingress Controller │ ││ │ (TLS terminates here) │ ││ │ │ ││ │ Uses certificate from Secret: example-tls │ ││ └─────────────────────────────────────────────────────────┘ ││ │ ││ │ Plain HTTP (inside cluster) ││ ▼ ││ ┌──────────────────┐ ││ │ Service │ ││ │ (port 80) │ ││ └──────────────────┘ ││ │└────────────────────────────────────────────────────────────────┘Анотації — це місце, де Інгрес стає потужним і заплутаним. API Інгресу Kubernetes визначає хости, шляхи, TLS, стандартні бекенди та посилання на бекенди, але він не стандартизує кожну поведінку проксі, на яку розраховують команди. Тому контролери відкривають такі можливості, як перенаправлення, переписування, тайм-аути, обмеження частоти запитів і CORS, через анотації, а це означає, що YAML може стати прив’язаним до однієї реалізації контролера.
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: annotated-ingress annotations: # Rewrite URL path nginx.ingress.kubernetes.io/rewrite-target: /
# SSL redirect nginx.ingress.kubernetes.io/ssl-redirect: "true"
# Timeouts nginx.ingress.kubernetes.io/proxy-connect-timeout: "30" nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
# Rate limiting nginx.ingress.kubernetes.io/limit-rps: "10"
# CORS nginx.ingress.kubernetes.io/enable-cors: "true"spec: ingressClassName: nginx rules: - http: paths: - path: / pathType: Prefix backend: service: name: web-service port: number: 80Переписування URL — класичний приклад цього компромісу переносності. Бекенд може віддавати /dashboard, тоді як публічна URL-адреса має бути /app/dashboard; без переписування бекенд отримує публічний префікс і може повернути коректну 404 на рівні застосунку. Анотація нижче показує стиль, специфічний для контролера, з яким стикається багато учнів, тоді як Gateway API пізніше дає вам більш переносний спосіб виразити подібну поведінку через фільтри.
# Route /app/(.*) to backend /($1)apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: rewrite-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /$1spec: ingressClassName: nginx rules: - http: paths: - path: /app/(.*) pathType: ImplementationSpecific backend: service: name: web-service port: number: 80Зупиніться й подумайте: ваш Інгрес обслуговує і api.example.com, і web.example.com, і ви хочете HTTPS для обох з різними сертифікатами. Вам потрібні два Secret’и типу TLS, якщо сертифікати різні; обидва Secret’и мають бути в тому самому просторі імен, що й Інгрес, який на них посилається; а термінація відбувається на контролері, якщо ви навмисно не налаштуєте іншу модель шифрування бекенду.
Діагностика збоїв маршрутизації Інгресу
Розділ «Діагностика збоїв маршрутизації Інгресу»Налагодження Інгресу найкраще працює, коли ви проходите шлях запиту по порядку, а не дивитеся лише на маніфест Інгресу. Почніть з того, чи обробив контролер ресурс, потім перевірте, чи може контролер дістатися Сервісу, потім перевірте, чи має Сервіс ендпоінти, і лише тоді досліджуйте поведінку на рівні застосунку. Більшість невдач на іспиті вкладаються в один із цих кроків, і більшість промислових інцидентів виграють від тієї самої дисципліни.
Ingress Not Working? │ ├── kubectl get ingress (check ADDRESS) │ │ │ ├── No ADDRESS → Controller not processing │ │ Check IngressClass │ │ │ └── Has ADDRESS → Continue debugging │ ├── kubectl describe ingress (check events) │ │ │ └── Errors? → Fix configuration │ ├── Check backend service │ kubectl get svc,endpoints │ │ │ └── No endpoints? → Service has no pods │ ├── Check Ingress controller logs │ kubectl logs -n ingress-nginx <controller-pod> │ └── Test from inside cluster kubectl run test --rm -i --image=curlimages/curl -- \ curl -s <service># List ingresseskubectl get ingresskubectl get ing # Short form
# Describe ingresskubectl describe ingress my-ingress
# Get ingress YAMLkubectl get ingress my-ingress -o yaml
# Check IngressClasskubectl get ingressclass
# Check Ingress controller podskubectl get pods -n ingress-nginx
# View controller logskubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx| Симптом | Причина | Розв’язання |
|---|---|---|
| Не призначено ADDRESS | Немає Інгрес-контролера | Встановіть інгрес-контролер |
| ADDRESS призначено, але 404 | Шлях не збігається | Перевірте path і pathType |
| 503 Service Unavailable | Немає ендпоінтів | Перевірте селектор сервісу / pod’и |
| Помилка SSL | Неправильний/відсутній TLS-secret | Переконайтеся, що secret існує й відповідає хосту |
| Неправильний IngressClass | Кілька контролерів | Вкажіть правильний ingressClassName |
Порожнє поле ADDRESS зазвичай означає, що контролер не перехопив і не узгодив Інгрес. Причиною може бути відсутній контролер, неправильний ingressClassName, клас, що вказує на інший контролер, або контролер, якому бракує дозволу оновлювати статус. 404 зазвичай означає, що контролер живий, але запит не збігся з тією комбінацією хоста й шляху, на яку ви очікували. 503 зазвичай означає, що маршрут збігся, але бекенд-Сервіс не має придатних ендпоінтів.
Стандартні бекенди корисні, коли ви хочете, щоб незбіжні запити потрапляли кудись навмисно. Без стандартного бекенду незбіжний хост чи шлях зазвичай отримує власну стандартну відповідь контролера. Зі стандартним бекендом ви можете повернути брендовану сторінку помилки, сервіс-перехоплювач або контрольовану відповідь, яка допомагає експлуатації розрізняти «контролер працює» і «маршрут не налаштовано».
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: default-backend-ingressspec: ingressClassName: nginx defaultBackend: # Catch-all service: name: default-service port: number: 80 rules: - host: api.example.com http: paths: - path: / pathType: Prefix backend: service: name: api-service port: number: 80Сценарій вправи: ви застосовуєте Інгрес з ingressClassName: nginx, kubectl get ingress показує адресу, а /api/users повертає сторінку фронтенду. Найкраща перша перевірка — не лічильник перезапусків Pod’а контролера; це те, чи використовує шлях /api Prefix, чи існує більш специфічне правило для цього імені хоста і чи містить запит заголовок хоста, що збігається з правилом, яке ви, на вашу думку, тестуєте.
Покроковий розбір запиту
Розділ «Покроковий розбір запиту»Уявіть запит на https://app.example.com/api/users, що входить у кластер через зовнішній балансувальник навантаження перед контролером. DNS уже розв’язав ім’я хоста в публічну адресу контролера, і клієнт тепер відкриває TLS-з’єднання з цим контролером. У цей момент Сервіси Kubernetes для api та web не видимі клієнту; клієнт бачить лише ендпоінт, відкритий Сервісом контролера.
Контролер отримує TLS-рукостискання й добирає сертифікат, використовуючи запитане ім’я сервера та записи tls.hosts зі збіжних ресурсів Інгресу. Якщо Secret сертифіката існує в правильному просторі імен і містить придатний матеріал сертифіката, контролер може завершити рукостискання. Якщо Secret неправильний, збій усе одно стається до того, як будь-який Сервіс чи Pod отримає трафік, — ось чому помилки TLS не повинні відразу спрямовувати вас до налагодження Деплойменту.
Після термінації TLS контролер читає рядок HTTP-запиту й заголовки. Заголовок Host вирішує, яке правило хоста є придатним, а шлях вирішує, який бекенд під цим хостом має отримати запит. Цей порядок важливий, тому що /api під app.example.com відрізняється від /api під admin.example.com; шлях, який виглядає правильним в одному блоці хоста, нічого не робить для запиту, що несе інше значення хоста.
Для pathType: Prefix Kubernetes у звичайному випадку визначає елементи шляху, а не наївний строковий префікс. Маршрут для /api має збігатися з /api та /api/users, але ви все одно маєте бути точними, коли з’являються кінцеві слеші або схоже названі шляхи. Маршрут для /api не слід трактувати як випадковий збіг для кожного шляху застосунку, який просто починається з тих самих літер, і документацію контролера варто почитати, коли поведінка стає тонкою.
Щойно правило збіглося, контролер перенаправляє запит до названого Сервісу й порту. Саме тут руйнується багато неправильних ментальних моделей. Бекенд Інгресу не вказує на Деплоймент, ReplicaSet чи селектор міток Pod’а; він вказує на Сервіс, а Сервіс уже вказує на ендпоінти, отримані з дібраних Pod’ів, готових достатньо, щоб приймати трафік.
Це розділення дає вам чисту послідовність усунення несправностей. Якщо правило Інгресу називає api на порту 80, почніть з підтвердження того, що Сервіс на ім’я api існує в тому самому просторі імен і відкриває порт 80. Потім підтвердьте, що селектор Сервісу збігається з потрібними Pod’ами. Нарешті підтвердьте, що Pod’и запущені й готові, бо Сервіс без ендпоінтів — поширена причина відповідей «маршрут збігся, але бекенд недоступний».
Шлях відповіді проходить у зворотному напрямку, але важливі межі відповідальності залишаються тими самими. Код застосунку володіє статусом і тілом відповіді після того, як запит досягає Pod’а. Сервіс володіє добором ендпоінтів. Контролер володіє HTTP-збігами, термінацією TLS та поведінкою проксі. Зовнішній балансувальник навантаження або NodePort володіє першою точкою входу в мережу до контролера.
Ця модель меж допомагає інтерпретувати коди стану. Сповіщення TLS зазвичай указує на добір сертифіката, форму Secret’а чи довіру клієнта. Згенерована контролером 404 зазвичай указує на незбіжні правила хоста чи шляху. 503 зазвичай указує на недоступний бекенд після того, як маршрут збігся. Згенерована бекендом 404 зазвичай означає, що запит дійшов до застосунку, але застосунок не розпізнав отриманий шлях.
Під час переписування чи відрізання префіксів будьте особливо уважні, щоб визначити, який компонент створив 404. Якщо контролер ніколи не збігав маршрут, анотації переписування не допоможуть, бо запит не дійшов до цього правила. Якщо бекенд отримав /app/dashboard, а очікував /dashboard, переписування може допомогти, але тепер ваша переносність залежить від обраного контролера та точної семантики його анотацій.
Ось чому curl-тести мають включати заголовок хоста, коли DNS не налаштовано. Тестування curl http://controller-ip/api без -H "Host: app.example.com" не задіює те саме правило, що й реальний запит браузера для app.example.com. На іспитових лабораторних роботах локальні кластери часто полегшують про це забути, бо все начебто досяжне через localhost, але рішення HTTP-маршрутизації все одно залежать від значення хоста.
Та сама дисципліна застосовується, коли кілька ресурсів Інгресу спільно використовують ім’я хоста. Контролери зазвичай об’єднують маршрути для одного хоста відповідно до своєї реалізації, а конфлікти можуть бути відхилені, про них можуть попередити або їх можуть розв’язати правилами пріоритетності. Для навчання та іспитової роботи тримайте пов’язані правила в одному маніфесті, коли можливо, щоб ви могли бачити повну форму хоста й шляху в одному виводі kubectl describe ingress.
Простори імен додають ще одну межу, яку легко не помітити. Посилання бекенд-Сервісу в Інгресі прив’язане до простору імен, тож маршрут вказує на Сервіси в тому самому просторі імен, що й Інгрес. Посилання Secret’а типу TLS також прив’язане до простору імен. Якщо платформним командам потрібні моделі прив’язки між просторами імен, їм слід оцінити Gateway API, бо він має явні концепції делегування та дозволу на посилання, замість того щоб покладатися на випадкові припущення про роботу між просторами імен.
Готовність до промислової експлуатації та нотатки про перехід
Розділ «Готовність до промислової експлуатації та нотатки про перехід»Інгрес досі варто вивчати глибоко, бо багато кластерів роками виконуватимуть маніфести Інгресу, навіть коли нові архітектури рухаються в бік Gateway API. Промисловому оператору потрібно відрізняти «API застаріле» від «конкретний контролер виведено з експлуатації», бо ці твердження ведуть до різних дій. Перше вимагало б негайно замінити модель ресурсу, тоді як друге вимагає переглянути підтримку контролера, час переходу та залежність від анотацій.
Виведення з експлуатації спільнотного ingress-nginx ставить це розрізнення прямо. Наявні кластери все ще можуть містити багато ресурсів Інгресу, які є дійсними об’єктами API Kubernetes, але контролер площини даних за ними може більше не отримувати підтримки. Це означає, що план переходу має інвентаризувати Деплойменти контролерів, IngressClass’и, анотації, вебхуки допуску, кастомні сніпети, автоматизацію TLS та операційні дашборди, а не просто рахувати об’єкти Інгресу.
Gateway API покращує кілька сфер, які Інгрес розтягував через анотації. Він відокремлює слухачів, що належать інфраструктурі, від маршрутів, що належать застосункам, моделює більше поведінки маршрутизації як повноцінні поля й надає чіткіші патерни прив’язки між просторами імен. Це не робить кожен Інгрес терміновим для заміни, але означає, що нова робота над платформою має обґрунтовувати, чому вона обирає Інгрес, а не за замовчуванням переходить до новішої моделі маршрутизації.
Для цілей CKA зосередьтеся на стабільних поведінках Інгресу, які переносяться між контролерами: вибір класу, правила хостів, правила шляхів, бекенд-Сервіси, посилання на Secret’и типу TLS та базове усунення несправностей. Не намагайтеся запам’ятати кожну анотацію від одного контролера. Іспит очікує, що ви застосуєте основні концепції мереж Kubernetes, а можливості, специфічні для контролера, радше з’являться як контекстні підказки, ніж як головна навчальна ціль.
Для проєктування платформи анотації заслуговують на мітку переходу. Маршрут, який лише встановлює ssl-redirect, може бути легким для відтворення деінде, тоді як маршрут, що використовує шляхи з регулярними виразами, складні переписування, кастомні сніпети та обмеження частоти, може потребувати ретельного перекладу. Маршрут із найбільшою кількістю анотацій часто є тим маршрутом, який власникам застосунку видається простим, але несе найбільше прихованої зв’язаності з платформою.
Керування сертифікатами також змінюється з масштабом. Самопідписаний сертифікат, створений через openssl, годиться для лабораторії, але промислові сертифікати слід запитувати, поновлювати й розповсюджувати засобами автоматизації. Якщо платформа використовує cert-manager, автоматизацію зовнішнього DNS чи хмарні менеджери сертифікатів, маніфест Інгресу стає однією частиною більшого ланцюжка, а налагодження має включати статус емітента, DNS-записи та логи подій контролера.
Контроль доступу — ще одна промислова відмінність. У спільному кластері не кожному простору імен слід дозволяти створювати маршрути, доступні з інтернету, обирати будь-який IngressClass чи долучати довільні анотації. Політики допуску можуть вимагати схвалених імен класів, блокувати небезпечні патерни анотацій, забезпечувати дотримання правил іменування хостів і вимагати TLS для публічних хостів. Ці засоби контролю перетворюють правила маршрутизації з окремих рішень у YAML на політику платформи.
Спостережуваність слід планувати до першого збою. Контролер має відкривати метрики для частоти запитів, кодів відповідей, затримки, перезавантажень конфігурації та відхилених ресурсів. Логи мають дозволяти операторам відрізняти незбіжний маршрут від збою висхідного потоку (upstream). Команди застосунків мають знати, чи можуть вони бачити логи доступу контролера, чи ними під час інциденту володіє платформна команда.
Планування ємності теж належить до рівня контролера. Один спільний контролер може спростити зовнішнє відкриття доступу, але він також може стати спільним вузьким місцем, якщо нехтувати запитами ресурсів, автомасштабуванням та налаштуваннями балансувальника навантаження. Висока доступність зазвичай означає кілька реплік контролера, бюджети на порушення роботи (disruption budgets), ретельне розміщення на вузлах і достатню перевірку справності балансувальника навантаження, щоб не надсилати трафік до зламаного проксі.
Бекенд-Сервіси все ще мають значення, коли контролер справний. Якщо проби готовності надто суворі, Деплоймент може мати запущені Pod’и, але не мати ендпоінтів, через що трафік зі збіглим маршрутом зазнає невдачі. Якщо проби готовності надто слабкі, Сервіс може надсилати трафік до Pod’ів, які насправді не готові. Налагодження Інгресу часто виявляє проблеми готовності застосунку, бо HTTP-трафік концентрується через видиму точку входу.
Володіння шляхами слід записувати для спільних імен хостів. Якщо одна команда володіє /api, а інша — /api/admin, командам потрібна домовленість про пріоритетність, переписування, автентифікацію та порядок розгортання. Інакше нешкідливий на вигляд маршрут може затінити більш специфічний маршрут або змінити шлях, який отримує бекенд. Межі «один хост на продукт» часто легше експлуатувати, бо володіння видиме в DNS і сертифікатах.
Стандартні бекенди корисні, але вони мають бути навмисними. Стандартний бекенд, що повертає узагальнену сторінку успіху, може приховати відсутню конфігурацію маршрутів, роблячи кожен незбіжний запит здоровим на вигляд. Краща стандартна відповідь пояснює, що жоден маршрут не збігся, встановлює чіткий код стану й дає операторам достатньо інформації, щоб визначити, чи отримав контролер запит. У промисловій експлуатації спостережуваність важливіша за гарну запасну сторінку.
Порівнюючи Інгрес і Gateway API, не формулюйте вибір лише як «старе проти нового». Практичне питання — хто володіє слухачем, хто володіє маршрутом, наскільки переносною має бути поведінка та скільки можливостей, специфічних для контролера, уже використовується. Невеликий наявний Інгрес з одним хостом і одним Сервісом може не заслуговувати на терміновий перехід, тоді як нова спільна платформа має рішуче віддавати перевагу чіткішій моделі володіння Gateway API.
Для іспиту практикуйте написання нудного правильного маніфесту, перш ніж тягнутися до просунутої поведінки. Установіть клас, установіть хост, коли потрібно, обирайте Prefix чи Exact навмисно, коректно посилайтеся на порт Сервісу та перевіряйте ендпоінти, перш ніж винуватити контролер. Ця рутина розв’язує більше збоїв, ніж запам’ятовування рідкісних анотацій, і вона дає вам надійний запасний варіант, коли тиск часу робить складне налагодження спокусливим.
Остання операційна звичка — тримати тести маршрутів реалістичними. Включайте заголовок хоста, використовуйте правильну схему, тестуйте точний шлях і знайте, чи тестуєте ви ззовні кластера, з вузла чи з тимчасового Pod’а. Кожне місце обходить або включає різні частини шляху запиту. Успішний внутрішньокластерний curl до Сервісу доводить, що бекенд працює, але він не доводить TLS, збіг хоста чи поведінку зовнішнього балансувальника навантаження.
Читання маніфестів Інгресу під тиском іспиту
Розділ «Читання маніфестів Інгресу під тиском іспиту»Коли ви читаєте маніфест Інгресу під час CKA, переглядайте його в тому самому порядку, у якому його використовує запит. Почніть з ingressClassName, бо чудово написаний маршрут інертний, якщо його не обробляє жоден збіжний контролер. Потім перегляньте tls на предмет покриття хостів та імен Secret’ів. Нарешті прочитайте кожне правило хоста й шляху, перевіривши, що кожне ім’я та порт бекенд-Сервісу може існувати в тому самому просторі імен, що й Інгрес.
Порт бекенду заслуговує на навмисну паузу. Kubernetes дозволяє Сервісу відкривати один порт, перенаправляючи на інший цільовий порт на Pod’ах, а бекенд Інгресу посилається на порт Сервісу. Якщо Деплоймент слухає на порту контейнера 8080, Сервіс відкриває порт 80, а Інгрес указує на порт 8080, маршрут може зазнати невдачі, бо Сервіс не відкриває цей номер порту.
Читайте маніфест і на предмет прихованих припущень про контролер. Ключ анотації, що починається з nginx.ingress.kubernetes.io, говорить вам, що маніфест очікує поведінку, сумісну з NGINX, а не загальну поведінку Інгресу. Майбутній контролер може проігнорувати цю анотацію або інтерпретувати схожу можливість інакше. На іспиті ця підказка допомагає вам зрозуміти задуману поведінку; у промисловій експлуатації вона стає інвентарем для переходу.
Імена хостів мають змусити вас запитати, як сформовано тестовий запит. Якщо правило Інгресу каже host: api.example.com, то curl до IP-адреси без заголовка хоста — не достовірний тест. Контролер бачить значення HTTP-хоста, а не коментар, який ви тримали в думці. Ось чому багато локальних тестів використовують curl -H "Host: api.example.com", поки DNS усе ще відсутній.
Для правил шляхів перевірте, чи потрібні родині маршрутів дочірні шляхи. Маршрут фронтенду для / з Prefix широкий за задумом, тож будь-який більш специфічний маршрут має бути достатньо правильним, щоб його перемогти. Якщо /api/users провалюється до /, проблема зазвичай у шляху Exact, незбігу хоста або в тестовому запиті, який ніколи не дійшов до потрібного блоку хоста.
Описи та події швидші за здогадки. kubectl describe ingress зазвичай показує правила в компактній формі, клас, адресу й нещодавні події контролера. Якщо контролер відхилив правило, не зміг знайти Сервіс чи мав проблеми із завантаженням Secret’а типу TLS, потік подій може дати вам пряму підказку. Сприймайте вивід describe як міст між наміром YAML і узгодженням контролера.
Логи контролера додають деталей, коли подій недостатньо, але вони не повинні бути першою зупинкою для кожного збою. Логи можуть бути галасливими, особливо на спільних контролерах, що обслуговують багато просторів імен. Спочатку звузьте проблему за допомогою об’єкта Інгресу, Сервісу, ендпоінтів і реалістичного curl-тесту. Потім використовуйте логи, щоб підтвердити, чи контролер збіг маршрут, дібрав висхідний потік чи сам згенерував відповідь.
Інспекція ендпоінтів — найкоротший шлях через багато збоїв 503. Сервіс може існувати, мати правильний порт і все одно не мати готових ендпоінтів, бо мітки Pod’а не збігаються, проби готовності зазнають невдачі або Деплоймент не розгорнувся. У цьому випадку редагування Інгресу лише додає метушні. Виправте проблему доступності бекенду, потім перетестуйте той самий маршрут, не змінюючи правило маршрутизації.
Збої TLS заслуговують на власну гілку у вашому ментальному чекліст. Підтвердьте, що тип Secret’а — kubernetes.io/tls, що Secret містить дані сертифіката й ключа, і що Secret у тому самому просторі імен, що й Інгрес. Потім підтвердьте, що хост у секції TLS збігається з іменем хоста, яке клієнти насправді використовують. Сертифікат для неправильного імені може виглядати як збій Інгресу, навіть коли маршрутизація в іншому коректна.
Нарешті пам’ятайте, що Інгрес — це один рівень у довшому ланцюжку. DNS, хмарні балансувальники навантаження, мережа вузлів, Pod’и контролера, правила Інгресу, Сервіси, EndpointSlice’и, готовність Pod’ів та маршрутизація застосунку — усе бере участь у фінальному досвіді користувача. Практична навичка — не вгадувати правильний рівень за інстинктом; це проходити ланцюжок достатньо швидко, щоб кожне спостереження одразу відкидало кілька хибних теорій.
Найбезпечніша стратегія на іспиті — тримати ваш перший маніфест консервативним. Уникайте необов’язкових анотацій, доки не запрацює потрібний маршрут, використовуйте Prefix лише там, де родині маршрутів потрібні дочірні шляхи, і тримайте правила хостів очевидними. Щойно основний маршрут стане справним, додавайте TLS чи переписування по одній зміні за раз, щоб наступний збій мав малий простір пошуку.
У промисловій експлуатації та сама звичка стає керуванням змінами. Зміна маршруту, зміна сертифіката та зміна переписування в одному pull request можуть зробити відкат неясним, бо будь-яке з цих редагувань може змінити поведінку, видиму користувачу. Менші зміни маршрутів легше переглядати, легше тестувати реалістичними curl-командами та легше повертати назад, якщо контролер прийме маніфест, але трафік поведеться несподівано.
Якщо ви запам’ятаєте лише одне речення про налагодження, нехай це буде воно: відсутня адреса вказує на узгодження контролера чи класу, 404 вказує на збіг хоста й шляху, а 503 вказує на збіглі маршрути з недоступними бекендами. Цей скорочений запис не замінює доказів, але дає вам швидку стартову гіпотезу, яка чисто лягає на об’єкти Kubernetes, які ви можете дослідити.
Патерни та антипатерни
Розділ «Патерни та антипатерни»Патерни Інгресу менше про запам’ятовування YAML і більше про те, щоб зробити володіння маршрутизацією явним. Хороший патерн дозволяє команді застосунку випустити маршрут, не захопивши випадково ім’я хоста іншої команди, тоді як хороший платформний патерн дозволяє адміністраторам кластера змінювати контролери, не переписуючи кожен застосунок з нуля. Таблиця нижче зосереджена на рішеннях, які ви можете обґрунтувати в поясненні на іспиті та в огляді архітектури.
| Патерн | Коли використовувати | Чому працює | Міркування щодо масштабування |
|---|---|---|---|
Один спільний контролер з явним ingressClassName | Кільком командам потрібна HTTP-маршрутизація через одну точку входу платформи | Кожен Інгрес каже, який контролер ним володіє, уникаючи випадкової стандартної поведінки | Додайте політику допуску чи шаблони, щоб команди не пропускали клас |
| Маршрутизація за хостом для меж застосунку | Різним застосункам потрібні незалежні DNS-імена | Імена хостів створюють чисте володіння й уникають зв’язаності через префікс шляху | Автоматизація сертифікатів стає важливою, коли кількість хостів зростає |
| Маршрутизація за шляхом усередині однієї поверхні продукту | Один публічний застосунок має кілька внутрішніх бекендів | Користувачі бачать одне ім’я хоста, тоді як сервіси лишаються розгортуваними окремо | Документуйте володіння префіксами, щоб команди не зіткнулися на /api чи /admin |
| Secret’и типу TLS, керовані автоматизацією | Сертифікати регулярно ротуються або існує багато хостів | Ручна заміна Secret’ів стає операційним ризиком | Використовуйте cert-manager чи платформні засоби з чіткими правилами просторів імен |
Головний антипатерн — трактувати анотації як нешкідливе оздоблення. Анотація на кшталт правила переписування, перенаправлення чи тайм-ауту може змінити семантику запиту так само, як і правило маршруту. Якщо ці анотації прив’язані до одного контролера, їх слід задокументувати як поведінку, специфічну для реалізації, і вважати роботою з переходу, коли організація оцінює Gateway API чи інший контролер.
| Антипатерн | Що йде не так | Краща альтернатива |
|---|---|---|
Пропуск ingressClassName у кластерах з кількома контролерами | Жоден контролер не перехоплює маршрут, або це робить неправильний стандартний контролер | Вимагайте явних імен класів у маніфестах і політиці |
| Поставити один непов’язаний флот за префіксами шляхів | Бекенди стають зв’язаними з публічною структурою шляхів, а переписувань стає більше | Віддавайте перевагу маршрутизації за хостом, коли продукти мають окреме володіння |
| Зберігати Secret типу TLS в іншому просторі імен | Інгрес не може послатися на сертифікат | Тримайте Secret поруч з Інгресом або використовуйте механізми Gateway API для роботи між просторами імен, де доречно |
Використовувати ImplementationSpecific для звичайних префіксів | Поведінка змінюється, коли змінюються контролери | Використовуйте Prefix чи Exact, доки не потрібна можливість, специфічна для контролера |
Рамка для прийняття рішень
Розділ «Рамка для прийняття рішень»Обирайте Інгрес, коли задача маршрутизації — це HTTP чи HTTPS, кластер уже має підтримуваний контролер, а потрібні можливості вкладаються в стабільний API Інгресу плюс невелику кількість прийнятих анотацій. Обирайте Сервіс типу LoadBalancer, коли робоче навантаження не обізнане з HTTP або заслуговує на власний виділений ендпоінт L4. Обирайте Gateway API для нових архітектур платформи, яким потрібні багатші й краще переносні можливості маршрутизації, окреме володіння інфраструктурою та застосунками або чистіше делегування між просторами імен.
| Питання | Віддайте перевагу цьому | Причина |
|---|---|---|
| Вам потрібен TCP чи UDP без рішень за HTTP-хостом/шляхом? | Сервіс LoadBalancer | Інгрес HTTP-орієнтований і додає зайвий механізм рівня 7 |
| Вам потрібно багато HTTP-застосунків за однією зовнішньою точкою входу? | Ingress або Gateway API | Обидва можуть маршрутизувати за хостом і шляхом через спільну інфраструктуру |
| Ви будуєте нову платформу Kubernetes 1.35+? | Gateway API | Це наступна модель з кращим розділенням ролей і багатшими концепціями маршрутизації |
| Ви підтримуєте наявні маніфести Інгресу? | Ingress з плануванням переходу | API лишається підтримуваним, але вибір контролера й анотацій потребує перегляду |
| Ви сильно покладаєтеся на анотації, специфічні для контролера? | Оцініть зусилля на перехід | Ці анотації — центр витрат, коли контролери змінюються |
Використовуйте цю послідовність під час оглядів архітектури. По-перше, вирішіть, чи трафік обізнаний з HTTP. По-друге, вирішіть, хто володіє зовнішнім слухачем і сертифікатом. По-третє, вирішіть, чи мають правила маршрутизації бути переносними між контролерами. Нарешті вирішіть, чи має кластер уже контролер і політику, потрібні, щоб зробити обрану модель надійною.
Чи знали ви?
Розділ «Чи знали ви?»- API Інгресу перейшов на
networking.k8s.io/v1і є стабільною формою API від Kubernetes 1.19, ось чому сучасні приклади мають включатиpathTypeта структурований формат бекендуservice.name. - Виведення з експлуатації спільнотного контролера
ingress-nginxбуло оголошено керівництвом проєкту Kubernetes на березень 2026 року, але це виведення не позначило застарілим сам API Інгресу Kubernetes. - Один Інгрес може містити кілька правил хостів і кілька правил шляхів, але Secret’и типу TLS, на які посилається цей Інгрес, усе одно мають перебувати в тому самому просторі імен, що й об’єкт Інгресу.
- Збіг шляхів у Kubernetes використовує пріоритетність за найдовшим шляхом, і коли збіги
ExactтаPrefixрівні за найдовшим шляхом, перемагає збігExact.
Типові помилки
Розділ «Типові помилки»| Помилка | Чому трапляється | Як виправити |
|---|---|---|
| Створення Інгресу до того, як з’явився будь-який контролер | API приймає об’єкт, тож учні припускають, що маршрутизація існує | Установіть або визначте контролер, потім перевірте Pod’и, Сервіс і IngressClass |
Пропуск ingressClassName у спільному кластері | Локальні лабораторії часто мають один стандартний клас, що приховує залежність | Установіть spec.ingressClassName явно й підтвердьте, що він збігається з kubectl get ingressclass |
| Надсилання бекенду Інгресу на порт контейнера замість порту Сервісу | Блок бекенду каже port, тож легко думати про Pod першочергово | Зіставте бекенд Інгресу з портом Сервісу, що стоїть перед Pod’ами |
Використання Exact для шляхів, яким потрібні дочірні | /api працює у швидкому тесті, але /api/users провалюється | Використовуйте Prefix для родин маршрутів і резервуйте Exact для окремих ендпоінтів |
| Очікування, що Secret’и типу TLS працюватимуть між просторами імен | Імена Secret’ів виглядають глобальними при швидкому читанні | Створіть Secret типу TLS у тому самому просторі імен, що й Інгрес |
| Трактування 404 і 503 як одного й того самого збою | Обидва видимі користувачам як зламані сторінки | Використовуйте 404 як підказку збігу/маршрутизації, а 503 — як підказку ендпоінта бекенду |
| Копіювання анотацій, специфічних для контролера, без читання його документації | Приклади часто приховують припущення про переносність | Документуйте залежність від контролера або використовуйте можливості Gateway API, де доступно |
Тест
Розділ «Тест»Питання 1: Ваша команда запускає кілька HTTPS-вебсервісів і пропонує один Сервіс `LoadBalancer` на кожне робоче навантаження. Яку архітектуру ви порекомендуєте і про який компроміс варто згадати?
Використовуйте маршрут Інгресу чи Gateway API через спільний контролер, коли трафік — це HTTP чи HTTPS і платформі потрібна маршрутизація за хостом або шляхом. Окремий LoadBalancer на робоче навантаження може бути доречним для виділених ендпоінтів, але він збільшує кількість зовнішніх IP, вартість хмарних балансувальників навантаження, дублювання сертифікатів та операційну поверхню. Для нової платформи Kubernetes 1.35+ згадайте, що Gateway API — переважний напрямок, тоді як Інгрес лишається поширеним і підтримуваним для наявної маршрутизації.
Питання 2: Ви застосовуєте Інгрес, і `kubectl get ingress` не показує адресу через кілька хвилин. Що слід дослідити першим?
Почніть з перевірки, чи встановлено й справний Інгрес-контролер, бо API-сервер сам по собі не маршрутизує трафік. Потім дослідіть kubectl get ingressclass і порівняйте ім’я класу з spec.ingressClassName на Інгресі. Якщо контролер і клас виглядають правильними, опишіть Інгрес і дослідіть логи контролера, щоб побачити, чи контролер відхилив ресурс або чи йому бракує дозволу оновлювати статус.
Питання 3: Запити на `/api/users` повертають сторінку фронтенду, тоді як `/` призначено для фронтенду, а `/api` — для API. Яка ймовірна помилка маршрутизації?
Найімовірніша помилка в тому, що шлях /api використовує Exact, прив’язаний до іншого правила хоста або не збігається, бо тестовому запиту бракує очікуваного заголовка хоста. З pathType: Prefix /api/users має збігтися з /api й перемогти префікс /, бо Kubernetes використовує пріоритетність за найдовшим шляхом. Після перевірки типу шляху й хоста дослідіть оброблений Інгрес через kubectl describe ingress і підтвердьте ім’я та порт бекенд-Сервісу.
Питання 4: TLS-Інгрес посилається на `secretName: prod-tls`, але клієнти бачать стандартний сертифікат. Яке правило простору імен слід перевірити?
Перевірте, що prod-tls існує в тому самому просторі імен, що й об’єкт Інгресу. API Інгресу не дозволяє маршруту в одному просторі імен напряму посилатися на Secret типу TLS в іншому просторі імен. Якщо Secret відсутній, у неправильному просторі імен, неправильно сформований або не є Secret’ом типу TLS у Kubernetes, контролер може віддавати запасний сертифікат або повідомити про помилку в подіях і логах.
Питання 5: Бекенд віддає `/dashboard`, але користувачі відвідують `/app/dashboard` через Інгрес і отримують 404 застосунку. Як ви діагностуєте різницю між маршрутизацією Інгресу та маршрутизацією застосунку?
Спершу підтвердьте, чи запит досягає потрібного бекенду, перевіривши логи доступу контролера, ендпоінти Сервісу та прямий внутрішньокластерний запит до Сервісу. Якщо бекенд отримує /app/dashboard, але віддає лише /dashboard, Інгрес збігся коректно, а проблема, що лишилася, — форма URL. Анотація переписування, специфічна для контролера, може відрізати префікс /app, але це слід задокументувати, бо поведінка переписування не переносна між усіма контролерами.
Питання 6: Платформа має і публічний, і приватний Інгрес-контролери. Чому явний `ingressClassName` — частина безпекової позиції?
Явний клас не дає маршруту бути перехопленим тим контролером, що є стандартним, або жодним контролером узагалі. У розділенні на публічний/приватний клас може кодувати, чи маршрут доступний з інтернету, чи внутрішній, а це рішення про володіння інфраструктурою, а не дрібна деталь YAML. Політика допуску може вимагати дозволених імен класів, щоб команди застосунків не змогли випадково опублікувати внутрішній сервіс через публічний контролер.
Питання 7: Інгрес повертає 503 для шляху, який начебто збігається коректно. Які перевірки бекенду слід виконати перед редагуванням маршруту?
503 зазвичай означає, що контролер збіг маршрут, але не зміг дістатися справних ендпоінтів бекенду. Перевірте ім’я та порт Сервісу, на які посилається Інгрес, потім запустіть kubectl get svc,endpoints або дослідіть EndpointSlice’и для Сервісу. Якщо ендпоінтів немає, виправте селектор Сервісу, мітки Pod’а, готовність Pod’а чи справність Деплойменту, перш ніж змінювати правила шляхів.
Практична вправа
Розділ «Практична вправа»Сценарій вправи: побудуйте невелику конструкцію HTTP-маршрутизації з двома Сервісами, одним Інгресом за шляхом, одним Інгресом за хостом та одним TLS-Інгресом. Лабораторна робота передбачає навчальний кластер з Інгрес-контролером і доступним IngressClass nginx; якщо ваш кластер використовує інший підтримуваний контролер, збережіть ту саму структуру API, але замініть ім’я класу й анотації, специфічні для контролера, відповідно до документації цього контролера.
Завдання 1: Створіть бекенд-Сервіси
Розділ «Завдання 1: Створіть бекенд-Сервіси»Створіть два простих Деплойменти й відкрийте їх як Сервіси ClusterIP. Образи навмисно банальні, бо мета — поведінка маршрутизації, а не логіка застосунку. Після створення перевірте обидва Деплойменти й Сервіси, перш ніж писати будь-яке правило Інгресу, бо правильний маршрут не врятує відсутній бекенд.
# API servicekubectl create deployment api --image=nginxkubectl expose deployment api --port=80
# Web servicekubectl create deployment web --image=nginxkubectl expose deployment web --port=80kubectl get deployment api webkubectl get svc api webНотатки до розв'язання Завдання 1
Обидва Деплойменти мають показати доступні репліки після запуску образу, а обидва Сервіси мають показати TYPE як ClusterIP з портом 80. Якщо Деплойменти ще не доступні, дочекайтеся Pod’ів, перш ніж налагоджувати Інгрес. Якщо Сервіси відсутні або мають несподівані імена, пізніші посилання бекенду Інгресу спричинять заплутані збої в стилі 503.
Завдання 2: Створіть маршрутизацію за шляхом
Розділ «Завдання 2: Створіть маршрутизацію за шляхом»Створіть один Інгрес, який спрямовує /api до API-Сервісу, а / — до вебсервісу. Це найменша корисна форма маршрутизації для іспиту, бо вона змушує вас пов’язати пріоритетність шляхів, імена Сервісів, порти Сервісів та обраний IngressClass в одному маніфесті.
cat << 'EOF' | kubectl apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: multi-path-ingressspec: ingressClassName: nginx rules: - http: paths: - path: /api pathType: Prefix backend: service: name: api port: number: 80 - path: / pathType: Prefix backend: service: name: web port: number: 80EOFkubectl get ingresskubectl describe ingress multi-path-ingress# Get ingress address (fallback to localhost if no LB IP is assigned in local clusters)INGRESS_IP=$(kubectl get ingress multi-path-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}')[ -z "$INGRESS_IP" ] && INGRESS_IP="localhost"
# Test paths directly from the host node (since INGRESS_IP might be localhost)curl -s http://$INGRESS_IP/apicurl -s http://$INGRESS_IP/Нотатки до розв'язання Завдання 2
Важливий сигнал успіху — те, що Інгрес має правила, які вказують на Сервіси api та web на порту 80. У локальних кластерах значення ADDRESS може відрізнятися, тож не підлаштовуйтеся надмірно під зовнішню IP у хмарному стилі. Якщо /api зазнає невдачі, але / працює, дослідіть тип шляху й ендпоінти бекенд-Сервісу, перш ніж редагувати непов’язані налаштування TLS чи анотацій.
Завдання 3: Створіть маршрутизацію за хостом
Розділ «Завдання 3: Створіть маршрутизацію за хостом»Створіть Інгрес, що маршрутизує два різних імені хостів до двох Сервісів. Маршрутизація за хостом — найчистіший спосіб розділити володіння між застосунками, бо кожна команда може міркувати про власне DNS-ім’я, не ділячись префіксами шляхів під одним публічним сайтом.
cat << 'EOF' | kubectl apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: host-ingressspec: ingressClassName: nginx rules: - host: api.example.com http: paths: - path: / pathType: Prefix backend: service: name: api port: number: 80 - host: web.example.com http: paths: - path: / pathType: Prefix backend: service: name: web port: number: 80EOFkubectl describe ingress host-ingressНотатки до розв'язання Завдання 3
Вивід describe має показати два правила хостів, кожне з префіксом / та іншим бекенд-Сервісом. Щоб протестувати цю форму, вам потрібно надіслати правильний заголовок Host або налаштувати локальний DNS. Запит без очікуваного заголовка хоста може потрапити до стандартного бекенду, навіть коли Інгрес ідеально дійсний.
Завдання 4: Додайте термінацію TLS
Розділ «Завдання 4: Додайте термінацію TLS»Створіть самопідписаний сертифікат для практики й збережіть його як Secret типу TLS у Kubernetes. Самопідписані сертифікати — не промисловий матеріал, але вони хороші для навчання, бо дозволяють відпрацювати форму об’єкта, не покладаючись на зовнішнього емітента сертифікатів.
# self-signed, no SAN — modern curl needs --insecure (lab/testing only)openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout tls.key -out tls.crt \ -subj "/CN=example.com"
kubectl create secret tls example-tls --cert=tls.crt --key=tls.keykubectl get secret example-tlscat << 'EOF' | kubectl apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: tls-ingressspec: ingressClassName: nginx tls: - hosts: - secure.example.com secretName: example-tls rules: - host: secure.example.com http: paths: - path: / pathType: Prefix backend: service: name: web port: number: 80EOFkubectl describe ingress tls-ingressНотатки до розв'язання Завдання 4
Секція TLS має посилатися на example-tls, а Secret має бути в тому самому просторі імен, що й tls-ingress. Якщо ваш контролер віддає запасний сертифікат, перевірте тип Secret’а, простір імен, загальне ім’я сертифіката чи альтернативні імена суб’єкта (SAN) та події контролера. У промисловому кластері автоматизація сертифікатів зазвичай володіє цим Secret’ом, а не людина, що запускає openssl вручну.
Завдання 5: Прибирання та перевірка успіху
Розділ «Завдання 5: Прибирання та перевірка успіху»Приберіть ресурси лабораторної роботи після того, як ви їх дослідили. Видалення ресурсів Інгресу першими прибирає зовнішні маршрути перед видаленням бекендів, а це той самий безпечний порядок, який ви зазвичай використовуєте під час контрольованого згортання.
kubectl delete ingress multi-path-ingress host-ingress tls-ingresskubectl delete deployment api webkubectl delete svc api webkubectl delete secret example-tlsrm tls.key tls.crtКритерії успіху:
- Спроєктувати маршрутизацію Інгресу за шляхом і за хостом для двох бекенд-Сервісів.
- Налаштувати термінацію TLS з Secret’ом типу TLS у Kubernetes у правильному просторі імен.
- Оцінити, чи має кластер відповідний IngressClass і контролер для маршруту.
- Діагностувати збої маршрутизації за допомогою
kubectl describe ingress, Сервісів, Endpoint’ів та логів контролера. - Пояснити, коли Gateway API був би кращою наступною архітектурою, ніж додавання нових анотацій до Інгресу.
Хронометровані практичні дрилі
Розділ «Хронометровані практичні дрилі»Ці дрилі зберігають екзаменаційно-швидку практику з оригінального модуля. Запускайте їх лише в одноразовому просторі імен або лабораторному кластері. Вони навмисно повторюють невеликі форми маршрутизації, щоб ви могли швидко писати правильні маніфести, водночас пояснюючи, чому маршрут має працювати.
Дриль 1: Базовий Інгрес
Розділ «Дриль 1: Базовий Інгрес»# Create servicekubectl create deployment drill-app --image=nginxkubectl expose deployment drill-app --port=80
# Create Ingresscat << 'EOF' | kubectl apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: drill-ingressspec: ingressClassName: nginx rules: - http: paths: - path: / pathType: Prefix backend: service: name: drill-app port: number: 80EOF
# Checkkubectl get ingress drill-ingresskubectl describe ingress drill-ingress
# Cleanupkubectl delete ingress drill-ingresskubectl delete deployment drill-appkubectl delete svc drill-appДриль 2: Інгрес з кількома шляхами
Розділ «Дриль 2: Інгрес з кількома шляхами»# Create serviceskubectl create deployment api --image=nginxkubectl create deployment web --image=nginxkubectl expose deployment api --port=80kubectl expose deployment web --port=80
# Create Ingresscat << 'EOF' | kubectl apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: multi-pathspec: ingressClassName: nginx rules: - http: paths: - path: /api pathType: Prefix backend: service: name: api port: number: 80 - path: / pathType: Prefix backend: service: name: web port: number: 80EOF
# Verifykubectl describe ingress multi-path
# Cleanupkubectl delete ingress multi-pathkubectl delete deployment api webkubectl delete svc api webДриль 3: Інгрес за хостом
Розділ «Дриль 3: Інгрес за хостом»# Create serviceskubectl create deployment app1 --image=nginxkubectl create deployment app2 --image=nginxkubectl expose deployment app1 --port=80kubectl expose deployment app2 --port=80
# Create Ingresscat << 'EOF' | kubectl apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: host-basedspec: ingressClassName: nginx rules: - host: app1.example.com http: paths: - path: / pathType: Prefix backend: service: name: app1 port: number: 80 - host: app2.example.com http: paths: - path: / pathType: Prefix backend: service: name: app2 port: number: 80EOF
# Verifykubectl get ingress host-basedkubectl describe ingress host-based
# Cleanupkubectl delete ingress host-basedkubectl delete deployment app1 app2kubectl delete svc app1 app2Дриль 4: TLS-Інгрес
Розділ «Дриль 4: TLS-Інгрес»# Create servicekubectl create deployment secure-app --image=nginxkubectl expose deployment secure-app --port=80
# Generate certificate# self-signed, no SAN — modern curl needs --insecure (lab/testing only)openssl req -x509 -nodes -days 1 -newkey rsa:2048 \ -keyout tls.key -out tls.crt -subj "/CN=secure.local"
# Create secretkubectl create secret tls tls-secret --cert=tls.crt --key=tls.key
# Create Ingress with TLScat << 'EOF' | kubectl apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: tls-ingressspec: ingressClassName: nginx tls: - hosts: - secure.local secretName: tls-secret rules: - host: secure.local http: paths: - path: / pathType: Prefix backend: service: name: secure-app port: number: 80EOF
# Verifykubectl describe ingress tls-ingress
# Cleanupkubectl delete ingress tls-ingresskubectl delete deployment secure-appkubectl delete svc secure-appkubectl delete secret tls-secretrm tls.key tls.crtДриль 5: Перевірка IngressClass
Розділ «Дриль 5: Перевірка IngressClass»# List IngressClasseskubectl get ingressclass
# Describekubectl describe ingressclass nginx
# Check which is defaultkubectl get ingressclass -o jsonpath="{range .items[*]}{.metadata.name}{\"\\t\"}{.metadata.annotations['ingressclass\\.kubernetes\\.io/is-default-class']}{\"\\n\"}{end}"Дриль 6: Інгрес з анотаціями
Розділ «Дриль 6: Інгрес з анотаціями»# Create servicekubectl create deployment annotated-app --image=nginxkubectl expose deployment annotated-app --port=80
# Create Ingress with annotationscat << 'EOF' | kubectl apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: annotated-ingress annotations: nginx.ingress.kubernetes.io/ssl-redirect: "false" nginx.ingress.kubernetes.io/proxy-connect-timeout: "30"spec: ingressClassName: nginx rules: - http: paths: - path: / pathType: Prefix backend: service: name: annotated-app port: number: 80EOF
# Check annotationskubectl get ingress annotated-ingress -o yaml | grep -A5 annotations
# Cleanupkubectl delete ingress annotated-ingresskubectl delete deployment annotated-appkubectl delete svc annotated-appДриль 7: Налагодження Інгресу
Розділ «Дриль 7: Налагодження Інгресу»# Create Ingress with wrong service name (intentionally broken)cat << 'EOF' | kubectl apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: broken-ingressspec: ingressClassName: nginx rules: - http: paths: - path: / pathType: Prefix backend: service: name: nonexistent-service port: number: 80EOF
# Debugkubectl describe ingress broken-ingress# Look for warnings about backend
# Check ingress controller logs (if installed)kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx --tail=10
# Fix: create the missing servicekubectl create deployment fix-app --image=nginxkubectl expose deployment fix-app --port=80 --name=nonexistent-service
# Verifykubectl describe ingress broken-ingress
# Cleanupkubectl delete ingress broken-ingresskubectl delete deployment fix-appkubectl delete svc nonexistent-serviceДриль 8: Виклик — повне налаштування Інгресу
Розділ «Дриль 8: Виклик — повне налаштування Інгресу»Не заглядаючи в розв’язання, створіть деплойменти на ім’я api та frontend, відкрийте обидва як Сервіси ClusterIP на порту 80, створіть Інгрес для хоста myapp.local, маршрутизуйте /api до api, маршрутизуйте / до frontend, додайте Secret типу TLS, перевірте через describe й приберіть усе.
# YOUR TASK: Complete the challenge in under 7 minutesРозв'язання
# 1. Create deploymentskubectl create deployment api --image=nginxkubectl create deployment frontend --image=nginx
# 2. Expose as ClusterIPkubectl expose deployment api --port=80kubectl expose deployment frontend --port=80
# 3. Create Ingresscat << 'EOF' | kubectl apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: challenge-ingressspec: ingressClassName: nginx rules: - host: myapp.local http: paths: - path: /api pathType: Prefix backend: service: name: api port: number: 80 - path: / pathType: Prefix backend: service: name: frontend port: number: 80EOF
# 4. Add TLS# self-signed, no SAN — modern curl needs --insecure (lab/testing only)openssl req -x509 -nodes -days 1 -newkey rsa:2048 \ -keyout tls.key -out tls.crt -subj "/CN=myapp.local"kubectl create secret tls myapp-tls --cert=tls.crt --key=tls.key
# Update Ingress with TLScat << 'EOF' | kubectl apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: challenge-ingressspec: ingressClassName: nginx tls: - hosts: - myapp.local secretName: myapp-tls rules: - host: myapp.local http: paths: - path: /api pathType: Prefix backend: service: name: api port: number: 80 - path: / pathType: Prefix backend: service: name: frontend port: number: 80EOF
# 5. Verifykubectl describe ingress challenge-ingress
# 6. Cleanupkubectl delete ingress challenge-ingresskubectl delete deployment api frontendkubectl delete svc api frontendkubectl delete secret myapp-tlsrm tls.key tls.crtДжерела
Розділ «Джерела»- Ingress | Kubernetes
- IngressClass | Kubernetes
- Ingress path types | Kubernetes
- Ingress TLS | Kubernetes
- Services, Load Balancing, and Networking | Kubernetes
- Service | Kubernetes
- Kubernetes Gateway API
- Migrating from Ingress | Kubernetes Gateway API
- Ingress NGINX Retirement: What You Need to Know | Kubernetes Blog
- Ingress NGINX Statement | Kubernetes Blog
- ingress2gateway | Kubernetes SIGs
- ingress-nginx kind deployment manifest — retired controller; lab/learning use only; see maintained alternatives above
Наступний модуль
Розділ «Наступний модуль»Модуль 3.5: Gateway API — наступне покоління інгресу Kubernetes з багатшими ресурсами маршрутів і чіткішими межами володіння на платформі.
Перевірка для учня
Розділ «Перевірка для учня»Якщо ви запам’ятаєте лише одне речення про налагодження, нехай це буде воно: відсутня адреса вказує на узгодження контролера чи класу, 404 вказує на збіг хоста й шляху, а 503 вказує на збіглі маршрути з недоступними бекендами.