26 липня 2026 р.
Встановлення та налаштування Nginx Ingress Controller

Ingress Controller приймає HTTP та HTTPS трафік на межі Kubernetes-кластера, аналізує host і path, а потім спрямовує запит до потрібного Service. Без контролера ресурс Ingress залишається лише декларацією: Kubernetes збереже YAML, але самостійно не створить reverse proxy і не почне обробляти зовнішні з’єднання.
У цьому матеріалі встановимо community-проєкт ingress-nginx через офіційний Helm chart, перевіримо створені компоненти, опублікуємо тестовий застосунок, налаштуємо host-based routing і розберемо діагностику. Перед початком потрібні робочий кластер, доступ через kubectl, Helm і розуміння того, звідки надходить зовнішній трафік. Якщо chart-и ще незнайомі, корисно спочатку пройти практичний матеріал Helm Charts для початківців.
Ingress працює тільки з HTTP(S). Для довільного TCP або UDP потрібна окрема конфігурація контролера чи Service іншого типу. Також важливо не плутати ingress-nginx із комерційними продуктами NGINX Inc.: у них різні chart-и, образи, параметри та документація.
Що перевірити перед встановленням контролера
Спочатку переконаємося, що kubectl спрямований у правильний кластер. Помилка kube-context небезпечніша за помилку YAML, адже коректна команда може змінити не те середовище.
kubectl config current-context
kubectl cluster-info
kubectl get nodes -o wide
helm versionДалі перевіримо, чи вже немає іншого Ingress Controller. У керованому кластері він може бути встановлений платформою, а в k3s або Rancher Desktop часто вже працює Traefik. Два контролери допустимі, але для них потрібні різні IngressClass і зрозумілий розподіл ресурсів.
kubectl get ingressclass
kubectl get pods --all-namespaces \
-l app.kubernetes.io/component=controllerПотрібно заздалегідь визначити спосіб зовнішнього доступу. У хмарному кластері Service типу LoadBalancer зазвичай отримує адресу від інтеграції провайдера. На bare-metal сам тип LoadBalancer не створить фізичний балансувальник: потрібен MetalLB, зовнішній load balancer, NodePort або інша мережева схема. Цю частину не можна маскувати налаштуванням Ingress, бо controller не керує маршрутом до Kubernetes-вузлів.
Для production також варто визначити кількість реплік, topology spread або anti-affinity, ресурси, політику збереження client IP та джерело TLS-сертифікатів. Коли такі рішення охоплюють кластер, CI/CD і спостережуваність, їх доцільно оформлювати як єдиний контур DevOps-послуг, а не як набір ручних команд.
Встановлення ingress-nginx через Helm
Додамо офіційний chart repository та переглянемо доступні версії. У відтворюваному процесі версію chart потрібно фіксувати, а не щоразу мовчки брати найновішу.
helm repo add ingress-nginx \
https://kubernetes.github.io/ingress-nginx
helm repo update
helm search repo ingress-nginx/ingress-nginx --versions | headЗбережемо типові values у файл для аудиту. Це допомагає бачити доступні параметри саме тієї версії, яку плануємо встановити.
helm show values ingress-nginx/ingress-nginx \
--version CHART_VERSION \
> ingress-nginx-default-values.yamlСтворимо невеликий `values-ingress-nginx.yaml`. Для універсального прикладу залишаємо LoadBalancer, дві репліки, ресурси та metrics endpoint. У конкретній хмарі до Service можуть бути потрібні provider-specific annotations.
controller:
replicaCount: 2
service:
type: LoadBalancer
externalTrafficPolicy: Local
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
metrics:
enabled: true
config:
use-forwarded-headers: "true"`externalTrafficPolicy: Local` допомагає зберігати адресу клієнта, але вимагає уважної перевірки health checks і розміщення controller pods. `use-forwarded-headers` має сенс лише тоді, коли перед ingress-nginx є довірений proxy або load balancer. Не можна без перевірки довіряти довільним forwarded headers з інтернету.
Встановимо release idempotent-командою. Значення `CHART_VERSION` потрібно замінити на перевірену версію з попереднього списку.
helm upgrade --install ingress-nginx \
ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--create-namespace \
--version CHART_VERSION \
-f values-ingress-nginx.yaml \
--atomic \
--wait \
--timeout 10mПараметр `--atomic` поверне release до попереднього стану, якщо upgrade не завершиться успішно. Це не скасовує необхідність окремо перевіряти мережу, DNS і доступність backend після встановлення.
Перевірка controller, webhook і зовнішньої адреси
Після Helm-команди перевіримо release та Kubernetes-об’єкти. Controller pod повинен перейти у стан Ready, а admission jobs і webhook — створитися без помилок.
helm status ingress-nginx -n ingress-nginx
kubectl get pods,svc -n ingress-nginx -o wide
kubectl get ingressclass
kubectl get validatingwebhookconfiguration \
ingress-nginx-admissionПерший запуск може тривати довше, поки jobs створюють сертифікат admission webhook. Дочекаємося готовності controller pods:
kubectl wait --namespace ingress-nginx \
--for=condition=ready pod \
--selector=app.kubernetes.io/component=controller \
--timeout=180sУ хмарі зовнішню адресу дивимося у Service:
kubectl get service ingress-nginx-controller \
-n ingress-nginx \
-o wideЯкщо поле EXTERNAL-IP довго залишається `<pending>`, причина зазвичай не в Ingress YAML. Треба перевірити cloud controller manager, квоти, annotations провайдера або відсутність реалізації LoadBalancer у bare-metal кластері.
На bare-metal для першого тесту можна використати NodePort. Змініть `controller.service.type` на `NodePort`, виконайте Helm upgrade і подивіться виділені порти. За замовчуванням вони потрапляють у діапазон 30000–32767.
kubectl get service ingress-nginx-controller \
-n ingress-nginx
kubectl get nodes -o wideNodePort не означає автоматичний доступ на стандартних 80/443. Зовнішній firewall, NAT, DNS і маршрути до IP вузла залишаються окремими компонентами.
Тестовий застосунок і ресурс Ingress
Створимо окремий namespace і простий HTTP backend. У production замість імперативних команд ці ресурси мають зберігатися у Git як YAML або chart.
kubectl create namespace ingress-demo
kubectl create deployment echo \
--namespace ingress-demo \
--image=hashicorp/http-echo \
-- -text="ingress works"
kubectl expose deployment echo \
--namespace ingress-demo \
--port=80 \
--target-port=5678Тепер створимо `echo-ingress.yaml`. Ресурс Ingress і backend Service повинні бути в одному namespace. Поле `ingressClassName: nginx` явно вказує, який controller має обробляти правило.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: echo
namespace: ingress-demo
spec:
ingressClassName: nginx
rules:
- host: echo.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: echo
port:
number: 80Застосуємо маніфест і перевіримо, як controller його прийняв:
kubectl apply -f echo-ingress.yaml
kubectl get ingress -n ingress-demo
kubectl describe ingress echo -n ingress-demo
kubectl get endpointslices -n ingress-demo \
-l kubernetes.io/service-name=echoDNS A або CNAME record для `echo.example.com` повинен вести на зовнішню адресу ingress-nginx. До зміни DNS правило можна перевірити через curl, підставивши адресу вручну:
curl --resolve echo.example.com:80:INGRESS_IP \
http://echo.example.com/Для локальної діагностики без зовнішнього load balancer підійде port-forward. Це тестовий метод, а не production-схема.
kubectl port-forward \
--namespace ingress-nginx \
service/ingress-nginx-controller 8080:80
curl -H 'Host: echo.example.com' \
http://127.0.0.1:8080/Після перевірки тимчасовий namespace можна видалити, але не робіть цього, якщо він використовується командою для подальшої діагностики.
TLS, оновлення та типові помилки
Для HTTPS ресурс Ingress посилається на Secret типу `kubernetes.io/tls` у тому самому namespace. Secret можна створити вручну для тесту, але у стабільному середовищі сертифікати краще випускати та поновлювати автоматично.
spec:
ingressClassName: nginx
tls:
- hosts:
- echo.example.com
secretName: echo-example-tlsПеред оновленням chart переглядайте release notes, diff values і сумісність із версією Kubernetes. Збережіть поточні values та історію:
helm get values ingress-nginx \
-n ingress-nginx -o yaml > current-values.yaml
helm history ingress-nginx -n ingress-nginx
helm repo updateПотім спочатку виконайте dry run, а реальний upgrade запускайте з тим самим versioned values-файлом через контрольований pipeline. Такий процес природно доповнює побудову та оптимізацію CI/CD.
helm upgrade ingress-nginx \
ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--version NEW_CHART_VERSION \
-f values-ingress-nginx.yaml \
--dry-run=server \
--debugТипова помилка — створити Ingress без controller або з неправильною `ingressClassName`. У такому разі ресурс існує, але маршрут не з’являється. Друга проблема — Service selector не знаходить pod, тому EndpointSlice порожній, а NGINX повертає 502 або 503. Третя — DNS веде не на ту адресу чи firewall не пропускає 80/443.
Четверта помилка — використання annotations без перевірки документації ingress-nginx. Деякі annotations змінюють поведінку NGINX, а небезпечні snippet annotations можуть бути заборонені адміністратором. П’ята — очікування, що bare-metal LoadBalancer з’явиться без MetalLB або іншої зовнішньої реалізації.
Для діагностики дивіться події Ingress, endpoints backend і логи controller, фільтруючи конкретний host:
kubectl describe ingress echo -n ingress-demo
kubectl get endpointslices -n ingress-demo
kubectl logs -n ingress-nginx \
-l app.kubernetes.io/component=controller \
--tail=200 | grep echo.example.comВисновок
Надійне встановлення ingress-nginx складається не лише з однієї Helm-команди. Потрібно перевірити наявні IngressClass, вибрати спосіб зовнішнього доступу, зафіксувати chart version, зберігати values у Git, дочекатися admission webhook і протестувати повний шлях від DNS до backend endpoints.
Робоча послідовність виглядає так: перевірка kube-context, Helm installation у власний namespace, контроль controller pods і Service, тестовий backend, Ingress з `networking.k8s.io/v1` та `ingressClassName`, перевірка через curl, а потім додавання TLS і автоматизованого upgrade-процесу. Якщо маршрут не працює, діагностику слід вести пошарово: зовнішня адреса, firewall, DNS, controller, правило Ingress, Service selector і готовність pod.
Такий підхід дає відтворювану точку входу в кластер і зменшує кількість ситуацій, коли зовнішня помилка маскується випадковою правкою annotations. Після стабілізації HTTP-маршрутизації наступним логічним кроком буде автоматичний випуск TLS-сертифікатів через cert-manager.