Модуль 5.2: Ingress
Складність:
[MEDIUM]— важливо для зовнішнього доступу, кілька концепційЧас на виконання: 45-55 хвилин
Передумови: Модуль 5.1 (Сервіси), розуміння HTTP та DNS
Результати навчання
Розділ «Результати навчання»Після завершення цього модуля ви зможете:
- Створювати ресурси Ingress із правилами маршрутизації на основі хоста та шляху, які з’єднують зовнішній HTTP-трафік із внутрішніми Сервісами.
- Налаштовувати термінацію TLS та кілька бекенд-Сервісів в одному Ingress, зберігаючи при цьому правильні межі простору імен і сертифікатів.
- Діагностувати збої маршрутизації Ingress, перевіряючи стан контролера, прив’язку до IngressClass, порти бекенд-Сервісів, Endpoints та логи контролера.
- Оцінювати, коли Ingress є правильним механізмом надання доступу порівняно з Сервісами типу LoadBalancer, Сервісами NodePort та Gateway API.
Чому цей модуль важливий
Розділ «Чому цей модуль важливий»Гіпотетичний сценарій: ваша команда випускає невеликий продукт із вебфронтендом, API та адміністративним інтерфейсом. Кожне робоче навантаження вже має Сервіс ClusterIP, тож трафік працює всередині кластера, але користувачам поза кластером потрібні зручні HTTPS-адреси на кшталт app.example.com, api.example.com та app.example.com/admin. Можна було б надати кожному Сервісу окремий хмарний балансувальник навантаження, але такий вибір розкидає маршрутизацію, TLS і вартість по кількох об’єктах, які складніше осмислити під час інциденту.
Ingress дає Kubernetes стандартний контракт HTTP-маршрутизації для такої ситуації. Об’єкт Ingress описує імена хостів, URL-шляхи, TLS-секрети та бекенд-Сервіси, тоді як контролер Ingress перетворює цей опис на справжню конфігурацію проксі чи балансувальника навантаження. Сам по собі об’єкт не відкриває сокет, не виділяє публічну IP-адресу й не термінує TLS; він ближчий до письмового запиту на маршрутизацію, який контролер має узгодити.
Іспит CKAD зазвичай зосереджується на стороні власника застосунку в цьому контракті. Від вас очікують, що ви створюватимете й оглядатимете ресурси Ingress, обиратимете зіставлення шляхів Prefix або Exact, прив’язуватиметесь до правильного порту бекенд-Сервісу та розпізнаватимете, коли відсутній контролер чи неправильний клас пояснюють порожню адресу. Зазвичай вас не просять спроєктувати продакшн-архітектуру межі мережі, але та сама ментальна модель допомагає уникати помилок на іспиті та збоїв у продакшні.
Kubernetes 1.35+ усе ще підтримує Ingress networking.k8s.io/v1, але Ingress — це стабільний, навмисно обмежений API. Він добре обробляє HTTP- та HTTPS-маршрутизацію, проте не намагається змоделювати кожну сучасну функцію балансування навантаження. Розглядайте цей модуль як практичну основу CKAD, а потім порівнюйте його з Gateway API, коли вам потрібен багатший розподіл трафіку, міжпросторове під’єднання чи виразніший платформний контракт.
Ingress як контракт маршрутизації
Розділ «Ingress як контракт маршрутизації»Ingress розташований на один рівень вище за абстракцію Сервісу, яку ви вивчили в Модулі 5.1. Сервіс дає Подам стабільну віртуальну адресу всередині кластера, тоді як Ingress повідомляє контролеру на межі мережі, як зовнішні HTTP-запити мають досягати цих Сервісів. Контролером може бути Traefik, Kong, Cilium, Envoy Gateway, NGINX Gateway Fabric або інша реалізація, яка розуміє ресурси Ingress і володіє зовнішньою точкою входу.
Найважливіше розмежування — між бажаним станом і реалізацією. Ресурс Ingress зберігається на сервері API Kubernetes, але сам по собі не проксіює трафік. Контролер стежить за ресурсами Ingress, стежить за пов’язаними Сервісами та Endpoints і оновлює власну конфігурацію виконання щоразу, коли бажаний стан змінюється. Без цього контролера YAML може бути цілком валідним і все одно не маршрутизувати жодного трафіку.
Це той самий патерн контуру керування, який ви бачили з Деплойментами. Деплоймент не запускає контейнери напряму; він описує бажане розгортання, а контролери створюють ReplicaSet’и та Поди. Ingress дотримується цього патерну на межі мережі: ви пишете правило, контролер узгоджує правило, а балансувальник навантаження чи проксі контролера обробляє пакети.
Аналогія з готельною рецепцією корисна, якщо точно зберігати ролі. Гості прибувають до одного входу, просять ресторан, спа чи номер, а адміністратор спрямовує їх до потрібного місця. У термінах Kubernetes вхід — це зовнішня адреса контролера, хост і шлях запиту — це те, про що просить гість, а кінцева кімната — це бекенд-Сервіс, який уже знає, як дістатися здорових Подів.
Зупиніться й передбачте: якщо ви застосуєте Ingress із валідним YAML, а kubectl get ingress далі показує порожнє поле ADDRESS, яку частину системи ви оглянули б перед тим, як змінювати правила маршрутизації? Найшвидша відповідь — зазвичай контролер і прив’язка класу, а не селектор Сервісу, бо відсутність адреси означає, що реалізація межі мережі ще не заявила права на маршрут і не опублікувала його.
# Перевірте, чи є у вас контролер Ingresskubectl get pods -n ingress-nginx# абоkubectl get pods -A | grep -i ingressПростір імен у цій команді навмисно специфічний для контролера. Багато старіших лабораторних робіт використовують простір імен ingress-nginx, тоді як новіші кластери можуть запускати Traefik, Cilium, Kong, Envoy Gateway чи керований хмарний контролер в іншому просторі імен. Для роботи на іспиті спершу з’ясуйте, що існує, а потім адаптуйте назву класу та команду перегляду логів контролера до середовища, яке вам надали.
Ресурс Ingress потребує звичної оболонки об’єкта Kubernetes плюс spec, що містить правила. Кожне правило може зіставлятися з хостом, а тоді з одним чи кількома HTTP-шляхами, і кожен шлях указує на бекенд-Сервіс за іменем і портом. Бекенд-Сервіс має перебувати в тому самому просторі імен, що й Ingress, якщо API явно не каже інакше, а стандартний бекенд-Сервіс, показаний тут, — це звичайна форма CKAD.
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: my-ingressspec: rules: - host: myapp.example.com http: paths: - path: / pathType: Prefix backend: service: name: my-service port: number: 80Читайте секцію бекенду як вказівник на наявний Сервіс, а не безпосередньо на Под. Ця деталь важлива під час діагностики, бо робочий Ingress усе одно може повертати згенерований контролером код 503, якщо у Сервісу немає готових Endpoints. Шлях запиту такий: контролер Ingress, далі Сервіс, далі Endpoints чи EndpointSlices, далі Поди; кожен перехід має узгоджуватись щодо імен, портів і готовності.
У ресурсу також є важлива історія зі значеннями за замовчуванням. Деякі кластери визначають типовий IngressClass, що дозволяє Ingress пропускати spec.ingressClassName; інші кластери вимагають явно називати клас. Для портативних маніфестів і чіткості на іспиті надавайте перевагу явному класу, коли середовище його надає, та використовуйте kubectl get ingressclass, перш ніж припускати назву контролера.
Наступна діаграма — це оригінальна картина потоку запитів модуля, де той самий захищений ресурс збережено для орієнтації. Вона навмисно статична, а не діаграма послідовності, бо ключова ідея — це розташування компонентів: контролер володіє зовнішньою адресою, Ingress зберігає правила, а Сервіси залишаються мостом до Подів.
┌─────────────────────────────────────────────────────────────┐│ Ingress Flow │├─────────────────────────────────────────────────────────────┤│ ││ Internet ││ │ ││ ▼ ││ ┌─────────────────────────────────────┐ ││ │ Ingress Controller │ ││ │ (traefik, kong, cilium, etc.) │ ││ │ │ ││ │ Reads Ingress rules │ ││ │ Routes based on host/path │ ││ └─────────────────────────────────────┘ ││ │ ││ │ api.example.com/users ││ │ ││ ▼ ││ ┌─────────────────────────────────────┐ ││ │ Ingress Resource │ ││ │ │ ││ │ rules: │ ││ │ - host: api.example.com │ ││ │ paths: │ ││ │ - /users → user-svc:80 │ ││ │ - /orders → order-svc:80 │ ││ │ - host: web.example.com │ ││ │ paths: │ ││ │ - / → frontend-svc:80 │ ││ └─────────────────────────────────────┘ ││ │ ││ ▼ ││ ┌──────────┐ ┌──────────┐ ┌──────────┐ ││ │ user-svc │ │order-svc │ │frontend │ ││ │ :80 │ │ :80 │ │svc :80 │ ││ └──────────┘ └──────────┘ └──────────┘ ││ │└─────────────────────────────────────────────────────────────┘Практичний наслідок полягає в тому, що діагностика Ingress починається з володіння. Якщо жоден контролер не заявляє права на Ingress, немає й конфігурації межі мережі для огляду. Якщо контролер заявив права, але повертає помилку, наступне питання — чи зіставляється правило з хостом і шляхом запиту. Якщо правило зіставляється, але контролер не може дістатися бекенду, наступним рівнем доказів стають Сервіс та Endpoints.
Зіставлення шляхів і правила маршрутизації
Розділ «Зіставлення шляхів і правила маршрутизації»Маршрутизація Ingress будується з двох видимих частин HTTP-запиту: заголовка Host та URL-шляху. Хост вирішує, до якого віртуального сайту намагається дістатися запит, а шлях вирішує, яка частина цього сайту має обробити запит. Це робить Ingress хорошим варіантом для багатьох компонувань застосунків, як-от api.example.com для трафіку API та example.com/docs для трафіку документації.
Перший тип шляху, до якого варто звертатися, — це Prefix. Kubernetes визначає його як поелементне зіставлення префікса за сегментами шляху, тож /api зіставляється з /api, /api/ та /api/users, але це не означає довільне зіставлення підрядків. Це розрізнення не дозволяє маршруту для /api несподівано зіставитися зі шляхом на кшталт /apix, коли контролер правильно дотримується семантики Kubernetes.
pathType: Prefixpath: /api# Matches: /api, /api/, /api/users, /api/users/123Exact суворіший і корисний, коли один URL має означати один бекенд без дочірніх шляхів. Маршрут для /api з Exact не зіставляється з /api/ чи /api/users, тож він рідко є правильним вибором для цілої поверхні API. Він корисний для сторінки стану, ендпоінта зворотного виклику або навмисно вузького маршруту, який не має поглинати сусідній трафік.
pathType: Exactpath: /api# Matches: /api only# Does NOT match: /api/, /api/usersImplementationSpecific делегує інтерпретацію шляху реалізації IngressClass. Це може бути привабливим, коли ви залежите від специфічної для контролера функції, але це послаблює портативність, бо інший контролер може інтерпретувати той самий шлях інакше. У практиці CKAD надавайте перевагу Prefix або Exact, якщо завдання явно не вимагає поведінки, специфічної для контролера.
Коли зіставляється кілька шляхів, пріоритет шляхів Kubernetes надає перевагу найдовшому зіставленому шляху перед розглядом типу шляху. Це означає, що /api/v2 є точнішим збігом, ніж /api, для запиту на кшталт /api/v2/users. Перш ніж це запускати, який вивід ви очікуєте, якщо Ingress містить обидва правила, а ви робите curl на /api/v2/users із правильним заголовком хоста? Відповіддю має бути бекенд за довшим зіставленим шляхом за умови, що контролер реалізує стандартні правила пріоритету.
Маршрутизація на основі хоста — найчистіший дизайн, коли різні імена DNS представляють різні застосунки або межі безпеки. Вона зберігає URL-шляхи простими, дозволяє TLS-сертифікатам природно зіставлятися з іменами хостів і зменшує ймовірність того, що один застосунок випадково залежатиме від префікса шляху іншого застосунку. Компроміс полягає в тому, що DNS і сертифікати стають частиною кожного середовища, яке ви тестуєте.
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: host-routingspec: 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Маршрутизація на основі шляху корисна, коли одне ім’я хоста представляє продукт, але різні Сервіси володіють різними URL-префіксами. Вона поширена для невеликих систем, порталів документації та внутрішніх інструментів, але може стати крихкою, якщо застосунки припускають, що вони змонтовані за /. Коли застосунок генерує абсолютні посилання, перенаправлення, кукі чи шляхи OpenAPI, ви маєте перевірити, що він поводиться правильно за обраним префіксом.
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: path-routingspec: rules: - host: example.com 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Зупиніться й подумайте: Ingress має два правила шляху — /api з pathType: Prefix та /api/v2 з pathType: Prefix. Надходить запит на /api/v2/users. Який бекенд отримує трафік і яку єдину команду ви запустили б після цього, щоб підтвердити відрендерений контролером перелік бекендів?
Типовий бекенд (default backend) — це маршрут-перехоплювач для запитів, які не зіставляються з жодним правилом хоста чи шляху. Деякі контролери налаштовують глобальний типовий бекенд поза вашим об’єктом Ingress, тоді як Kubernetes також дозволяє spec.defaultBackend на рівні Ingress. У модулях про застосунки використовуйте його навмисно для відомого резервного Сервісу, а не як спосіб приховати неоднозначні маршрути.
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: with-defaultspec: defaultBackend: service: name: default-service port: number: 80 rules: - host: example.com http: paths: - path: /api pathType: Prefix backend: service: name: api-service port: number: 80Ризик маршрутизації-перехоплювача — це спостережуваність. Якщо неправильне ім’я хоста чи помилково написаний шлях тихо потрапляє на типову сторінку, користувачі можуть повідомляти про незрозумілу поведінку замість чіткої помилки. Для іспитових завдань типовий бекенд простий; для продакшн-дизайну поєднуйте його з логуванням, характерним тілом відповіді та моніторингом, який відокремлює очікуваний резервний трафік від трафіку зламаних маршрутів.
Порт бекенд-Сервісу в кожному маршруті має збігатися з відкритим портом Сервісу, а не обов’язково з портом контейнера Пода. Якщо ваш Сервіс відкриває port: 80 і зіставляється з targetPort: 8080, бекенд Ingress зазвичай має посилатися на порт Сервісу 80. Багато розслідувань 503 починаються з того, що хтось перевіряє порт контейнера Пода й пропускає те, що Ingress спілкується з абстракцією Сервісу.
Інша деталь маршрутизації з’являється, коли кілька об’єктів Ingress описують той самий хост. Контролери зазвичай зливають сумісні правила, але конфлікти специфічні для реалізації, і їх може бути важко помітити з одного маніфесту. Якщо дві команди обидві створюють шляхи під example.com, маршрут, який працює в розробці, може зіткнутися в спільному кластері. Під час усунення несправностей огляньте всі об’єкти Ingress у просторі імен і використовуйте kubectl get ingress -A, коли політика кластера дозволяє міжпросторову видимість.
Хости з символами підстановки (wildcard) заслуговують на ту саму обачність. Kubernetes підтримує імена хостів із символами підстановки в обмеженій формі, але сертифікат із символом підстановки, DNS-запис із символом підстановки та правило Ingress із символом підстановки — це три різні частини стану. Вони мають узгоджуватися, перш ніж трафік поводитиметься чисто. Маршрут із символом підстановки може бути корисним для preview-середовищ, але також може робити випадкові імена хостів схожими на валідні, тож поєднуйте його з явним володінням і чіткими правилами очищення.
Переписування шляхів (path rewrites) — це місце, де багато простих дизайнів стають специфічними для контролера. Бекенд, змонтований за /, може не розуміти, що користувачі дісталися його через /api, тож команди додають анотацію переписування, щоб зрізати префікс. Це може бути правильним, але воно змінює те, що бачить застосунок, порівняно з тим, що запитав клієнт. Під час діагностики перенаправлень входу, згенерованих посилань чи документації OpenAPI запитайте, чи отримує бекенд оригінальний шлях, чи переписаний.
Термінація TLS та межі HTTPS
Розділ «Термінація TLS та межі HTTPS»TLS у стандартному Ingress зазвичай означає термінацію на контролері. Клієнт під’єднується до контролера через HTTPS, контролер пред’являє сертифікат із Secret’у Kubernetes, а потім контролер пересилає запит до бекенд-Сервісу за допомогою протоколу, налаштованого цим контролером. API Ingress в Kubernetes моделює TLS-хост і посилання на Secret, але для розширеної поведінки бекенд-TLS можуть знадобитися специфічні для контролера анотації.
Тип Secret’у для матеріалу сертифіката — це kubernetes.io/tls, а kubectl create secret tls створює цю форму з сертифіката та приватного ключа. Secret має перебувати в тому самому просторі імен, що й Ingress, який на нього посилається. Ця межа простору імен — поширений збій на іспиті та в продакшні, бо специфікація Ingress лише називає secretName; вона не містить поля простору імен для TLS-секрету.
# Create TLS secret from cert and keykubectl create secret tls my-tls-secret \ --cert=path/to/tls.crt \ --key=path/to/tls.keyПерелік tls в Ingress зіставляє імена хостів з іменами Secret’ів. Ім’я хоста в блоці TLS має узгоджуватися з іменем хоста в правилі та з Subject Alternative Name сертифіката. Якщо Secret містить валідний сертифікат для іншого хоста, контролер усе одно може його завантажити, але браузери відхилять з’єднання, бо ідентичність сертифіката перевіряє клієнт.
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: tls-ingressspec: tls: - hosts: - secure.example.com secretName: my-tls-secret rules: - host: secure.example.com http: paths: - path: / pathType: Prefix backend: service: name: secure-service port: number: 80Сучасні контролери зазвичай підтримують SNI, що дозволяє кільком HTTPS-іменам хостів спільно використовувати ту саму зовнішню адресу, пред’являючи сертифікат, який відповідає кожному запитуваному хосту. Це одна з причин, чому один контролер Ingress може обслуговувати багато застосунків без окремого балансувальника навантаження на кожен Сервіс. SNI не усуває потреби в правильному DNS, розміщенні Secret’у та іменах хостів сертифіката; він лише дозволяє контролеру обрати серед сертифікатів під час TLS-рукостискання.
Для діагностики CKAD відокремлюйте проблеми TLS від проблем маршрутизації. Попередження про сертифікат перед будь-якою відповіддю застосунку вказує на Secret, ім’я сертифіката чи налаштування TLS-хоста. Чистий сертифікат, за яким іде 404 чи 503, означає, що TLS пройшов успішно, і вам слід оглянути правила хоста, правила шляху, Сервіси та Endpoints. Цей порядок не дає вам змінювати YAML, до якого запит так і не дійшов.
Є також межа безпеки, про яку варто пам’ятати. Якщо контролер термінує TLS і пересилає звичайний HTTP до Сервісу, трафік усередині кластера не зашифрований лише цим налаштуванням Ingress. Деякі платформи приймають це, бо мережа кластера є довіреною; інші вимагають специфічного для контролера бекенд-TLS, mTLS, сервісної сітки чи функцій Gateway API. Ingress дає вам контракт термінації на межі, а не повний дизайн наскрізного шифрування.
Ротація сертифікатів — ще одне місце, де API Ingress навмисно малий. Ingress посилається на ім’я Secret’у, а контролер стежить за цим Secret’ом, але API не каже, хто отримує, оновлює чи аудитує сертифікат. Деякі кластери використовують cert-manager, деякі — зовнішню автоматизацію, а деякі покладаються на платформну команду. Як автор застосунку ви маєте перевірити ім’я Secret’у, простір імен та імена хостів, не припускаючи, що система оновлення є частиною самого Ingress.
Для локального тестування пам’ятайте, що HTTPS перевіряє імена, а не лише IP-адреси. Якщо ви робите curl напряму на IP контролера, сертифікат для secure.example.com не відповідатиме цьому IP, якщо його не було видано з відповідним IP subject alternative name. Кращий тест надсилає правильний заголовок хоста або налаштовує локальне розв’язання імен так, щоб клієнт запитував те саме ім’я хоста, яке з’являється в правилі Ingress та сертифікаті.
IngressClass та поведінка, специфічна для контролера
Розділ «IngressClass та поведінка, специфічна для контролера»IngressClass відповідає на просте, але важливе питання: який контролер відповідає за цей Ingress? Кластер може запускати більш ніж один контролер, наприклад, контролер лише для внутрішнього доступу та контролер, повернутий до інтернету. Якщо ваш Ingress не називає клас і не існує типового класу, контролер може його проігнорувати, залишивши об’єкт присутнім в API без корисної зовнішньої адреси.
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: my-ingressspec: ingressClassName: nginx # Which controller rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: my-service port: number: 80Старіша анотація kubernetes.io/ingress.class усе ще видима в старих прикладах, але spec.ingressClassName — це поле Kubernetes, яке варто використовувати в сучасних маніфестах. Типовий клас може бути позначений на об’єкті IngressClass платформною командою, але автори застосунків не повинні припускати, що цей типовий клас існує. На незнайомому кластері перелічіть доступні класи, перш ніж вирішувати, чи встановлювати це поле.
# List available IngressClasseskubectl get ingressclassАнотації все ще поширені, бо Ingress навмисно малий. Переписування, поведінка перенаправлень, обмеження тіла запиту, вибір вищерозташованого протоколу та налаштування таймаутів часто специфічні для контролера, тож стандартний API залишає їх документації контролера. Ця гнучкість корисна, але вона означає, що анотації не є портативними контрактами між контролерами.
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: annotated-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / nginx.ingress.kubernetes.io/ssl-redirect: "true"spec: rules: - host: example.com http: paths: - path: /api pathType: Prefix backend: service: name: api-service port: number: 80Анотації в цьому збереженому прикладі навмисно в стилі NGINX, тож читайте їх як специфічні для контролера приклади, а не як універсальні налаштування Kubernetes. Розгортання Traefik, Kong, Cilium чи хмарного контролера може використовувати інші анотації чи кастомні ресурси для того самого наміру. Коли скопійована анотація начебто нічого не робить, спершу підтвердьте, що запущений контролер підтримує саме цей ключ.
Поширені анотації NGINX включають переписування URL, поведінку перенаправлення на HTTPS та максимальний розмір тіла запиту. Концепція переноситься між контролерами навіть тоді, коли синтаксис змінюється: ви просите реалізацію межі мережі змінити обробку запитів поза стандартними полями хоста, шляху, бекенду та TLS. Ця межа допомагає вам вирішити, чи належить проблема до портативного YAML Kubernetes, чи до документації контролера.
Стан Ingress також належить контролеру. Поле status.loadBalancer.ingress — це не те, що ви зазвичай встановлюєте в маніфесті, бо контролер оновлює його після публікації адреси чи імені хоста. Якщо стан ніколи не змінюється, контролер може бути відсутнім, стежити за іншим класом, заблокованим дозволами чи нездатним надати свою зовнішню залежність. Це відрізняється від збою на рівні застосунку, де адреса існує, але бекенд повертає помилку.
Поведінка типового IngressClass зручна, але може приховувати зміни платформи. Якщо адміністратор кластера змінює, який клас є типовим, нові Ingress’и без ingressClassName можуть почати потрапляти на інший контролер, тоді як старіші об’єкти зберігають свій попередній стан. Явні імена класів трохи більш багатослівні, але вони роблять огляди й хронології інцидентів чіткішими, бо передбачений контролер записаний у маніфест застосунку.
Наведений нижче короткий довідник зберігає інвентар команд оригінального модуля з виправленим придатним до виконання скороченням. Використовуйте його як діагностичну послідовність, а не як випадковий перелік команд. Почніть із підтвердження об’єкта Ingress, потім огляньте його відрендерені правила та події, потім перевірте адресу, клас і логи контролера, якщо маршрут поводиться не так, як очікувалося.
# Create Ingress imperatively (limited)kubectl create ingress my-ingress --class=nginx \ --rule="host.example.com/path=service:port"
# View Ingresskubectl get ingresskubectl describe ingress NAME
# Get Ingress address (ip and/or hostname — kind/minikube often use hostname)kubectl get ingress NAME -o jsonpath='{.status.loadBalancer.ingress[0].ip}{"\n"}{.status.loadBalancer.ingress[0].hostname}'
# Check IngressClasskubectl get ingressclass
# View controller logskubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginxІмперативне створення зручне під час іспитових тренувань, але декларативний YAML кращий для всього, що ви плануєте оглядати чи повторно використовувати. Імперативна команда не може комфортно виразити кожну специфічну для контролера анотацію, компонування TLS чи дизайн із багатьма правилами. Використовуйте kubectl create ingress, коли важлива швидкість, а завдання просте; переходьте до маніфесту, коли чіткість, придатність до огляду чи повторюваність важливіші.
Діагностика шляху запиту
Розділ «Діагностика шляху запиту»Надійна процедура діагностики Ingress рухається в тому самому напрямку, що й запит. Підтвердьте, що клієнт досягає адреси контролера, підтвердьте, що контролер прийняв Ingress, підтвердьте, що хост і шлях зіставляються з очікуваним правилом, підтвердьте, що ім’я й порт бекенд-Сервісу існують, і нарешті підтвердьте, що Сервіс має готові ендпоінти. Перехід відразу до логів Пода може марнувати час, коли маршрут ніколи не обирав ці Поди.
Вивід kubectl describe ingress часто є найкращим першим артефактом, бо він поєднує правила, бекенди, інформацію про адресу, анотації, клас і події. Якщо секція бекенду показує Сервіс, але без адрес ендпоінтів, контролер має достатньо інформації, щоб знайти Сервіс, але недостатньо здорових цілей для проксіювання. Це зазвичай вказує на невідповідність селектора Сервісу, збій проби готовності чи неправильний targetPort.
Коли симптомом є порожня адреса, спершу ставте питання про володіння. Чи запущений контролер? Чи називає Ingress правильний ingressClassName? Чи визначає кластер типовий IngressClass? Чи має контролер дозвіл оновлювати стан Ingress? Ці питання передують зіставленню шляхів, бо правило, на яке не заявлено права, не може маршрутизувати жодного запиту.
Коли симптомом є 404 від контролера, контролер, імовірно, досяжний, але не зіставив запит із передбаченим правилом. Перевірте заголовок Host запиту, ім’я DNS чи локальне зіставлення /etc/hosts, префікс шляху та чи володіє точнішим правилом інший Ingress. 404 від бекенд-застосунку — це інше; він доводить, що запит досяг Пода, тож оглядайте маршрутизацію застосунку, а не зіставлення Ingress.
Коли симптомом є 503 від контролера, правило зазвичай зіставилося, але бекенд недоступний. Огляньте Сервіс, Endpoints, EndpointSlices та готовність Пода. Ingress не робить неготовий Под здоровим і не обходить селектор Сервісу. Сервіс із нульовою кількістю ендпоінтів — це зламаний міст між маршрутом і робочим навантаженням.
Інструменти тестування можуть випадково змінити проблему, яку ви намагаєтеся спостерігати. Браузер слідує за перенаправленнями, кешує рішення HSTS і може повторно використовувати з’єднання, тоді як curl може надіслати точний заголовок хоста й шлях. Під час діагностики маршруту запишіть хост, шлях, схему та очікуваний бекенд перед тестуванням. Ця маленька дисципліна перетворює «Ingress зламаний» на спростовне твердження про одну форму запиту.
DNS перебуває поза об’єктом Ingress, але всередині користувацького досвіду. Ingress може правильно опублікувати адресу, тоді як app.example.com усе ще вказує кудись інде чи не поширився. У лабораторії ви можете симулювати DNS за допомогою локального файлу hosts або опції curl resolve. У продакшні включіть DNS-записи та видачу сертифікатів до контрольного списку розгортання, бо користувачі не взаємодіють зі станом об’єктів Kubernetes напряму.
Сценарій вправи: ви створюєте маршрутизацію api.example.com до api-service:80, сертифікат валідний, а лог контролера показує помилки з’єднання з вищерозташованим бекендом. У цій ситуації змінювати TLS-секрет малоцінно, бо TLS уже пройшов успішно. Кращий шлях — оглянути api-service, перевірити його селектор, підтвердити готові Поди та порівняти port Сервісу з targetPort Пода.
Логи контролера все ще цінні, але читайте їх після того, як дізнаєтесь, який контролер володіє Ingress. Оригінальний короткий довідник використовує мітку ingress-nginx, бо старіші лабораторні роботи часто так робили, але сучасний кластер може надавати Traefik, Cilium, Kong, Envoy Gateway чи контролер хмарного провайдера. kubectl get pods -A | grep -i ingress дає вам кандидатів, а IngressClass каже, який кандидат має узгоджувати ваш об’єкт.
Ваша ментальна модель також має включати затримку поширення. Застосування Ingress оновлює сервер API негайно, але виділення зовнішнього балансувальника навантаження, оновлення DNS, перезавантаження сертифікатів та узгодження контролером можуть тривати довше. Під час іспиту ця затримка зазвичай коротка; у реальних кластерах вона може варіюватися залежно від хмарного провайдера й контролера. Перезапускайте сфокусовані команди огляду, перш ніж робити непов’язані правки.
Події часто розкривають першу корисну скаргу контролера. Відхилений бекенд, відсутній Secret, невалідне значення анотації чи невідповідність класу можуть з’явитися в kubectl describe ingress, перш ніж це стане очевидним з відрендереного маршруту. Події не є тривким сховищем логів, тож використовуйте їх як швидкий локальний доказ, а потім переходьте до логів контролера, якщо вам потрібна довша історія. Це тримає розслідування прив’язаним до об’єкта, який збоїть.
Робочий приклад: поєднання хостів, шляхів, TLS та бекендів
Розділ «Робочий приклад: поєднання хостів, шляхів, TLS та бекендів»Припустімо, вам потрібна одна зовнішня точка входу для невеликого застосунку з фронтендом та API. Маршрутизація на основі хоста дала б API власне ім’я DNS, тоді як маршрутизація на основі шляху могла б розмістити його під тим самим іменем хоста. Вибір дизайну залежить від очікувань клієнта, володіння сертифікатами та чи написані застосунки так, щоб жити під префіксом шляху.
Для іспитового завдання найпростіша валідна відповідь — це часто один Ingress із двома Сервісами та або двома правилами хоста, або двома правилами шляху. Вам не потрібен окремий Ingress для кожного бекенду, якщо завдання не вимагає окремого володіння, різних анотацій чи різної поведінки TLS. Менша кількість об’єктів може бути легшою для огляду, але один гігантський спільний Ingress може стати проблемою координації у великих командах.
Якщо API має бути досяжним як api.local, а вебінтерфейс як web.local, правила хоста тримають кожен бекенд ізольованим. Якщо обидва мають спільно використовувати myapp.local, працюють правила шляху на кшталт /frontend та /backend, але лише якщо застосунки толерують ці префікси. Ось чому практична вправа просить вас потренувати обидві форми, а не запам’ятати лише одну.
Який підхід ви обрали б тут і чому: одне ім’я хоста з /api чи окремі імена api.example.com та web.example.com? Сильна відповідь згадує більше, ніж довжину YAML. Вона має враховувати поведінку браузера, кукі, сертифікати, закладки клієнта, потреби переписування шляху та те, як легко черговий інженер може побачити, який Сервіс має отримати запит.
Варіант із типовим бекендом додає резерв для незіставленого трафіку. Це може бути корисним для зручної цільової сторінки чи внутрішньої діагностичної відповіді, але також приховує помилки, якщо кожна друкарська помилка повертає щось схоже на валідне. У навчальній лабораторії це демонструє форму API; у продакшні воно заслуговує на логування та дуже навмисну відповідь.
Далі TLS додає посилання на Secret та перевірку ідентичності за іменем хоста. Якщо ви тестуєте із самопідписаним сертифікатом, очікуйте попереджень про довіру браузера, якщо тільки ви не довіряєте сертифікату локально, але все одно перевірте, що Ingress завантажує Secret, а правило вказує на передбачений Сервіс. Стан, події та логи контролера підказують вам, чи прийняв він матеріал сертифіката.
Тепер додайте володіння до робочого прикладу. Якщо фронтенд та API належать одній команді, один Ingress може бути розумною одиницею змін, бо один огляд може охопити спільний хост і сертифікат. Якщо ними володіють окремі команди, окремі ресурси Ingress чи володіння маршрутами Gateway API можуть зменшити ризик координації. API Kubernetes дозволяє вам представити обидва вибори, тож обирайте форму, що відповідає операційній відповідальності.
Планування відкату — частина дизайну маршруту. Розподіл на основі хоста часто можна відкотити, змінивши DNS чи володіння маршрутом, тоді як розподіл на основі шляху може потребувати видалення лише одного правила шляху. Якщо Ingress також містить непов’язані шляхи, поспішний відкат може випадково потурбувати здоровий трафік. Тримайте маніфести достатньо малими, щоб людина могла ідентифікувати уражений хост і шлях під тиском.
Решта модуля перетворює це міркування на повторювані рішення, а потім просить вас побудувати ті самі патерни в кластері. Тримайте шлях запиту в голові, поки працюєте: зовнішній клієнт, адреса контролера, правило хоста й шляху, порт Сервісу, ендпоінти та готові Поди. Ця послідовність — найкоротший маршрут від симптому до зламаного рівня.
Патерни та антипатерни
Розділ «Патерни та антипатерни»Патерни та антипатерни для Ingress переважно стосуються меж володіння. Хороший дизайн Ingress робить очевидним, хто володіє іменем хоста, який Сервіс отримує шлях, де живе TLS-матеріал і яка специфічна для контролера поведінка потрібна. Слабкий дизайн розкидає ці відповіді по анотаціях, неявних значеннях за замовчуванням, скопійованих фрагментах і Сервісах, чиї селектори ніхто не перевіряв.
| Патерн | Коли використовувати | Чому працює |
|---|---|---|
Явний ingressClassName | Кластер має більш ніж один контролер, або ви не впевнені, чи існує типовий клас. | Він робить володіння контролером видимим і не дає кожному контролеру проігнорувати валідний Ingress. |
| Маршрутизація на основі хоста для окремих продуктів | Різні команди, клієнти, кукі, сертифікати чи політики безпеки належать різним застосункам. | Імена хостів роблять володіння та TLS-ідентичність чіткими, і вони уникають несподіванок із префіксами шляхів усередині застосунків. |
| Маршрутизація на основі шляху для одного цілісного сайту | Один продукт природно ділить ім’я хоста, а застосунки можуть коректно працювати під призначеними їм префіксами. | Вона тримає DNS і сертифікати простими, водночас розділяючи бекенд-Сервіси за однією точкою входу. |
| Анотації контролера, тримані близько до маршруту | Маршрут потребує переписувань, перенаправлень, змін розміру тіла чи таймаутів, специфічних для одного контролера. | Маніфест документує непортативну поведінку поряд із маршрутом, що від неї залежить. |
Явний клас — найважливіший операційний патерн, бо він запобігає тихій неоднозначності. У кластері з внутрішнім і зовнішнім контролерами пропуск класу може виставити застосунок на неправильну межу чи залишити його без заявлених прав. Навіть коли типовий клас існує, називання класу в навчальних маніфестах робить ваш намір легшим для огляду.
Маршрутизація на основі хоста — сильний типовий вибір, коли застосунки належать незалежним власникам. Вона чисто зіставляється з DNS, сертифікатами, джерелами браузера (origins) та політиками доступу. Ціна — додаткова робота з DNS і сертифікатами, але ця робота часто купує чіткішу діагностику, бо саме ім’я хоста каже вам, який маршрут має зіставлятися.
Маршрутизація на основі шляху працює найкраще, коли застосунки спроєктовані для неї. Якщо бекенд припускає, що працює за /, префікс на кшталт /api може потребувати переписувань чи конфігурації застосунку. Це не збій Kubernetes; це невідповідність між припущеннями застосунку щодо URL та дизайном маршрутизації на межі.
| Антипатерн | Що йде не так | Краща альтернатива |
|---|---|---|
| Не встановлювати контролер і лише застосовувати YAML Ingress | Об’єкт API існує, але жоден проксі за ним не стежить і не публікує адресу. | Підтвердьте контролер і клас, перш ніж вважати маршрут активним. |
| Копіювання анотацій контролера між реалізаціями | Новий контролер ігнорує ключі чи інтерпретує їх інакше. | Прочитайте документацію запущеного контролера й тримайте портативні поля окремо від налаштувань, специфічних для реалізації. |
| Вказування Ingress на порт Пода замість порту Сервісу | Бекенд виглядає правильним для людей, але збоїть, бо Сервіс відкриває інший порт. | Огляньте Сервіс і посилайтеся на service.spec.ports[].port з бекенду Ingress. |
| Використання широкого типового бекенду для приховування всього незіставленого трафіку | Друкарські помилки та неправильні заголовки хоста повертають правдоподібні сторінки замість чітких збоїв. | Використовуйте явні правила хоста й робіть резервні відповіді характерними та спостережуваними. |
Повторюваною темою є не «використовуйте менше анотацій» чи «завжди надавайте перевагу одному стилю маршрутизації». Сильніше правило — робити кожну неочевидну поведінку придатною для огляду з об’єктів Kubernetes та документації контролера. Якщо інший інженер може запустити kubectl describe ingress, оглянути Сервіс і передбачити шлях запиту, дизайн, імовірно, придатний для супроводу.
Каркас прийняття рішень
Розділ «Каркас прийняття рішень»Почніть рішення про надання доступу з протоколу. Якщо робоче навантаження потребує сирого TCP чи UDP, стандартний Ingress — неправильна перша абстракція, бо він визначений для HTTP- та HTTPS-маршрутизації. Якщо робоче навантаження — HTTP, запитайте, чи потребує маршрут простих правил хоста/шляху, чи багатшої політики трафіку, як-от зважений розподіл, міжпросторові посилання чи розширене володіння слухачами. Прості правила пасують Ingress; багатші платформні контракти часто вказують на Gateway API.
| Потреба | Надавайте перевагу | Причина |
|---|---|---|
| Одна стабільна адреса лише для внутрішнього доступу | Сервіс ClusterIP | Трафік залишається всередині кластера й не потребує маршрутизації на межі. |
| Одна зовнішня адреса, напряму прив’язана до одного Сервісу | Сервіс LoadBalancer | Хмарний чи платформний балансувальник навантаження може обслуговувати Сервіс без маршрутизації за хостом/шляхом. |
| Багато HTTP-маршрутів, що ділять одну точку входу | Ingress | Правила хоста й шляху консолідують маршрутизацію через контролер. |
| Багата політика трафіку чи розділення платформи/команд | Gateway API | Gateway та HTTPRoute розділяють володіння інфраструктурою від володіння маршрутом виразніше. |
| Швидке локальне чи іспитове надання доступу без DNS | NodePort чи port-forward | Корисно для тимчасового доступу, але зазвичай не чиста продакшн-межа. |
Використовуйте цей ментальний потік під час вибору форми Ingress. По-перше, підтвердьте, що трафік — це HTTP чи HTTPS. По-друге, визначте, чи є імена хостів або шляхи природним контрактом, поверненим до користувача. По-третє, вирішіть, чи достатньо одного класу контролера, чи внутрішній і зовнішній трафік потребують окремих класів. По-четверте, додавайте TLS лише після того, як імена хостів стануть достатньо стабільними, щоб зіставлятися з ідентичностями сертифікатів.
Рішення між маршрутизацією на основі хоста й на основі шляху не лише стилістичне. Маршрутизація на основі хоста дає кожному застосунку власне джерело браузера (origin), що впливає на кукі, CORS та планування сертифікатів. Маршрутизація на основі шляху створює одне джерело, що може спростити клієнтів, але може змусити застосунки знати про префікс чи анотації переписування. Правильний вибір слідує за поведінкою клієнта й припущеннями застосунку, а не лише за компактністю YAML.
Рішення між Ingress та Сервісом LoadBalancer залежить від того, скільки HTTP-інтелекту вам потрібно на межі. Сервіс LoadBalancer простий для одного зовнішньо досяжного Сервісу, але він зазвичай не виражає кілька імен хостів і шляхів в одному об’єкті Kubernetes. Ingress додає цей рівень HTTP-маршрутизації, але він також залежить від контролера й операцій, специфічних для контролера.
Рішення між Ingress та Gateway API стосується майбутньої форми. Ingress залишається корисним для завдань CKAD і багатьох прямолінійних застосунків, але проєкт Kubernetes розглядає Gateway API як виразніший напрямок для новіших сценаріїв маршрутизації. Коли вам потрібні слухачі (listeners), правила під’єднання маршрутів, розподіл трафіку чи чіткіше платформне володіння, оцінюйте Gateway API замість того, щоб проштовхувати все через анотації.
Для іспиту оптимізуйте під робочий стандартний маніфест Ingress із правильним apiVersion, іменами бекенд-Сервісів, портами Сервісів, pathType та класом. Для реальних систем оптимізуйте під маршрут, який інший інженер може проаудитувати під тиском. Ці цілі перетинаються, але продакшн додає до базового YAML життєвий цикл сертифікатів, володіння DNS, логування, оновлення контролерів та платформну політику.
Є ще одне практичне рішення: чи володіє контролером команда застосунку, чи платформна команда. Команди застосунків зазвичай володіють об’єктами Ingress, бо знають імена хостів, шляхи та бекенд-Сервіси. Платформні команди зазвичай володіють встановленням контролера, зовнішніми балансувальниками навантаження, типовими класами та політикою спільних анотацій. Розмивання цієї межі може створювати інциденти, де маніфест застосунку правильний, але контролер не може надати інфраструктуру.
Використовуйте мітки й угоди про іменування, щоб зробити цю межу придатною для пошуку. Маршрут, названий api, у просторі імен, названому prod, каже вам менше, ніж orders-api-public із мітками, що ідентифікують застосунок-власник і рівень доступу. Іменування не є замінником правильного YAML, але воно скорочує першу хвилину інциденту. Об’єктів Ingress достатньо мало, щоб чіткі імена швидко окупалися.
Чи знали ви?
Розділ «Чи знали ви?»- Ingress — це конфігурація, а не Сервіс. Ресурс зберігається в API Kubernetes, але фактичну маршрутизацію виконують Поди контролера чи інтеграції з керованими балансувальниками навантаження, які за ним стежать.
- Ingress отримав загальну доступність у Kubernetes 1.19. Старіший бета-API було видалено з обслуговуваних API в Kubernetes 1.22, тому сучасні маніфести використовують
networking.k8s.io/v1. - Анотація
kubernetes.io/ingress.classзастаріла. Сучасні маніфести мають використовуватиspec.ingressClassName, тоді як платформи можуть позначити типовий IngressClass, коли хочуть, щоб пропущені імена класів призначалися автоматично. - Стандартний Ingress моделює лише HTTP- та HTTPS-маршрутизацію. Для сирого TCP чи UDP надання доступу використовуйте тип Сервісу чи функцію, специфічну для контролера, і порівнюйте Gateway API для новіших моделей маршрутів.
Типові помилки
Розділ «Типові помилки»| Помилка | Чому стається | Як виправити |
|---|---|---|
| Не встановлено контролер Ingress | Учні припускають, що сам об’єкт API проксіює трафік, тож kubectl apply здається достатнім. | Підтвердьте, що контролер запущений і що він володіє класом, який використовує Ingress. |
Неправильний чи відсутній ingressClassName | Кластер має кілька контролерів чи не має типового класу, тож ресурс валідний, але без заявлених прав. | Запустіть kubectl get ingressclass, потім установіть spec.ingressClassName на передбачений клас. |
Неправильний pathType | Exact та Prefix поводяться по-різному, особливо для вкладених шляхів застосунку. | Використовуйте Prefix для дерев шляхів та Exact лише для одного точного URL-шляху. |
| Невідповідність імені чи порту Сервісу | Бекенд Ingress указує на порт Сервісу, який не існує чи не є відкритим портом Сервісу. | Опишіть Сервіс і посилайтеся на service.spec.ports[].port у бекенді Ingress. |
| Сервіс не має готових ендпоінтів | Маршрут зіставляється, але контролеру нема куди здорового надсилати трафік. | Перевірте Endpoints чи EndpointSlices, готовність Подів, мітки та селектор Сервісу. |
| TLS-секрет у неправильному просторі імен | Ingress може посилатися на Secret лише за іменем у власному просторі імен. | Створіть чи скопіюйте Secret kubernetes.io/tls у той самий простір імен, що й Ingress. |
| Копіювання непідтримуваних анотацій | Специфічні для контролера фрагменти вставляються в кластер, що працює з іншим контролером. | Перевірте запущений контролер і використовуйте лише анотації, задокументовані для цієї реалізації. |
Тест
Розділ «Тест»-
Ваш маніфест Ingress застосовується успішно, але
kubectl get ingressпоказує порожнє полеADDRESSпісля кількох циклів узгодження. Інші Сервіси у просторі імен здорові. Що слід перевірити першим і чому?Відповідь
Почніть із володіння контролером, а не з бекенд-Подів. Порожня адреса зазвичай означає, що жоден контролер не заявив права на Ingress і не опублікував його, тож перевірте, чи запущений контролер Ingress і чи має ресурс правильний `ingressClassName`. Потім запустіть `kubectl get ingressclass` і порівняйте імена класів зі своїм маніфестом. Ендпоінти Сервісу мають значення пізніше, але вони не пояснюють, чому адресу межі так і не було призначено. -
Користувачі досягають
https://secure.example.com, але браузер попереджає, що сертифікат не валідний для сайту. Правило Ingress та блок TLS обидва згадуютьsecure.example.com. Які дві ймовірні причини?Відповідь
По-перше, Secret може містити сертифікат, чий Subject Alternative Name не включає `secure.example.com`; поле Ingress не переписує ідентичність сертифіката. По-друге, контролер може завантажувати інший Secret, бо названий Secret відсутній чи невалідний у просторі імен Ingress. Перевірте, що Secret існує поряд з Ingress, потім огляньте імена сертифіката. Здоров'я бекенд-Сервісу не є першим підозрюваним, бо попередження стається під час валідації TLS-ідентичності. -
Запит на
example.com/api/v2/usersмаршрутизується до застарілого API, хоча новіший бекенд/api/v2існує в тому самому Ingress. Які деталі ви оглянули б?Відповідь
Підтвердьте, що новіше правило справді використовує `path: /api/v2` з `pathType: Prefix` і що контролер відрендерив його для того самого хоста. Пріоритет шляхів Kubernetes має надавати перевагу найдовшому зіставленому префіксу, тож правильне правило `/api/v2` має перемагати `/api`. Якщо правило відсутнє, призначене іншому хосту чи проігноровано через специфічну для контролера поведінку, ширший маршрут `/api` може перемогти. Також перевірте, чи інший Ingress для того самого хоста додає шляхи, що перекриваються. -
Ingress повертає згенерований контролером 503 для
/api, аkubectl describe ingressпоказує бекендapi-service:80. Контролер має адресу, і хост зіставляється. Яка ваша наступна послідовність діагностики?Відповідь
503 після зіставлення правила зазвичай вказує на доступність бекенду. Опишіть `api-service`, перевірте, що порт `80` існує на Сервісі, потім огляньте Endpoints чи EndpointSlices на готові адреси. Якщо перелік ендпоінтів порожній, порівняйте селектор Сервісу з мітками Пода й перевірте готовність Пода. Логи контролера можуть додати деталей, але їх слід читати поряд зі станом Сервісу та ендпоінтів. -
Ваша команда хоче
shop.example.comдля вітрини йblog.example.comдля статей, але також хоче/blogпід хостом магазину для старих посилань. Як ви структурували б Ingress?Відповідь
Використовуйте правила на основі хоста для обох первинних імен хостів, потім додайте правило шляху під `shop.example.com`, що надсилає `/blog` до Сервісу блогу. Хост магазину також має мати маршрут із префіксом `/` до Сервісу вітрини. Маршрут `/blog` точніший за `/`, тож він має отримувати старі посилання на блог, коли хост — `shop.example.com`. Перевірте, що застосунок блогу працює під цим префіксом, або додайте підтримувану контролером поведінку переписування. -
Скопійований маніфест включає
nginx.ingress.kubernetes.io/rewrite-target: /, але кластер використовує контролер Traefik, і переписування не стається. Яка корінна проблема?Відповідь
Анотація специфічна для реалізації, а не частина портативного API Ingress. Контролер Traefik не зобов'язаний шанувати ключ анотації NGINX, тож маршрут може зіставлятися, тоді як переписування ігнорується. Підтвердьте запущений контролер через IngressClass і Поди контролера, потім використовуйте документацію та модель конфігурації для цього контролера. Стандартні поля для хоста, шляху, бекенду та TLS залишаються портативними; поведінка анотацій — ні. -
Вам потрібно надати доступ до HTTP-застосунку для завдання в стилі CKAD. Ви можете обрати NodePort, Сервіс LoadBalancer чи Ingress. Завдання згадує маршрутизацію на основі хоста та TLS. Який об’єкт вам слід створити і який наявний об’єкт уже має працювати?
Відповідь
Створіть Ingress, бо маршрутизація на основі хоста та термінація TLS — це стандартні завдання Ingress. Бекенд-Сервіс уже має працювати, бо Ingress указує на ім'я й порт Сервісу, а не напряму на Поди. Вам також слід підтвердити, що в кластері існують контролер Ingress і відповідний клас. NodePort чи LoadBalancer самі по собі можуть надати доступ до Сервісу, але вони не виражають запитану маршрутизацію за хостом так само.
Практична вправа
Розділ «Практична вправа»Ця вправа зберігає практичний робочий процес оригінального модуля, роблячи намір чіткішим. Ви створите два прості Деплойменти, надасте їм доступ через Сервіси, створите три варіанти Ingress, а потім приберете за собою. Якщо ваш лабораторний кластер не містить контролера Ingress, об’єкти все одно можна створити та описати, але живе HTTP-тестування залежатиме від налаштування контролера в середовищі.
Перша мета — не запам’ятати YAML. Мета — побачити, як малі зміни в полях хоста, шляху, типового бекенду, класу й TLS змінюють контракт маршрутизації контролера. Прочитайте кожен маніфест перед його застосуванням, передбачте, який Сервіс має отримати трафік, потім використайте kubectl describe ingress, щоб порівняти своє передбачення з відрендереним переліком правил.
Налаштування
Розділ «Налаштування»Ця лабораторна робота припускає, що лабораторна платформа вже має контролер ingress-nginx та встановлений IngressClass nginx. Перевірте обидва перед створенням ресурсів застосунку, бо наведені нижче маніфести Ingress прив’язуються явно до spec.ingressClassName: nginx.
kubectl get pods -n ingress-nginxkubectl get ingressclass nginxПродовжуйте лише тоді, коли Поди контролера запущені, а IngressClass nginx існує. Якщо будь-яка команда збоїть, спершу встановіть чи увімкніть ingress-nginx через ваше лабораторне середовище.
# Create two deploymentskubectl create deployment web --image=nginxkubectl create deployment api --image=nginx
# Create serviceskubectl expose deployment web --port=80kubectl expose deployment api --port=80
# Wait for Deployments (avoids racing pod scheduling)kubectl wait --for=condition=Available deployment/web deployment/api --timeout=60sЧастина 1: Простий Ingress
Розділ «Частина 1: Простий Ingress»Цей перший Ingress надсилає весь HTTP-трафік, що досягає контролера для цього простору імен і набору правил, до Сервісу web. Він навмисно мінімальний, тож корисний для доведення, що контролер може заявити права на Ingress і що бекенд-Сервіс здоровий, перед додаванням складності хоста чи шляху.
cat << 'EOF' | kubectl apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: simple-ingressspec: ingressClassName: nginx rules: - http: paths: - path: / pathType: Prefix backend: service: name: web port: number: 80EOF
kubectl get ingress simple-ingresskubectl describe ingress simple-ingressНотатки до розв'язку
Вивід describe має показати правило префікса `/`, що вказує на `web:80`. Якщо бекенд має готові адреси ендпоінтів, селектор Сервісу й Поди узгоджені. Якщо адреса порожня, огляньте IngressClass і контролер, а не переписуйте спершу секцію бекенду.Частина 2: Маршрутизація на основі шляху
Розділ «Частина 2: Маршрутизація на основі шляху»Другий Ingress розділяє одну точку входу за URL-префіксом. Запити під /web мають обирати Сервіс web, тоді як запити під /api мають обирати Сервіс api. Це лабораторна версія дизайну зі спільним іменем хоста, і саме тут поведінка префіксів стає видимою.
cat << 'EOF' | kubectl apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: path-ingressspec: ingressClassName: nginx rules: - http: paths: - path: /web pathType: Prefix backend: service: name: web port: number: 80 - path: /api pathType: Prefix backend: service: name: api port: number: 80EOF
kubectl describe ingress path-ingressНотатки до розв'язку
Відрендерені правила мають перелічити обидва `/web` та `/api` з їхніми відповідними Сервісами. Якщо обидва показують той самий бекенд, маніфест було відредаговано неправильно. Якщо в одного бекенду немає ендпоінтів, поверніться до відповідного Сервісу й Деплойменту, перш ніж змінювати правило шляху Ingress.Частина 3: Маршрутизація на основі хоста
Розділ «Частина 3: Маршрутизація на основі хоста»Третій Ingress використовує імена хостів замість префіксів шляхів. У реальному кластері ви вказали б DNS чи локальні записи хостів на адресу контролера перед тестуванням. У лабораторії важливий крок огляду — підтвердити, що web.local та api.local з’являються як окремі правила хоста з окремими бекенд-Сервісами.
cat << 'EOF' | kubectl apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: host-ingressspec: ingressClassName: nginx rules: - host: web.local http: paths: - path: / pathType: Prefix backend: service: name: web port: number: 80 - host: api.local http: paths: - path: / pathType: Prefix backend: service: name: api port: number: 80EOF
kubectl describe ingress host-ingressНотатки до розв'язку
Вивід має показати дві секції хостів. Якщо ви тестуєте з curl, включіть правильний заголовок хоста чи ім'я DNS; інакше запит може не зіставитися з жодним правилом хоста. Правильний Сервіс може виглядати зламаним, коли клієнт надсилає неправильний хост.Очищення
Розділ «Очищення»kubectl delete ingress simple-ingress path-ingress host-ingresskubectl delete deployment web apikubectl delete svc web apiТренувальні завдання
Розділ «Тренувальні завдання»Наведені нижче тренувальні завдання зберігають оригінальні асети з таймером для практики з виправленими придатними до виконання командами. Розглядайте цільові часи як вправу під тиском після того, як зрозумієте модель маршрутизації, а не як перший прохід через матеріал. Якщо завдання збоїть, запишіть, який рівень збоїв, перш ніж пробувати знову: володіння контролером, зіставлення маршруту, порт Сервісу, ендпоінти чи TLS-матеріал.
Завдання 1: Простий Ingress (Ціль: 2 хвилини)
Розділ «Завдання 1: Простий Ingress (Ціль: 2 хвилини)»kubectl create deployment drill1 --image=nginxkubectl expose deployment drill1 --port=80
cat << 'EOF' | kubectl apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: drill1spec: ingressClassName: nginx rules: - http: paths: - path: / pathType: Prefix backend: service: name: drill1 port: number: 80EOF
kubectl get ingress drill1kubectl delete ingress drill1kubectl delete deployment drill1kubectl delete svc drill1Завдання 2: Маршрутизація на основі хоста (Ціль: 3 хвилини)
Розділ «Завдання 2: Маршрутизація на основі хоста (Ціль: 3 хвилини)»kubectl create deployment app1 --image=nginxkubectl create deployment app2 --image=nginxkubectl expose deployment app1 --port=80kubectl expose deployment app2 --port=80
cat << 'EOF' | kubectl apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: drill2spec: ingressClassName: nginx rules: - host: app1.local http: paths: - path: / pathType: Prefix backend: service: name: app1 port: number: 80 - host: app2.local http: paths: - path: / pathType: Prefix backend: service: name: app2 port: number: 80EOF
kubectl describe ingress drill2kubectl delete ingress drill2kubectl delete deployment app1 app2kubectl delete svc app1 app2Завдання 3: Маршрутизація на основі шляху (Ціль: 3 хвилини)
Розділ «Завдання 3: Маршрутизація на основі шляху (Ціль: 3 хвилини)»kubectl create deployment frontend --image=nginxkubectl create deployment backend --image=nginxkubectl expose deployment frontend --port=80kubectl expose deployment backend --port=80
cat << 'EOF' | kubectl apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: drill3spec: ingressClassName: nginx rules: - host: myapp.local http: paths: - path: /frontend pathType: Prefix backend: service: name: frontend port: number: 80 - path: /backend pathType: Prefix backend: service: name: backend port: number: 80EOF
kubectl get ingress drill3kubectl delete ingress drill3kubectl delete deployment frontend backendkubectl delete svc frontend backendЗавдання 4: Ingress із типовим бекендом (Ціль: 3 хвилини)
Розділ «Завдання 4: Ingress із типовим бекендом (Ціль: 3 хвилини)»kubectl create deployment default-app --image=nginxkubectl create deployment api-app --image=nginxkubectl expose deployment default-app --port=80kubectl expose deployment api-app --port=80
cat << 'EOF' | kubectl apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: drill4spec: ingressClassName: nginx defaultBackend: service: name: default-app port: number: 80 rules: - http: paths: - path: /api pathType: Prefix backend: service: name: api-app port: number: 80EOF
kubectl describe ingress drill4kubectl delete ingress drill4kubectl delete deployment default-app api-appkubectl delete svc default-app api-appЗавдання 5: Створення Ingress імперативно (Ціль: 2 хвилини)
Розділ «Завдання 5: Створення Ingress імперативно (Ціль: 2 хвилини)»kubectl create deployment drill5 --image=nginxkubectl expose deployment drill5 --port=80
# Create ingress imperativelykubectl create ingress drill5 --class=nginx --rule="drill5.local/=drill5:80"
kubectl get ingress drill5kubectl describe ingress drill5
kubectl delete ingress drill5kubectl delete deployment drill5kubectl delete svc drill5Завдання 6: Ingress із TLS (Ціль: 4 хвилини)
Розділ «Завдання 6: Ingress із TLS (Ціль: 4 хвилини)»# Create self-signed cert (for demo)openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout /tmp/tls.key -out /tmp/tls.crt \ -subj "/CN=secure.local" 2>/dev/null
# Create TLS secretkubectl create secret tls drill6-tls --cert=/tmp/tls.crt --key=/tmp/tls.key
kubectl create deployment drill6 --image=nginxkubectl expose deployment drill6 --port=80
cat << 'EOF' | kubectl apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: drill6spec: ingressClassName: nginx tls: - hosts: - secure.local secretName: drill6-tls rules: - host: secure.local http: paths: - path: / pathType: Prefix backend: service: name: drill6 port: number: 80EOF
kubectl describe ingress drill6
kubectl delete ingress drill6kubectl delete secret drill6-tlskubectl delete deployment drill6kubectl delete svc drill6rm /tmp/tls.key /tmp/tls.crtКритерії успіху
Розділ «Критерії успіху»- Ви можете пояснити, чому ресурс Ingress потребує контролера, перш ніж він зможе маршрутизувати трафік.
- Ви можете створити простий Ingress, що вказує на Сервіс за іменем і портом Сервісу.
- Ви можете порівняти маршрутизацію на основі хоста з маршрутизацією на основі шляху для тих самих двох бекенд-Сервісів.
- Ви можете описати, коли слід використовувати зіставлення шляхів
PrefixтаExact. - Ви можете налаштувати посилання на TLS-секрет та ідентифікувати невідповідності простору імен чи імені хоста.
- Ви можете діагностувати збійний маршрут, пройшовши від володіння контролером до ендпоінтів Сервісу.
Перевірка для учня
Розділ «Перевірка для учня»На kind/minikube та багатьох хмарних балансувальниках навантаження
status.loadBalancer.ingressможе заповнюватиhostnameзамістьip, тож jsonpath, що читає лише.ip, може виглядати порожнім навіть тоді, коли Ingress здоровий.
Перш ніж рухатися далі, поясніть, чому практична вправа очікує на deployment/web та deployment/api з condition=Available замість kubectl wait на pod -l app=web чи app=api. Ґрунтовна відповідь згадує розгортання ReplicaSet, перегони планування Подів та чому доступність Деплойменту є стабільним сигналом готовності перед створенням бекендів Ingress.
Джерела
Розділ «Джерела»- Документація концепції Ingress в Kubernetes
- Документація концепції Service в Kubernetes
- Документація TLS Secret в Kubernetes
- Довідник API Ingress в Kubernetes
- Довідник API IngressClass в Kubernetes
- Довідник kubectl create ingress
- Довідник kubectl create secret tls
- Документація Gateway API
- Документація контролера Ingress-NGINX
- Документація провайдера Traefik Kubernetes Ingress
- Документація Cilium Ingress
- Документація контролера Kong Kubernetes Ingress
Наступний модуль
Розділ «Наступний модуль»Модуль 5.3: NetworkPolicies — Контроль комунікації між подами.