/etc/resolv.conf dla podów Kubernetes, opcja ndots:5, jak może to negatywnie wpłynąć na wydajność aplikacji

/etc/resolv.conf dla podów Kubernetes, opcja ndots:5, jak może to negatywnie wpłynąć na wydajność aplikacji

Niedawno uruchomiliśmy Kubernetes 1.9 na AWS przy użyciu Kops. Wczoraj, płynnie wdrażając nowy ruch do największego z naszych klastrów Kubernetes, zacząłem zauważać nietypowe błędy rozpoznawania nazw DNS rejestrowane przez naszą aplikację.

Jest sporo na ten temat na GitHubie przemówił, więc też postanowiłem to rozgryźć. W końcu zdałem sobie sprawę, że w naszym przypadku jest to spowodowane zwiększonym obciążeniem kube-dns и dnsmasq. Najbardziej interesującą i nową rzeczą dla mnie była sama przyczyna znacznego wzrostu ruchu żądań DNS. Mój post jest o tym i o tym, co z tym zrobić.

Rozpoznawanie DNS wewnątrz kontenera – jak w każdym systemie Linux – jest określane przez plik konfiguracyjny /etc/resolv.conf. Domyślny Kubernetes dnsPolicy to ClusterFirst, co oznacza, że ​​każde żądanie DNS zostanie przekazane do dnsmasq, bieganie w kapsule kube-dns wewnątrz klastra, który z kolei przekaże żądanie do aplikacji kube-dns, jeśli nazwa kończy się sufiksem klastra, lub w przeciwnym razie do serwera DNS wyższego poziomu.

plik /etc/resolv.conf wewnątrz każdego kontenera wartość domyślna będzie wyglądać następująco:

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

Jak widać, istnieją trzy dyrektywy:

  1. Serwer nazw to adres IP usługi kube-dns
  2. Określono 4 lokalne domeny wyszukiwania search
  3. Jest taka opcja ndots:5

Interesującą częścią tej konfiguracji jest sposób wyszukiwania lokalnych domen i ustawień ndots:5 dogadywać się razem. Aby to zrozumieć, musisz zrozumieć, jak działa rozpoznawanie DNS dla niekwalifikowanych nazw.

Jakie jest pełne imię i nazwisko?

W pełni kwalifikowana nazwa to nazwa, dla której nie będzie wykonywane żadne wyszukiwanie lokalne i nazwa ta będzie traktowana jako bezwzględna podczas rozpoznawania nazwy. Zgodnie z konwencją oprogramowanie DNS uważa nazwę za w pełni kwalifikowaną, jeśli kończy się kropką (.), a w innych przypadkach za niew pełni kwalifikowaną. To jest google.com. w pełni zdefiniowane i google.com - NIE.

Jak obsługiwana jest niekwalifikowana nazwa?

Gdy aplikacja łączy się ze zdalnym hostem określonym w nazwie, rozpoznawanie nazw DNS odbywa się zwykle za pomocą wywołania systemowego, np. getaddrinfo(). Ale jeśli nazwa nie jest kwalifikowana (nie kończy się na .), zastanawiam się, czy wywołanie systemowe spróbuje najpierw rozpoznać nazwę jako nazwę bezwzględną, czy też najpierw przejdzie przez lokalne domeny wyszukiwania? To zależy od opcji ndots.

Z instrukcji resolv.conf:

ndots:n

устанавливает порог для количества точек, которые должны появиться в имени, прежде чем будет сделан начальный абсолютный запрос. Значение по умолчанию для n равно 1, что означает, что если в имени есть какие-либо точки, имя будет сначала опробовано как абсолютное имя, прежде чем к нему будут добавлены какие-либо элементы списка поиска.

Oznacza to, że jeśli dla ndots biorąc pod uwagę wartość 5 i nazwę zawierającą mniej niż 5 kropek, wywołanie systemowe spróbuje rozwiązać problem sekwencyjnie, najpierw przechodząc przez wszystkie lokalne domeny wyszukiwania, a jeśli się to nie powiedzie, ostatecznie rozpoznając ją jako nazwę bezwzględną.

Dlaczego tak ndots:5 czy może to mieć negatywny wpływ na wydajność aplikacji?

Jak możesz sobie wyobrazić, jeśli Twoja aplikacja korzysta z dużego ruchu zewnętrznego, to dla każdego nawiązanego połączenia TCP (a dokładniej dla każdej rozpoznanej nazwy) wyśle ​​5 zapytań DNS, zanim nazwa zostanie poprawnie rozpoznana, ponieważ najpierw przejdzie przez 4 lokalna domena wyszukiwania, a na koniec wystawi żądanie bezwzględnego rozpoznania nazwy.

Poniższy wykres przedstawia całkowity ruch w naszych 3 modułach kube-dns przed i po zmianie kilku nazw hostów skonfigurowanych w naszej aplikacji na w pełni kwalifikowane.

/etc/resolv.conf dla podów Kubernetes, opcja ndots:5, jak może to negatywnie wpłynąć na wydajność aplikacji

Poniższy diagram przedstawia opóźnienie aplikacji przed i po zmianie kilku nazw hostów skonfigurowanych w naszej aplikacji na pełne nazwy (pionowa niebieska linia to wdrożenie):

/etc/resolv.conf dla podów Kubernetes, opcja ndots:5, jak może to negatywnie wpłynąć na wydajność aplikacji

Rozwiązanie nr 1 — Użyj w pełni kwalifikowanych nazw

Jeśli masz kilka statycznych nazw zewnętrznych (tzn. zdefiniowanych w konfiguracji aplikacji), do których tworzysz dużą liczbę połączeń, być może najprostszym rozwiązaniem jest przełączenie ich na w pełni kwalifikowane poprzez proste dołączenie. na końcu.

Nie jest to rozwiązanie ostateczne, ale pozwala szybko, choć nie czysto, poprawić sytuację. Zastosowaliśmy tę łatkę, aby rozwiązać nasz problem, czego skutki pokazano na powyższych zrzutach ekranu.

Rozwiązanie nr 2 – personalizacja ndots в dnsConfig

W Kubernetes 1.9 pojawiła się funkcjonalność w trybie alfa (wersja beta v1.10), która pozwala lepiej kontrolować parametry DNS poprzez właściwość pod w dnsConfig. Umożliwia między innymi konfigurację wartości ndots dla konkretnego zasobnika, tj.

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

Źródła informacji

Przeczytaj także inne artykuły na naszym blogu:

Źródło: www.habr.com

Dodaj komentarz