/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 Вътре в всеки контейнер по подразбиране ще изглежда така:

nameserver 100.64.0.10
search namespace.svc.cluster.local svc.cluster.local cluster.local 
eu-west-1.compute.internal
options ndots:5

Както можем да видим, тук има три директиви:

  1. DNS сървърът е IP на услугата kube-dns
  2. Посочени са 4 локални търсещи домейна search
  3. Има опция ndots:5

Интересната част от тази конфигурация е как локалните търсещи домейни и настройките 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 преди и след като превключихме няколко имена на хостове, настроени в приложението ни, на напълно определени.

/etc/resolv.conf для Kubernetes pods, опция ndots:5, как это может негативно сказаться на производительности приложения

На следващата диаграма е показана латентността на приложението преди и след като превключихме няколко имена на хостове, настроени в приложението ни, на пълни (вертикалната синя линия обозначава разгръщането):

/etc/resolv.conf для Kubernetes pods, опция ndots:5, как это может негативно сказаться на производительности приложения

Решение #1 — използване на напълно определени имена

Ако имате малко статични външни имена (т.е. определени в конфигурацията на приложението), за които създавате много връзки, може би най-простото решение е да ги превключите на напълно определени, просто добавяйки . в края.

Това не е окончателно решение, но помага бързо, макар и не напълно, да подобри ситуацията. Този патч приложихме, за да решим нашия проблем, резултатите от което бяха показани на екранните снимки по-горе.

Решение #2 — персонализация ndots в dnsConfig

В Kubernetes 1.9 в алфа режим се появи функционалност (бета версия v1.10), която позволява по-добър контрол над параметрите на DNS чрез свойството на пода в dnsConfig. Сред другото, тя позволява да се конфигурира стойността ndots за конкретен под, т.е.

apiVersion: v1
kind: Pod
metadata:
  namespace: default
  name: dns-example
spec:
  containers:
    - name: test
      image: nginx
  dnsConfig:
    options:
      - name: ndots
        value: "1"

Източници

Също така прочетете други статии в нашия блог:

Източник: habr.com

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster