
不久前,我们使用Kops在AWS上启动了Kubernetes 1.9。 昨天,在将新流量平稳地扩展到我们最大的Kubernetes集群的同时,我开始注意到我们的应用程序记录的异常DNS名称解析错误。
GitHub 讨论了很长时间,所以我也决定弄清楚。 最后,我意识到在我们的例子中,这是由于kube-dns
和dnsmasq
负载增加所致。 对我而言,最有趣和新颖的原因就是DNS查询流量显着增加的原因。 关于这个以及如何处理,我的帖子。
与任何Linux系统一样,容器内部DNS的解析由配置文件/etc/resolv.conf
。 默认情况下,Kubernetes dnsPolicy
是ClusterFirst
,这意味着任何DNS查询都将重定向到在群集内部kube-dns
运行的dnsmasq
,如果名称以群集后缀结尾,则反过来会将查询重定向到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
如您所见,有三个指令:
- 名称服务器是
kube-dns
的IP服务 - 指定了4个本地搜索域
- 有一个选项
ndots:5
此配置的一个有趣的部分是本地搜索域和ndots:5
设置。 要了解这一点,您需要了解DNS解析对于部分名称的工作方式。
全名是什么?
完全限定名称是不会对其进行本地搜索的名称,并且在名称解析期间,该名称将被视为绝对名称。 按照约定,如果域名以句号(。)结尾,则DNS软件会将其视为完全合格的名称,否则将不进行完整定义。 那是google.com.
完全定义,但google.com
否。
如何处理不完整的名称?
当应用程序连接到名称中指定的远程主机时,通常使用系统调用(例如getaddrinfo()
来完成DNS名称解析。 但是,如果名称不完整(不以。结尾),我想知道系统调用是否会首先尝试将名称解析为绝对名称,还是会首先通过本地搜索域? 这取决于ndots
选项。
从resolv.conf
手册中:
ndots:n , , . n 1, , - , , - .
这意味着,如果ndots
设置为5,并且名称包含少于5个点,则系统调用将尝试依次解决该问题,方法是首先遍历所有本地搜索域,如果不成功,则最终将其解析为绝对名称。
为什么ndots:5
会对应用程序性能产生不利影响?
如您所知,如果您的应用程序使用大量外部流量,则对于每个已建立的TCP连接(或更确切地说,对于每个解析的名称),它将在正确解析名称之前发出5个DNS查询,因为它将首先经过4个本地搜索域,最后将发出绝对名称解析请求。
下图显示了在将应用程序中配置的多个主机名切换为完全定义的主机名前后的3个kube-dns模块上的总流量。

下图显示了在将应用程序中配置的多个主机名切换为完整状态之前和之后的应用程序延迟(垂直的蓝线是部署):

解决方案1-使用标准名称
如果创建大量连接的静态外部名称(即在应用程序配置中定义的)很少,那么也许最简单的解决方案是通过简单地添加它们来将它们切换为完全定义的外部名称。 最后。
这不是最终决定,但这有助于快速(尽管不是很干净)改善情况。 我们应用了此补丁程序来解决我们的问题,其结果显示在上面的屏幕截图中。
解决方案2-在dnsConfig
自定义dnsConfig
在Kubernetes 1.9中,一项功能以alpha模式出现(beta版本v1.10),该功能允许通过dnsConfig
的pod属性更好地控制DNS参数。 除其他事项外,它允许您调整特定炉床的ndots
值,即
apiVersion: v1 kind: Pod metadata: namespace: default name: dns-example spec: containers: - name: test image: nginx dnsConfig: options: - name: ndots value: "1"
资料来源
另请阅读我们博客上的其他文章: