Kubernetes pod 的 /etc/resolv.conf,ndots:5 選項,這會對應用程式效能產生負面影響

Kubernetes pod 的 /etc/resolv.conf,ndots:5 選項,這會對應用程式效能產生負面影響

我們最近使用 Kops 在 AWS 上推出了 Kubernetes 1.9。 昨天,在向我們最大的 Kubernetes 叢集順利推出新流量時,我開始注意到我們的應用程式記錄了不尋常的 DNS 名稱解析錯誤。

GitHub 上有很多關於這方面的內容 說話,所以我也決定弄清楚。 最後,我意識到,在我們的例子中,這是由於負載增加所造成的 kube-dns и dnsmasq。 對我來說最有趣、最新鮮的事情就是 DNS 請求流量顯著增加的原因。 我的帖子就是關於這個以及如何處理它的。

容器內的 DNS 解析(與任何 Linux 系統中一樣)由設定檔決定 /etc/resolv.conf。 預設 Kubernetes dnsPolicyClusterFirst,這意味著任何 DNS 請求都將轉送到 dnsmasq,在 Pod 中運行 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. 名稱伺服器是服務的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 模組上的總流量。

Kubernetes pod 的 /etc/resolv.conf,ndots:5 選項,這會對應用程式效能產生負面影響

下圖顯示了我們將應用程式中配置的幾個主機名稱切換為全名之前和之後的應用程式延遲(垂直藍線是部署):

Kubernetes pod 的 /etc/resolv.conf,ndots:5 選項,這會對應用程式效能產生負面影響

解決方案#1 - 使用完全限定名稱

如果您創建了大量連接的靜態外部名稱(即在應用程式配置中定義)很少,也許最簡單的解決方案是透過簡單地附加它們將它們切換為完全限定的名稱。 在最後。

這不是最終的解決方案,但它有助於快速(儘管不是徹底)改善情況。 我們應用這個補丁來解決我們的問題,其結果如上面的螢幕截圖所示。

解決方案#2 - 定制 ndots в dnsConfig

在 Kubernetes 1.9 中,功能以 alpha 模式出現(beta 版本 v1.10),它允許您透過 pod 屬性更好地控制 DNS 參數 dnsConfig。 除此之外,它還允許您配置值 ndots 對於特定的 Pod,即

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

來源

也請閱讀我們部落格上的其他文章:

來源: www.habr.com

添加評論