← Back to notes

Ingress и
Gateway API


Каждый 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.


06: Services

08: ConfigMap и Secret

Ingress и Gateway API | Aleksandr Suprun