Возможны ли обновления без попадания в GKE с externalTrafficPolicy: Local? - PullRequest
1 голос
/ 08 февраля 2020

У меня есть кластер GKE (1.12.10-gke.17).

Я использую nginx -ingress-controller с type: LoadBalancer.

Я установил externalTrafficPolicy: Local на сохранить исходный ip .

Все отлично работает, кроме как во время обновления обновлений. У меня есть maxSurge: 1 и maxUnavailable: 0.

Моя проблема заключается в том, что во время непрерывного обновления я начинаю получать тайм-ауты запроса. Я подозреваю, что балансировщик нагрузки Google по-прежнему отправляет запросы на узел, где модуль имеет значение Terminating, хотя проверки работоспособности не выполняются. Это происходит в течение примерно 30-60 секунд, начиная с момента, когда модуль меняется с Running на Terminating. Через некоторое время все стабилизируется, и traffi c в конечном итоге переходит только на новый узел с новым модулем.

Если балансировщик нагрузки медленен на , чтобы остановить отправку запросов на завершающий модуль, есть ли какой-нибудь способ сделать эти развертываемые развертывания безударными?


Насколько я понимаю, в нормальной k8s службе, где externalTrafficPolicy не является нормальной, балансировщик нагрузки Google просто отправляет запросы на все узлы и позволяет iptables разобраться с этим. Если для pod установлено значение Terminating, iptables обновляется быстро, и трафик c больше не отправляется в этот модуль. Однако в случае, когда externalTrafficPolicy равно Local, если узел, который получает запрос, не имеет модуля Running, то время ожидания запроса истекает, что и происходит здесь.

Если это правильно, тогда я вижу только два варианта

  1. прекратить отправку запросов на узел с Terminating pod
  2. продолжить обслуживание запросов, даже если pod имеет значение Terminating

Мне кажется, что вариант 1 сложен, так как он требует информирования балансировщика нагрузки о том, что модуль готовится к запуску Terminating.

Я добился определенного прогресса в варианте 2, но до сих пор не получил это работает. Мне удалось продолжить обслуживание запросов от модуля, добавив preStop ловушку жизненного цикла, которая просто запускает sleep 60, но я думаю, что проблема в том, что healthCheckNodePort сообщает localEndpoints: 0, и я подозреваю, что что-то блокирует запрос между прибывающий в узел и добирающийся до стручка. Возможно, iptables не маршрутизируется, когда localEndpoints: 0.

Я также настроил проверку работоспособности балансировщика нагрузки Google, которая отличается от readinessProbe и livenessProbe, на «самые быстрые» настройки, например, интервал 1 с, порог 1 сбоя, и я подтвердил что серверная часть балансировщика нагрузки, также называемая узлом k8s, действительно быстро проходит проверку работоспособности, но все равно продолжает отправлять запросы завершающему модулю.

1 Ответ

1 голос
/ 08 февраля 2020

Подобное обсуждение здесь . Хотя он не идентичен, это аналогичный вариант использования.

Все звучит так, как будто он работает как положено.

  • LoadBalancer отправит трафик c на любой работоспособный узел на основе проверки работоспособности LoadBalancer. LoadBalancer не знает об отдельных модулях.

  • Проверка работоспособности помечает узел как нездоровый после того, как порог проверки работоспособности пройден, ie H C отправляется каждые x секунд с x задержкой тайм-аута, x числом неудачных попыток Запросы. Это вызывает задержку между временем, в которое модуль завершает свою работу, и он помечается как нездоровый.

  • Также обратите внимание, что после того, как модуль помечен как notReady, модуль удаляется из службы конечная точка. Если на узле нет другого модуля, traffi c продолжит достигать этого узла (из-за поведения H C, описанного выше), запросы не могут быть перенаправлены из-за externalTrafficPolicy (traffi c остается включенным узел, куда он был отправлен).

Существует несколько способов решения этой проблемы.

  1. Чтобы свести к минимуму время между После прекращения работы модуля и того, что узел помечен как нездоровый, вы можете установить более агрессивную проверку работоспособности. Проблема в том, что чрезмерно чувствительный H C может вызывать ложные срабатывания, обычно увеличивает накладные расходы на узле (дополнительные запросы проверки работоспособности) и не полностью устраняет неудавшиеся запросы.

  2. Иметь достаточно стручков, чтобы на каждом узле всегда было как минимум 2 стручка. Так как служба удаляет модуль из конечной точки, как только он переходит в notReady, запросы будут просто отправляться в работающий модуль. Недостатком здесь является то, что у вас будут дополнительные накладные расходы (больше стручков) или более плотная группировка (более уязвимая к сбоям). Это также не полностью устранит неудавшиеся запросы, но их будет невероятно мало.

  3. Настройте H C и ваш контейнер для совместной работы: 3a. Имейте H C конечная точка должна быть отделена от обычного пути, который вы используете. 3b. Настройте контейнер readinessProbe так, чтобы он соответствовал основному пути, по которому ваш контейнер обслуживает трафик c (он будет отличаться от пути LB H C) 3 c. Сконфигурируйте ваше изображение так, чтобы при получении SIGTERM первым делом go был путь H C. 3d. Сконфигурируйте образ для постепенного истощения всех соединений после получения SIGTERM вместо немедленного закрытия всех сеансов и соединений.

Это должно означать, что текущие сеансы будут корректно завершаться, что уменьшает количество ошибок. Это также должно означать, что узел начнет отказывать зонды H C, даже если он готов обслуживать обычный трафик c, это дает время для того, чтобы узел был помечен как нездоровый, и LB прекратит посылать трафик c на до того, как он больше не сможет обслуживать запросы.

Проблема с этим последним вариантом в 2 раза. Во-первых, его сложнее настроить. Другая проблема заключается в том, что это означает, что вашим модулям потребуется больше времени для завершения, поэтому обновление обновлений займет больше времени, как и любой другой процесс, который полагается на постепенное завершение модуля, например, опустошение узла. Вторая проблема не так уж плоха, если вам не нужен быстрый поворот.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...