← Kubernetes: сеть
10 мин · средне · Урок 7 из 8

Ingress: host-based routing

Один вход на 80/443 и правила, которые раскидывают трафик по Service в зависимости от домена и пути.

Зачем нужен Ingress

Service умеет открыть приложение наружу. NodePort даёт порт на каждой ноде, LoadBalancer выдаёт публичный IP. И то и другое работает, пока Service один. Когда их десять, картина ломается: десять разных портов или десять IP, TLS вручную на каждом, никакой маршрутизации по домену.

Ingress решает другую задачу. Один контроллер слушает 80/443, читает правила «такой host или path идёт в такой Service», и раскидывает трафик. Один публичный адрес, много приложений за ним.

Схема fan-out по хостам: один контроллер на входе, дальше по заголовку Host запрос уходит в нужный Service.

                     /-- api.example.com   --> Service api
client --> Ingress --+-- web.example.com   --> Service web
                     \-- shop.example.com  --> Service shop

Ingress это декларация, не контроллер

IngressClass в кластере name: traefik (kubectl get ingressclass) Ingress · spec ingressClassName: traefik rules: helloapp.example.com совпадение строк
Строка одна и та же в двух объектах: разошлась и правило никто не подберёт.

Сам объект Ingress ничего не делает. Это запись в etcd: «вот мои правила, кто-нибудь их выполните». Работу делает Ingress Controller: отдельный Pod, который читает Ingress-объекты через API и настраивает себя как HTTP-прокси.

Ingress в кластере без контроллера будет висеть бессмысленно. А в кластере с двумя контроллерами (nginx и traefik) надо явно сказать, какой из них берёт правило.

Это делает поле ingressClassName. А ещё есть IngressClass-объект, который описывает контроллер на уровне кластера:

kubectl get ingressclass
# NAME      CONTROLLER                      PARAMETERS   AGE
# traefik   traefik.io/ingress-controller   <none>       42d

Если у одного IngressClass стоит аннотация ingressclass.kubernetes.io/is-default-class: "true", то Ingress без ingressClassName подхватит он. Полагаться на это поведение не стоит, класс указывают явно.

Дальше в примерах стоит ingressClassName: traefik. Сам манифест от контроллера не зависит: меняется только имя класса, поля rules, host, pathType остаются те же.

ingress-nginx снят с поддержки, но стоит почти везде

Самым массовым контроллером долгие годы был ingress-nginx с классом nginx. Именно его команды kubectl apply -f .../ingress-nginx/... лежат в половине репозиториев, статей и старых курсов.

24 марта 2026 репозиторий kubernetes/ingress-nginx перевели в архив. Последний релиз - controller-v1.15.1, заявленная поддержка кластеров до версии 1.35. Новых релизов, багфиксов и патчей безопасности не будет. Причина простая: один-два мейнтейнера в свободное время и накопленный техдолг, который делает безопасное сопровождение нерешаемым. Проект InGate, который готовили как преемника, тоже свернули.

Важно правильно понять масштаб. Речь про контроллер, а не про Ingress API. Объект kind: Ingress в группе networking.k8s.io/v1 остаётся GA, никем не deprecated, и кластеры обрабатывают его как раньше. Deprecated здесь одна конкретная реализация.

Практика от этого не изменилась в один день. По оценке из заявления Kubernetes Steering Committee, ingress-nginx крутится примерно в половине cloud-native окружений, и на сентябрь 2026 он продолжает работать в проде у огромного числа команд. Ты почти наверняка встретишь его на новой работе. Читать его аннотации (nginx.ingress.kubernetes.io/*) уметь надо.

Что это значит на практике:

Проверить, есть ли он в конкретном кластере:

kubectl get pods --all-namespaces \
  --selector app.kubernetes.io/name=ingress-nginx

Отдельная ловушка в учебных кластерах: minikube addons enable ingress по-прежнему разворачивает именно ingress-nginx, решения у minikube пока нет. У kind документацию переписали: ingress там теперь работает нативно через cloud-provider-kind, сторонний контроллер не нужен.

Минимальный манифест

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: helloapp
spec:
  ingressClassName: traefik
  rules:
    - host: helloapp.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: helloapp
                port:
                  number: 8080

Разбор:

Host в Ingress отличается от того, что в DNS или в curl -H Host: .... Контроллер матчит ровно строку.

pathType: три варианта

- path: /api
  pathType: Prefix

При нескольких правилах с Prefix выигрывает самое длинное совпадение. /api/users обгоняет /api обгоняет /. Порядок в YAML не важен.

Императивный путь

kubectl create ingress экономит время:

kubectl create ingress helloapp \
  --class=traefik \
  --rule="helloapp.example.com/*=helloapp:8080" \
  --dry-run=client -o yaml

На выходе готовый YAML, который остаётся дописать и применить. Синтаксис правила: host/path=service:port. Звёздочка в конце пути даёт pathType: Prefix, без неё Exact.

TLS

Сертификат вешается прямо на Ingress:

spec:
  tls:
    - hosts: [helloapp.example.com]
      secretName: helloapp-tls
  rules: [...]

secretName указывает на Secret типа kubernetes.io/tls с ключами tls.crt и tls.key. Контроллер вытаскивает сертификат и терминирует TLS на себе. Блок tls нужен не всегда: если HTTPS расшифровывает прокси перед кластером, до Ingress доезжает уже обычный HTTP. Синтаксис всё равно стоит помнить, в боевых кластерах он встречается часто.

Что часто ломается

Команды для разведки

kubectl get ingressclass
kubectl get ingress
kubectl describe ingress helloapp

describe показывает backends, paths и события от контроллера. Если правило не подхватилось, причина будет в Events.

Ingress и Gateway API

Ingress остаётся GA и стоит в большинстве кластеров, но у него есть предел: вся конфигурация (host, path, TLS, тонкие настройки) живёт в одном объекте и расширяется вендорными аннотациями. На смену пришёл Gateway API, более новый стандарт, где роутинг разнесён на несколько объектов с разными владельцами и из коробки умеет TCP, gRPC, веса трафика. Для нового проекта имеет смысл смотреть в его сторону; Ingress учат, потому что он повсюду и его надо уметь читать. Разница разбирается дальше в треке.

Домашка

Теорию закрепляет задание на своём кластере: 1 шаг с проверкой. Кластер поднимается по треку Kubernetes локально, задания лежат в репозитории k8s-practice.

./run.sh start k8s-ingress-basics     # развернуть стартовое состояние
./run.sh verify k8s-ingress-basics    # проверить текущий шаг

Коротко

Дрилл · вопросы как на собесе

Проверь себя без подсказок

Сформулируй ответ вслух или письменно, потом раскрой и честно отметь: знал или нет.

01

Что такое Ingress?

K8S-011

Прошли материал до конца? Отметьте урок пройденным.