Время отклика Kubenet ухудшено, решено с помощью hostNetwork: правда, с приложением Unicorn
Я пытаюсь отладить проблему, которая решается с помощью hostNetwork: true
, Установка k8s использует kubenet, а версия k8s 1.9.8.
Установка выполняется с помощью kops на AWS с использованием экземпляров m4.xlarge и c4.xlarge.
Проблема заключается в следующем:
Когда мы перенесли это приложение в kubernetes, время отклика (процентиль 95) для определенной конечной точки увеличилось примерно на 20-30%.
Эта проблема решается, однако, при использовании hostNetwork: true
в ямле. Производительность такая же, как на виртуальных машинах для этой конечной точки, т. Е. Процентиль 95 для времени отклика одинакова для этой конечной точки.
Я спрашивал об этом в рабочие часы кабинета 18 января (да, некоторое время назад!) И hostNetwork: true
Обходной путь подойдет туда.
Обратите внимание, что все содержимое Kube-прокси может быть отброшено, так как это увеличенное время отклика видно при измерении в самом приложении. Я имею в виду, что приложение ruby измеряет время, которое требуется, и отправляет его сборщику журналов. На этот раз, то есть, поскольку запрос начинает обрабатываться приложением до его завершения, он уже показывает снижение производительности. Таким образом, Kube-прокси и тому подобное вне уравнения.
Стручок имеет 3 контейнера:
- Nginx
- Сборщик бревен
- Приложение (приложение ruby, работающее с единорогом)
Эти приложения также находятся в режиме виртуальных машин
Что я пробовал:
- Нашел способ воспроизвести с помощью ab(apache benchmark)
ab -c 1 -n 1000 'https://...
- То же самое происходит с http, а не https
- Я попытался удалить контейнер nginx, но это ничего не меняет. Сборщик журналов используется поверх localhost, и то же самое делается на виртуальных машинах, которые не демонстрируют проблему.
- Я пытался использовать unix-сокеты между nginx и приложением вместо localhost, но это тоже ничего не изменило.
- Пробовал использовать те же экземпляры (m4.xlarge) с EKS: происходит то же самое. Хотя стоимость производительности не использует
hostNetwork: true
меньше, около 10%. Обратите внимание, что EKS не использует kubenet и использует свое собственное сетевое наложение на основе какого-либо открытого источника. - Пробовал использовать другую конечную точку, которая просто возвращает строку (ставит "ОК"), и проблема не возникает
- Пробовал использовать конечную точку, которая возвращает несколько МБ (например,
"Die" * 10 * 1024 * 1024
) и вопроса тоже не бывает - Пробовал ту же самую конечную точку, которая имеет проблему с различными параметрами строки запроса, таким образом, ответ является большим (9 МБ) или коротким (130 КБ), и оба надежно воспроизводят проблему
- Попробовал приложение nodejs, которое возвращает похожие jsons из аналогичных источников, и проблема отсутствует (ни с короткими / длинными ответами). Что может делать дальше:
Итак, я пытаюсь отладить эту проблему, чтобы понять, что это такое, и, надеюсь, перестать использовать hostNetwork: true
, Там, кажется, путь, чтобы копать дальше:
Попробуйте другие CNI (EKS показал меньшее снижение производительности), чтобы увидеть, если производительность меняется
Посмотрите, что делает эта конечная точка или как она взаимодействует с единорогом и всем стеком. Одно большое отличие состоит в том, что единорог - это один процесс на запрос (синхронный), а nodejs - нет.
Попробуйте использовать более новые машины (m5/c5), чтобы увидеть, не снижают ли они производительность. Но, поскольку эта проблема не существует с текущими экземплярами, использующими их в качестве виртуальных машин, кажется, что, если это поможет, будет только скрыть проблему
Эта конечная точка, имеющая проблему с perf, является конечной точкой в ruby, которая читает базу данных и возвращает json. С базой данных, хостом, сетью все выглядит нормально (мониторинг процессора, дискового ввода-вывода, подкачки и т. Д. С помощью vmstat, наших обычных инструментов, консоли AWS, проверка kern.log, sysloca и тому подобного)
Случайно, у вас был подобный опыт? Или у вас есть другие идеи о том, как продолжить отладку этой проблемы?
Любые идеи или любая помощь более чем приветствуются!
Родриго
2 ответа
Кажется, проблема в https://github.com/kubernetes/kubernetes/issues/56903
Обходные пути, упомянутые там (как dnsPolicy: Default
Решите вопрос для меня.
Эти два поста объясняют проблему подробно: https://www.weave.works/blog/racy-conntrack-and-dns-lookup-timeouts и https://blog.quentin-machu.fr/2018/06/24/5-15s-dns-lookups-on-kubernetes/
А также предоставить некоторые обходные пути.
Короче говоря: в nf существует состояние гонки, которое влияет на протоколы без установления соединения (например, UDP) при выполнении DNAT/SNAT. Ребята плетения прислали патч, чтобы исправить большинство гонок. Чтобы обойти это, вы можете использовать внешний DNS (т.е. не Kube-DNS, так как он предоставляется через службу и, следовательно, использует DNAT), установить флаги для glibc (но не работают для Musl), использовать минимальную задержку с tc
, так далее.
Примечание: использование dnsPolicy: Default
делает трюк, потому что он использует внешний DNS-сервер (то есть не размещен в kubernetes и не доступен через службу, которая выполняет DNAT).
Я проверю флаги glibc для моего кластера, хотя dnsPolicy: Default
Для меня эта проблема решается, так как мы используем разрешение службы DNS k8s в некоторых приложениях.
Звучит так, как будто вы испытываете накладные расходы из-за NAT Докера.hostNetwork: true
предоставляет доступ к сети хоста для pod/ контейнера (ов), в отличие от использования NAT, обеспечивая лучшую производительность... Но снижая безопасность.
Надеюсь это поможет!