Акция Панель управления Ispmanager для VDS — первый месяц бесплатно
до 31.07.2026 Подробнее
Выберите продукт

Kubernetes Ingress: как диагностировать 502/504 между ingress-controller, Service и Pod

502/504 на Kubernetes Ingress чаще всего возникают на стыке ingress-controller → Service → Pod: нет endpoints, Pod не Ready, перепутаны порты, не совпал протокол, сработали таймауты или рвутся keepalive-соединения. Ниже — быстрый чек-лист и типовые фиксы с командами.
Kubernetes Ingress: как диагностировать 502/504 между ingress-controller, Service и Pod

Что означают 502 и 504 на Ingress и почему это почти всегда «стык»

Когда вы видите kubernetes ingress 502 или ingress 504, важно помнить: Ingress не «исполняет приложение», он проксирует запросы дальше. В типичной схеме NGINX Ingress маршрут такой:

Client → LoadBalancer/NodePort → ingress-controller (NGINX) → Service → Endpoints/EndpointSlice → Pod (containerPort)

502 Bad Gateway означает, что NGINX как прокси не смог корректно получить ответ от upstream: не установилось соединение, upstream закрыл его, ответ не похож на ожидаемый протокол (HTTP/TLS), произошёл reset.

504 Gateway Timeout означает, что NGINX дотянулся до upstream, но не дождался ответа в пределах таймаутов. Частый текст в логах: upstream timed out.

В Kubernetes 502/504 чаще всего — симптом того, что Ingress «видит» Service, но фактически не может стабильно дойти до готового Pod по правильному порту и протоколу.

Быстрый чек-лист: где искать причину за 5–10 минут

Если времени мало, идите по порядку: это быстрее всего приводит к конкретному месту поломки.

  1. Понять, кто возвращает 502/504: ingress-controller или внешний прокси/балансировщик перед ним.
  2. Проверить, есть ли у Service реальные endpoints (EndpointSlice/Endpoints).
  3. Проверить, что Pod действительно Ready и readinessProbe не «флапает».
  4. Проверить соответствие портов: Ingress backend port → Service port → targetPort → containerPort.
  5. Посмотреть логи ingress-controller и вытащить точную формулировку: upstream timed out, connect() failed, no live upstreams.
  6. Проверить таймауты NGINX Ingress и реальное время ответа приложения (p95/p99).
  7. Проверить keepalive и закрытие соединений приложением/sidecar.

Если ваш Ingress/контроллер живёт в облегчённом кластере, полезно держать под рукой сравнение вариантов (Traefik/NGINX/HAProxy) и их поведения по таймаутам/балансировке: Ingress-контроллеры в k3s: что выбрать и как отличаются.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Шаг 1. Убедиться, что 502/504 отдаёт именно ingress-controller

Надёжный способ — посмотреть логи ingress-controller в момент запроса. Если записи появляются с вашим host/path, проблема почти наверняка на участке ingress-controller → Service/Pod.

kubectl -n ingress-nginx get pods -o wide
kubectl -n ingress-nginx logs deploy/ingress-nginx-controller --tail=200

Если 502/504 приходит, но в логах контроллера «тишина», ошибку может возвращать внешний L7/L4 балансировщик или другой прокси до Ingress.

Шаг 2. Service без endpoints: самая частая причина 502

Ситуация выглядит так: Ingress ссылается на Service, Service существует, но у него нет endpoints. Тогда проксировать просто некуда, и NGINX отдаёт 502 (иногда 503) или пишет, что upstream пустой.

Проверяем Service и соответствие selector’ов:

kubectl -n app get svc my-service -o yaml
kubectl -n app get pods -l app=my-app -o wide

Дальше смотрим Endpoints/EndpointSlice:

kubectl -n app get endpoints my-service -o yaml
kubectl -n app get endpointslices -l kubernetes.io/service-name=my-service -o yaml

Проверка Service, selectors и EndpointSlice при ошибках 502 на Ingress

Почему endpoints могут быть пустыми

  • Неверный selector у Service: метки не совпадают с Pod.
  • Pod не проходит readinessProbe и не попадает в ready endpoints.
  • Service типа ExternalName или нестандартная схема, где Ingress ожидает обычные endpoints.
  • Ошибка с namespace: Ingress и Service в разных namespaces, а ссылка сделана «как будто» в одном.

Классика: Service смотрит на app: backend, а Pod помечен app: back. В манифестах «всё есть», но endpoints пустые, и Ingress закономерно падает в 502.

Шаг 3. Readiness probe и «флапающие» Pods: причина и 502, и 504

