Сервіс типу LoadBalancer у Kubernetes створює окрему зовнішню IP-адресу на кожен застосунок — на VPS без хмарного балансувальника це або взагалі не працює, або вимагає ручного налаштування MetalLB. Ingress вирішує завдання інакше: один контролер і одна зовнішня IP-адреса обслуговують маршрутизацію за доменами одразу для всіх сервісів у кластері.
Що таке Ingress і навіщо він у кластері
Ingress — це правило маршрутизації HTTP і HTTPS трафіку всередину кластера за іменем домену і за шляхом в URL, а не окремий мережевий об'єкт. Саме правило нічого не робить без Ingress Controller — програми, яка читає ці правила і налаштовує за ними реальний проксі. ingress-nginx — найпоширеніший контролер, побудований поверх звичайного nginx.
Без Ingress кожен сервіс довелося б публікувати через NodePort чи окремий LoadBalancer, що на 10 застосунках у кластері означає 10 зовнішніх адрес і портів замість одного домену і однієї IP-адреси з маршрутизацією за піддоменами.
Як працює ingress-nginx
Ingress Controller і Ingress-ресурс
Controller — це под, який слухає зовнішній трафік на портах 80 і 443, читає об'єкти типу Ingress через Kubernetes API і на льоту перегенеровує конфіг nginx усередині себе. Ingress-ресурс — це YAML-маніфест із правилами: який домен на який Service і порт відправляти запит.
Маршрутизація за доменом і за шляхом
Один об'єкт Ingress може описувати одразу декілька правил: app.example.com веде на один Service, api.example.com — на інший, а /admin усередині app.example.com — на третій. Контролер сортує правила за специфічністю сам, вручну порядок задавати не потрібно.
| Спосіб публікації | Зовнішніх IP | Маршрутизація за доменом |
|---|---|---|
| NodePort | По одному на вузол | Немає |
| LoadBalancer | Один на сервіс | Немає |
| Ingress | Один на весь кластер | Так |
Встановлення ingress-nginx через Helm
Офіційний чарт ставить контролер, RBAC-ролі і Service типу LoadBalancer чи NodePort, залежно від оточення.
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx --create-namespace
На VPS без хмарного балансувальника Service варто перемкнути на hostNetwork чи NodePort і спрямувати домен напряму на IP вузла — MetalLB потрібен тільки коли важлива єдина віртуальна IP-адреса на декілька вузлів.
Ingress-ресурс із TLS через cert-manager
cert-manager автоматично запитує і продовжує сертифікати, а Ingress-ресурс просто вказує, для якого домену і в який Secret його покласти.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts: ["app.example.com"]
secretName: app-tls
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80
Автоматичний випуск сертифікатів Let's Encrypt
ClusterIssuer описує, яким способом cert-manager підтверджує володіння доменом — через HTTP-01 challenge, який проходить прямо через уже налаштований Ingress.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@example.com
privateKeySecretRef:
name: letsencrypt-prod-key
solvers:
- http01:
ingress:
class: nginx
Якщо кластер розгорнутий через k3s, ingress-nginx часто вже входить у постачання за замовчуванням — Traefik, який ставиться з k3s "з коробки", можна замінити на ingress-nginx чи залишити, залежно від того, які функції потрібні. Окремі VPS під ноди кластера зручно піднімати через Terraform, описавши їхню конфігурацію як код заздалегідь.
Чек-лист і типові помилки
- Анотація cert-manager.io/cluster-issuer вказана точно так само, як ім'я ClusterIssuer, помилка в назві не дає жодної помилки, просто сертифікат не видається.
- DNS-запис домену вже вказує на зовнішню IP-адресу Ingress Controller до запиту сертифіката — HTTP-01 challenge інакше не пройде перевірку.
- pathType вказаний явно (Prefix чи Exact) — без нього старі версії Kubernetes використовують застарілу поведінку маршрутизації.
- Secret з TLS-сертифікатом лежить у тому самому namespace, що і Ingress-ресурс, а не в namespace контролера.