Короткий ответ
Несколько Ingress-контроллеров в одном кластере нужны, когда разным группам трафика требуются разные возможности или изоляция — например, отдельный публичный внешний контроллер и отдельный внутренний для служебных сервисов, или разные вендоры (NGINX и облачный ALB-контроллер) для разных типов нагрузки; поле ingressClassName в объекте Ingress явно указывает, какой контроллер должен обрабатывать именно это правило.
Как это работает подробнее
каждый Ingress-контроллер при запуске слушает (через механизм watch) только те объекты Ingress, у которых ingressClassName совпадает с его собственным IngressClass, либо, если IngressClass помечен как default, обрабатывает Ingress без явно указанного класса. Без явного указания класса при наличии нескольких контроллеров поведение становится неоднозначным — в зависимости от конфигурации либо ни один контроллер не возьмёт объект, либо он будет случайно обработан "дефолтным".
Пример кода
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata: { name: internal-grafana }
spec:
ingressClassName: nginx-internal
rules:
- host: grafana.internal.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: grafana
port:
number: 80Что использовать на практике
- Практика. разделение на внешний и внутренний Ingress-контроллер позволяет держать внутренние административные интерфейсы (Grafana, внутренние API) полностью отделёнными от публичного внешнего адреса с собственными правилами безопасности, сертификатами и, возможно, более мягкими настройками rate-limiting. Использование двух разных реализаций (например, NGINX Ingress Controller и облачный контроллер, интегрированный с managed балансировщиком) оправдано, когда разным классам трафика нужны разные возможности — но это увеличивает операционную сложность поддержки двух разных систем.
Подводные камни
- Риски. не указывать
ingressClassNameв кластере с несколькими контроллерами и получать непредсказуемое поведение маршрутизации (правило либо не подхватывается никем, либо подхватывается не тем контроллером); помечать несколько IngressClass какdefaultодновременно, что в части реализаций приводит к конфликту или непредсказуемому выбору.