Если endpoints то появляются, то исчезают, ошибки становятся «плавающими»: часть запросов проходит, часть уходит в 502/504, особенно после релиза или под нагрузкой.

Смотрим события Pod и статусы проб:

kubectl -n app describe pod my-pod-xxxxx
kubectl -n app get pod my-pod-xxxxx -o jsonpath='{.status.containerStatuses[0].ready}'; echo

Проверьте:

  • readiness проверяет правильный порт/путь (часто путают containerPort и порт Service).
  • проба отражает реальную «готовность» (если приложение стартует 40 секунд, а проба начинает падать на 5-й — endpoints будут пустеть).
  • тайминги: initialDelaySeconds, periodSeconds, timeoutSeconds, failureThreshold.

Частый анти-паттерн

Readiness ходит на тяжёлый endpoint (например, / с рендерингом). Под нагрузкой он начинает отвечать медленно, readiness падает, Pod выкидывается из endpoints, Ingress начинает сыпать ошибками, нагрузка перераспределяется на оставшиеся Pod и добивает их. Для readiness лучше иметь лёгкий /healthz без внешних зависимостей или с адекватной деградацией.

Шаг 4. Несовпадение портов Service/Pod: «внутри что-то работает, но Ingress даёт 502»

В Kubernetes легко ошибиться портом в четырёх местах:

  • порт в Ingress backend (ссылка на Service port или named port);
  • spec.ports[].port у Service;
  • spec.ports[].targetPort у Service (число или имя);
  • containerPort у контейнера (и на каком порту реально слушает процесс).

Проверяем связку одним проходом:

kubectl -n app get ingress my-ing -o yaml
kubectl -n app get svc my-service -o yaml
kubectl -n app get pod -l app=my-app -o yaml

Симптомы в логах Ingress

  • connect() failed (111: Connection refused) while connecting to upstream — IP:port доступен, но на порту никто не слушает.
  • no live upstreams — как правило, нет готовых endpoints.

Отдельно проверьте named ports: если Service использует targetPort: http, то в Pod в ports[].name должен существовать порт с именем http.

Шаг 5. Диагностика сети: достучаться до Service «как NGINX»

Чтобы отделить проблему приложения от маршрутизации/политик, проверьте доступность сервиса из кластера.

Проверка DNS и ответа через ClusterIP:

kubectl -n app get svc my-service -o wide
kubectl -n app run tmp-shell --rm -i --tty --image=busybox:1.36 -- sh

Внутри временного Pod:

nslookup my-service
wget -S -O - http://my-service:80/healthz

Если сервис из кластера не отвечает стабильно, Ingress не «исправит» это настройками. Тогда копаем приложение, порты, NetworkPolicy, CNI, kube-proxy/IPVS и ресурсы нод.

Шаг 6. Таймауты NGINX Ingress: когда 504 — это ожидаемо, но нужно настроить

Если обработчик объективно долгий (отчёты, экспорт, тяжёлые запросы к БД), вы получите ingress 504. Типичный лог:

upstream timed out (110: Operation timed out) while reading response header from upstream

Это означает: NGINX ждал заголовки/данные от upstream и не дождался.

Какие таймауты важны

  • proxy_connect_timeout — время на установку соединения до upstream.
  • proxy_read_timeout — сколько ждать данных/ответа от upstream.
  • proxy_send_timeout — сколько ждать, пока NGINX отправляет запрос upstream’у.

В NGINX Ingress это обычно задаётся аннотациями Ingress (конкретные имена зависят от контроллера/версии). Практика простая: если handler реально работает 120 секунд, а read timeout 60 — будет 504 при полностью «живом» приложении.

Рабочий подход:

  • Измерить время ответа приложения (p95/p99), а не «поставить 10 минут на всякий случай».
  • Выставить read timeout немного выше p99 и продумать отмену запроса (cancellation) и идемпотентность.
  • Для стриминга (SSE/stream) обеспечить периодические данные, иначе соединение может считаться «молчаливым» и будет разрываться.
FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Шаг 7. Keepalive и разрывы соединений: скрытая причина 502

Про keepalive вспоминают, когда ошибка выглядит так: после простоя/релиза первые запросы проходят, а затем периодически появляются 502, особенно при высокой параллельности.

Типовые сценарии:

  • Ingress держит keepalive-соединение к Pod, а приложение/sidecar закрывает его по своему idle timeout. Следующий запрос пытается пойти по «полумёртвому» соединению и ловит 502.
  • HTTP/1.1 keepalive включён, но приложение некорректно обрабатывает повторное использование соединения.
  • Между NGINX и Pod есть ещё один прокси (например, mesh sidecar) — таймауты и лимиты должны совпадать по смыслу.

