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"

来源

另请阅读我们博客上的其他文章:

来源: habr.com

添加评论