Вход k8s nginx возвращает случайную ошибку 502 при загрузке

мы используем nginx (1.15.8.1) в качестве входного контроллера в нашем кластере k8s (v.1.17), управляемом Rancher (2.5.7).

До сих пор это работало довольно хорошо, но теперь мы настроили собственный модуль API, к которому можно получить внешний доступ через вход.

Теперь, выполняя некоторое нагрузочное тестирование API, запуская запрос каждую секунду в API, случайным образом возвращает «502 Bad Gateway» каждые пару запросов. Однако не периодически.

      <html>
<head><title>502 Bad Gateway</title></head>
<body>
<center><h1>502 Bad Gateway</h1></center>
<hr><center>openresty/1.15.8.1</center>
</body>
</html>

Соответствующий журнал входного контроллера:

      2021/04/11 11:02:48 [error] 25430#25430: *55805583 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: xxx, server: xxx, request: "POST /api/v1/xxx HTTP/2.0", upstream: "http://xxx/api/v1/xxx", host: "xxx"

Мы запускали тот же контейнер в среде, отличной от K8s, что и Docker-контейнер, где мы никогда раньше не сталкивались с этой проблемой, поэтому на данный момент я предполагаю, что это не проблема реализации контейнера/API.

Мои мысли были:

1- определение службы, которое абстрагирует модуль API, не может маршрутизировать трафик в модуль и поэтому отвечает с кодом 502.

-> Я изменил вход, чтобы напрямую перейти к рабочей нагрузке для тестирования, чтобы понять, в этом ли проблема. Тогда я получаю те же ошибки, поэтому определение службы, похоже, не является проблемой.

2- тайм-аут во входном ресурсе (поскольку сообщение отвечает с задержкой) может привести к сбою маршрутизации.

-> я установил таймауты на

          nginx.ingress.kubernetes.io/proxy-connect-timeout: 1d
    nginx.ingress.kubernetes.io/proxy-read-timeout: 1d
    nginx.ingress.kubernetes.io/proxy-send-timeout: 1d

но снова столкнулся с той же ошибкой. так что это тоже не проблема

3- ошибка в контейнере API (наиболее маловероятная), который отправляет обратно ошибки.

-> проверка журналов контейнера показывает, что отсутствующий запрос (который вернул 502 или что-то подобное, что затем оценивается на входном уровне как 502) никогда не был получен контейнером API. Более того, это вообще не имеет смысла с точки зрения маршрутизации трафика.

4. На последнем этапе я увеличил модуль до двух контейнеров, и все работает отлично.

Резюме: с учетом приведенных выше результатов я подвожу итог: 1 - определение сервиса не может быть проблемой (тест 1)2- тайм-ауты входа не могут быть проблемой 3- сам API не может быть проблемой

Если подумать о тесте 4, это указывает на то, что доступность контейнера в модулях может быть проблемой, поскольку API отбрасывает запросы (что приводит к ошибке 502), когда контейнер находится в определенном состоянии (это объясняет, почему он работает с 2 масштабирование контейнеров) ИЛИ где-то в пути истекает время маршрутизации трафика.

В настоящее время у меня нет дальнейших идей, куда идти дальше. Любой намек приветствуется.

1 ответ

если вы используете входящий обратный прокси-сервер nginx, возможно, причина в этом. Попробуйте проверить в Configmap наличиеproxy-next-upstreamнастройки и расширить его для обработкиhttp_502случай.
Также включитеretry-non-idempotentесли запрос, получивший 502, — это POST, LOCK, PATCH, если это безопасно для вашего приложения.

Я предполагаю: когда внутренний модуль достигает предела нагрузки (или перезапуска модуля), он «отклоняет» новый запрос, и обратный прокси-сервер nginx более чувствителен к этому отклонению. Без nginx-ingress k8s выполняет балансировку нагрузки и может справляться со всем лучше, ставя в очередь вместо отклонения.

Другие вопросы по тегам