Что делать:

  • Сравнить idle timeout на стороне ingress-controller и приложения/sidecar.
  • Проверить, нет ли агрессивного закрытия соединений на уровне приложения или промежуточного прокси.
  • В логах искать: upstream prematurely closed connection, connection reset by peer.

Шаг 8. Когда виноват не Ingress: перегруз нод, DNS, conntrack и политики

Иногда 504 — это не «медленный handler», а деградация инфраструктуры или сетевого контура:

  • Ноды перегружены по CPU: приложение «живое», но ему не дают времени на исполнение, очередь запросов растёт.
  • Проблемы с DNS внутри кластера (CoreDNS): часть компонентов начинает «подвисать» на резолве.
  • Забит conntrack/NAT на нодах: начинаются потери и timeouts.
  • NetworkPolicy режет трафик от ingress-controller до namespace приложения.

Быстрые проверки:

kubectl top nodes
kubectl -n ingress-nginx top pods
kubectl -n kube-system get pods -l k8s-app=kube-dns -o wide
kubectl -n app get networkpolicy

Проверка нагрузки нод, DNS и сетевых политик при ошибках 504 в Kubernetes

Типовые сообщения в логах NGINX Ingress и перевод в действия

upstream timed out

Почти всегда: измерить время ответа, затем увеличивать proxy_read_timeout (разумно), оптимизировать обработчик или выносить долгие операции в async/queue. Для стриминга — убедиться, что соединение не «молчит».

connect() failed (111: Connection refused)

Upstream IP:port есть, но на порту никто не слушает. Проверяйте порты, targetPort, именованные порты, реальный порт процесса в контейнере, а также readiness.

no live upstreams

У Service нет готовых endpoints. Проверяйте EndpointSlice/Endpoints, selectors, readiness и namespace.

upstream prematurely closed connection / connection reset by peer

Upstream сам закрыл соединение: рестарт/краш приложения, лимиты, несогласованный keepalive, перегруз. Смотрите логи приложения и события Pod.

Минимальный набор проверок, который стоит автоматизировать

  • Метрики ingress-controller: доля 5xx по Ingress/host, p95/p99 latency, upstream errors.
  • Алерты на пустые endpoints у критичных Service (EndpointSlice count = 0).
  • Алерты на flapping readiness (частые переходы Ready/NotReady).
  • Дашборд по ресурсам нод и Pod: CPU throttling, memory pressure, рестарты.

Если параллельно упираетесь в особенности кеширования/частичных ответов и поведение прокси, может пригодиться практический разбор: HTTP Range и кеширование в NGINX/Apache: типичные грабли.

Короткий рецепт поиска причины: от симптома к фиксу

  1. Есть kubernetes ingress 502 → смотрим логи ingress-controller → ищем no live upstreams или connect() failed → проверяем endpoints и порты.
  2. Есть ingress 504 → ищем upstream timed out → измеряем реальное время ответа → настраиваем таймауты и/или ускоряем обработчик.
  3. Ошибки «плавают» → проверяем readinessProbe, стабильность endpoints, затем keepalive и рестарты Pod.

Главная идея: не лечите 502/504 только настройками Ingress. В большинстве случаев это несогласованность между Service/Endpoints/Pod readiness или реальная производительность приложения под нагрузкой.

Если вы выносите такие сервисы на отдельные ресурсы (выделенные ноды, отдельные ingress-контроллеры, тестовые стенды), удобнее держать инфраструктуру на VDS: проще масштабировать, воспроизводить инциденты и изолировать шумных соседей.

Поделиться статьей

Вам будет интересно

Debian/Ubuntu: mount: wrong fs type, bad option, bad superblock — как быстро найти и исправить причину OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: mount: wrong fs type, bad option, bad superblock — как быстро найти и исправить причину

Ошибка mount: wrong fs type, bad option, bad superblock в Debian/Ubuntu может означать и простую опечатку в имени раздела, и пробл ...
Debian/Ubuntu: XFS metadata corruption и emergency read-only — пошаговое восстановление OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: XFS metadata corruption и emergency read-only — пошаговое восстановление

Если XFS-раздел внезапно стал доступен только для чтения, а сервер ушёл в emergency mode, главное — не спешить. Разберём безопасны ...
Debian/Ubuntu: как исправить Failed to fetch при apt update OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить Failed to fetch при apt update

Ошибка Failed to fetch при apt update в Debian и Ubuntu обычно связана не с самим APT, а с DNS, сетью, зеркалом, прокси, временем ...