Каждый Service типа LoadBalancer создаёт отдельный облачный балансировщик. При 20 сервисах — 20 балансировщиков, каждый со своим IP и ценой. Ingress решает это: один балансировщик, маршрутизация HTTP/HTTPS трафика к разным Service по hostname и пути.
[source: kubernetes.io/docs/concepts/services-networking/ingress/]
Что такое Ingress
Ingress — объект Kubernetes, определяющий правила маршрутизации HTTP/HTTPS трафика на уровне L7. Позволяет:
- Маршрутизировать по hostname (
api.example.com→ Service A,web.example.com→ Service B) - Маршрутизировать по пути (
/api→ Service A,/web→ Service B) - Терминировать TLS
Статус API. Ingress остаётся стабильным и широко используемым, но Kubernetes помечает его как frozen — новые возможности добавляются только в Gateway API. Для базового HTTP/HTTPS-routing Ingress по-прежнему подходит; для новых инсталляций с богатыми требованиями к traffic policy — смотри Gateway API.
Ingress Controller
Сам по себе Ingress-ресурс ничего не делает. Нужен Ingress Controller — компонент, который читает Ingress-объекты и настраивает прокси. Kubernetes не поставляет его по умолчанию — нужно установить отдельно.
[source: kubernetes.io/docs/concepts/services-networking/ingress-controllers/]
Манифест Ingress
Маршрутизация по пути
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: myapp.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
Маршрутизация по hostname
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-host-ingress
spec:
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
pathType
TLS-терминация
# Создать Secret с TLS-сертификатом
kubectl create secret tls my-tls-secret \
--cert=tls.crt \
--key=tls.key
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
spec:
ingressClassName: nginx
tls:
- hosts:
- myapp.example.com
secretName: my-tls-secret
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
cert-manager автоматически выпускает и обновляет TLS-сертификаты (Let's Encrypt) и записывает их в Secret. Стандартное решение для production.
Default Backend
Обрабатывает запросы, не совпавшие ни с одним правилом:
spec:
ingressClassName: nginx
defaultBackend:
service:
name: default-service
port:
number: 80
rules:
- host: myapp.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
IngressClass
IngressClass (introduced 1.18 alpha/beta, GA в 1.19) определяет, какой Ingress Controller обрабатывает конкретный Ingress-ресурс. Позволяет использовать несколько контроллеров в одном кластере.
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx
annotations:
ingressclass.kubernetes.io/is-default-class: "true"
spec:
controller: k8s.io/ingress-nginx
Если is-default-class: "true" установлен, Ingress без явного ingressClassName будет обработан этим контроллером.
Service (L4) vs Ingress (L7)
Gateway API
Почему Gateway API
Ingress API заморожен (frozen) — новые возможности в него не добавляются. Весь активный roadmap — в Gateway API. Стабильные ресурсы Gateway API (GatewayClass, Gateway, HTTPRoute, GRPCRoute) доступны в группе gateway.networking.k8s.io/v1.
[source: kubernetes.io/docs/concepts/services-networking/gateway/]
Ролевая модель
Пример: Gateway + HTTPRoute с canary
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: prod-gateway
spec:
gatewayClassName: istio
listeners:
- name: https
port: 443
protocol: HTTPS
tls:
mode: Terminate
certificateRefs:
- name: prod-cert
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
gateway-access: "true"
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app-route
spec:
parentRefs:
- name: prod-gateway
hostnames:
- "app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-svc
port: 8080
weight: 90
- name: api-svc-canary
port: 8080
weight: 10
weight в backendRefs — нативный traffic split для canary без нестандартных аннотаций. В Ingress это требует vendor-специфичных annotations.
Ingress vs Gateway API
Реализации Gateway API: Istio, Cilium, Envoy Gateway, Kong, NGINX Gateway Fabric, Contour.
Типичные ошибки
Создать Ingress без Ingress Controller. Ingress останется в подвешенном состоянии — ADDRESS не появится, трафик не пойдёт. Всегда проверять: kubectl get ingressclass.
Не указать ingressClassName. Если в кластере несколько Ingress Controller и нет дефолтного класса, Ingress не будет обработан никем.
Перепутать port: в backend.service.port. Там должен быть порт Service, не контейнера. Service уже занимается маршрутизацией до targetPort контейнера.
TLS Secret не в том namespace. Ingress и Secret должны быть в одном namespace.
rewrite-target без escaping. При использовании nginx.ingress.kubernetes.io/rewrite-target: /$2 с capture groups в path нужно правильно задавать регулярку в path. Пропустить — получить 404.
Альтернативы
Service LoadBalancer напрямую — если один сервис и не нужна L7-маршрутизация. Дороже при масштабировании.
Cloudflare Tunnel / ngrok — для доступа к локальному кластеру без публичного IP.
Service Mesh с ingress gateway (Istio Ingress Gateway, Linkerd Ingress) — если mesh уже есть, его ingress gateway может заменить отдельный Ingress Controller.