ProHoster > Блог > адміністрування > /etc/resolv.conf для Kubernetes pods, опція ndots:5, як це може негативно позначитися на продуктивності програми
/etc/resolv.conf для Kubernetes pods, опція ndots:5, як це може негативно позначитися на продуктивності програми
Нещодавно ми запустили Kubernetes 1.9 на AWS за допомогою Kops. Вчора, під час плавного викочування нового трафіку на найбільший з наших кластерів Kubernetes, я почав помічати незвичайні помилки дозволу імен DNS, залоговані нашим додатком.
На GitHub досить довго про це говорилитому я теж вирішив розібратися. У результаті я зрозумів, що в нашому випадку це викликано підвищеним навантаженням kube-dns и dnsmasq. Найцікавішим і найновішим для мене виявилася сама причина значного збільшення трафіку DNS-запитів. Про це і про те, що з цим робити, мій пост.
Роздільна здатність DNS всередині контейнера - як і в будь-якій системі Linux - визначається конфігураційним файлом /etc/resolv.conf. Типово Kubernetes dnsPolicy це ClusterFirst, що означає, що будь-який DNS-запит буде перенаправлений на dnsmasq, запущений у поді kube-dns всередині кластера, який, у свою чергу, перенаправить запит на додаток kube-dnsякщо ім'я закінчується суфіксом кластера, або, в іншому випадку, до DNS серверу вищого рівня.
Файл /etc/resolv.conf всередині кожного контейнера за умовчанням виглядатиме так:
Цікавою частиною цієї конфігурації є те, як локальні пошукові домени та налаштування ndots:5 уживаються разом. Щоб зрозуміти, необхідно розібратися, як працює дозвіл DNS для неповних імен.
Що таке повне ім'я?
Цілком певне ім'я — це ім'я, для якого не буде виконуватися локальний пошук, і ім'я вважатиметься абсолютним під час дозволу імен. За згодою, програмне забезпечення DNS вважає ім'я повністю визначеним, якщо воно закінчується точкою (.), і не повністю визначеним інакше. Тобто google.com. повністю визначено, а google.com - немає.
Як обробляється неповне ім'я?
Коли програма підключається до віддаленого хоста, вказаного в імені, роздільна здатність імен DNS зазвичай виконується за допомогою системного виклику, наприклад, getaddrinfo(). А ось якщо неповне ім'я (не закінчується на .), цікаво, чи спробує системний виклик спочатку дозволити ім'я як абсолютне, або спочатку пройде через локальні пошукові домени? Це залежить від опції ndots.
З мануалу по resolv.conf:
ndots:n
устанавливает порог для количества точек, которые должны появиться в имени, прежде чем будет сделан начальный абсолютный запрос. Значение по умолчанию для n равно 1, что означает, что если в имени есть какие-либо точки, имя будет сначала опробовано как абсолютное имя, прежде чем к нему будут добавлены какие-либо элементы списка поиска.
Це означає, що якщо для ndots задано значення 5, а ім'я містить менше 5 точок, системний виклик спробує дозволити його послідовно, спочатку пройшовши по всіх локальних пошукових доменів, і, у разі невдачі, нарешті дозволить його як абсолютне ім'я.
Чому ж ndots:5 може негативно позначитися на продуктивність програми?
Як ви розумієте, якщо ваша програма використовує багато зовнішнього трафіку, для кожного встановленого TCP-з'єднання (або, точніше, для кожного дозволеного імені) воно видаватиме 5 DNS-запитів, перш ніж ім'я буде правильно дозволено, тому що воно спочатку пройде через 4 локальних пошукових доменів, а в кінці видасть запит дозволу абсолютного імені.
На наступній діаграмі показано сумарний трафік на наших 3 модулях kube-dns до та після того, як ми переключили кілька імен хостів, налаштованих у нашому додатку, повністю визначені.
На наступній діаграмі показано затримку програми до і після того, як ми переключили кілька імен хостів, налаштованих у нашому додатку, на повні (вертикальна синя лінія це розгортання):
Рішення #1 - використовувати повністю певні імена
Якщо у вас мало статичних зовнішніх імен (тобто визначених у конфігурації програми), до яких ви створюєте велику кількість з'єднань, можливо, найпростіше рішення - переключити їх на певні, просто додавши. в кінці.
Це не остаточне рішення, але допомагає швидко, хай і не чисто, покращити ситуацію. Цей патч ми застосували для вирішення нашої проблеми, результати чого були показані на скріншотах вище.
Рішення #2 - кастомізація ndots в dnsConfig
У Kubernetes 1.9 в альфа режимі з'явився функціонал (бета-версія v1.10), який дозволяє краще контролювати параметри DNS через властивість подавання dnsConfig. Серед іншого він дозволяє налаштувати значення ndots для конкретного пода, тобто.