суббота, 3 июля 2021 г.

Задержка ответа DNS до 5 секунд или более в GKE

Изначально эта проблема попала ко мне с описанием "Нестабильная работа Solr на всех окружениях". В админке Drupal сайта тестирование настроек Solr в большинстве случаев завершалось с ошибкой, но сам поиск хоть и очень медленно, но работал.

Сперва выполнил пробный запрос к Solr из одного из контейнеров чтобы подтвердить наличие проблемы - с приличной задержкой, но запрос выполнился. Повторил запрос в цикле и получилось что время выполнения запроса "скачет" от 100 миллисекунд до 12 секунд. Чтобы исключить проблемы с DNS попробовал подключиться к Solr по IP, а не по FQDN - запрос выполняется быстро. Повторяю тест используя IP вместо FQDN в цикле и результат находится в пределах 100 - 150 миллисекунд. Выходит что проблема в DNS, но пока не ясно виноват kube-dns или вышестоящий DNS сервер к которому обращается kube-dns. Попробовал обращаться к другим доменам, например www.google.com - поведение аналогичное. Описание проблемы меняется с "Нестабильная работа Solr на всех окружениях" на "Нестабильная работа DNS в GKE на всех окружениях".

Для проверки вышестоящего сервера запустил отдельный под с "dnsPolicy: Default" чтобы исключить kube-dns из уравнения. Тест в цикле с использованием FQDN стал выполнятся быстро. Повторил тест несколько раз чтобы исключить случайное совпадение, но каждый раз запрос укладывался в 200 миллисекунд.

С этого момента главным подозреваемым становится kube-dns. Пока шла инвестигация проблема перестала воспроизводиться на тестовом сайте в DEV/STAGE окружениях и стабильно воспроизводилась только в PROD. Такая "самопочинка" DEV/STAGE напоминает "подземный стук", но ничего само не ломается и не чинится - обязательно что-то где-то поменялось, но пока не ясно что и где.

Начинаю размышлять о разнице между DEV/STAGE и PROD и почему проблема сама "починилась" на DEV/STAGE, но продолжает воспроизводиться на PROD. Версия GKE на всех окружениях одинаковая как и настройки самих кластеров. Различается только количество нод в кластерах, но как это может влиять на работу kube-dns пока не ясно.

Поиск в интернете вывел на репорты на Github про задержку в 5 секунд для DNS в Kubernetes, к примеру #56903 (DNS intermittent delays of 5s), которые датированы еще 2017-2018 годами. Читаю описание и нахожу упоминание о проблемах с conntrack когда приложение находится на той же ноде, где запущен kube-dns. Проверяю состояние conntrack на нодах PROD кластера и вижу, что есть много ошибок и их счетчики растут по мере прохождения теста.

Выходит что проблема зависит от того, где запущен под из которого я провожу тест. В PROD кластере сейчас только две ноды, а поскольку kube-dns запускает по две реплики, то совпадение есть для любого пода тестового сайта. Но в DEV/STAGE нод больше и после нескольких редеплоев тестовый сайт переместился на другие ноды и проблема "полечилась". Зная теперь куда смотреть возвращаюсь в DEV кластер и проверяю на каких нодах запущен kube-dns.

$ kubectl -n kube-system get pods -l k8s-app=kube-dns -o wide

Далее проверяю какие поды ещё запущены на этих нодах

$ kubectl describe node <node1>
$ kubectl describe node <node2>

Прогоняю тест по списку подов, которые запущены на этих нодах и проблема воспроизводится в каждом из них. На всякий случай выборочно проверяю поды с других нод и в них проблема не воспроизводится. Аналогичная ситуация и на STAGE. Т.е. DEV/STAGE на самом деле не "починились магически", просто проблема "спряталась" из-за перемещения подов тестового сайта на другие ноды из-за редеплоев этого тестового сайта.

Теперь об вариантах исправлении этой проблемы, которые я нашел в интернете:

  • Использовать NodeLocal DNSCache в GKE.
  • Добавить "options single-request-reopen" в /etc/resolv.conf. Работает только для резолвера из libc6 и не подходит для Alpine в котором используется musl.

Второй вариант не подошел, т.к. наши образы Docker на базе Alpine, а вот включение NodeLocal DNSCache помогло. Активация настройки на существующем кластере заняла больше 20 минут, но ноды обновляются только во время очередного maintenance периода (подробности тут).

Тестирование показало отличный результат ценой небольшого увеличения потребления ресурсов на каждой из нод.

Полезные ссылки:

  1. https://github.com/kubernetes/kubernetes/issues/56903
  2. https://tech.xing.com/a-reason-for-unexplained-connection-timeouts-on-kubernetes-docker-abd041cf7e02
  3. https://habr.com/ru/post/503032/
  4. https://blog.quentin-machu.fr/2018/06/24/5-15s-dns-lookups-on-kubernetes/

Комментариев нет:

Отправить комментарий