Alpine在Kubernetes中是否有已知的DNS问题?

最近,在尝试解决“大”DNS 查询(当答案大于 512M 时)时,我们在 EKS 上遇到了一些基于 Alpine 图像(节点:12.18.1-alpine)的微服务的 DNS 问题。

所以我尝试运行这个脚本来测试 DNS 解析:

var dns = require('dns');
var w3 = dns.lookup('hugedns.test.dziemba.net', function (err, addresses, family) {
  console.log(addresses);
});

每个图像有 2 个不同的场景

  1. 节点:12.18.1-高山
  • 在我的笔记本电脑上运行图像 - 成功解决
  • 在 EKS 1.16 上运行映像 - 无法解决
  1. 节点:12.18.1-slim
  • 在我的笔记本电脑上运行图像 - 成功解决
  • 在 EKS 1.16 上运行镜像 - 成功解决

从我看到的情况来看,Alpine 正在使用 musl(它不支持 DNS 来使用 TCP?)库而不是 glibc,因为 DNS 协议使用的是 UDP,并且仅在查询大于 512M 时才尝试回退到 TCP。所以我的理论是这是根本原因,但由于它对我有用并且在 EKS 上失败让我想知道问题在哪里可以传递......

有什么想法吗?

EKS v1.16 coredns:v1.6.6

BTW,这是我的第一篇文章,如果需要任何信息,请告诉我

回答

是的,已知 Alpine 镜像在 Kubernetes 集群中存在与 DNS 查询相关的问题。

即使不清楚该错误是否已在任何当前版本的 Alpine 中得到有效修复,以下是一些相关链接:

  • https://github.com/kubernetes-sigs/kind/issues/442
  • https://gitlab.alpinelinux.org/alpine/aports/-/issues/9017
  • https://github.com/gliderlabs/docker-alpine/issues/476

截至 2021 年 1 月,我在 Kubernetes 集群中遇到了这个问题,使用最新的 Alpine 3.12 映像,所以我认为它没有解决。

核心问题似乎是,如果有任何意外响应,musl库将停止在search指令中指定的可能域中搜索/etc/resolv.conf给定名称(基本上不是明确表明无法找到或已找到 FQDN 的内容)。

这与 Kubernetes 中关于 pod 中名称解析的策略并不一致。

确实,可以看到命名空间中的典型/etc/resolv.confpodexample如下:

nameserver 10.3.0.10
search example.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

策略是名称的解析,例如my-serviceor www.google.com,将针对search指令中指定的每个域进行测试:对于示例,它将是 FQDN 链my-service.example.svc.cluster.local, my-service.svc.cluster.local, my-service.cluster.local, my-serviceand www.google.com.example.svc.cluster.local, www.google.com.svc.cluster.local, www.google.com.cluster.local, www.google.com。显然,第一个链 ( my-service.example.svc.cluster.local) 的第一个 FQDN 和第二个链 ( www.google.com)的最后一个 FQDN将被正确解析。

可以看到,这个策略是集群的内部名称的优化决议中提出,在某种程度上允许的名字,如my-servicemy-service.my-namespacemy-service.my-namespace.svc将很好地解决外的开箱。

ndots在参数options指令定义一个名字点的最小数量要考虑到的名称实际上是一个FQDN,因此搜索链应该有利于直接DNS解析尝试进行skiped。与ndots:2,www.google.com将被视为 FQDN 而my-service.my-namespace将通过搜索链。

鉴于search超过 3 个可能域的选项,任何明显的 URL 都不会被视为 FQDN,因为Alpine docker 库中ndots:5的搜索循环中断musl,所有这些都大大增加了 Docker 中主机解析失败的可能性在 Kubernetes 中运行的 Alpine。如果您的主机解析是某种定期运行的循环的一部分,您将遇到许多需要处理的故障。

怎么办?

  • 您可以使用 adnsPolicy减少ndots并将较短的名称视为 FQDN 并跳过搜索循环(请参阅https://pracucci.com/kubernetes-dns-resolution-ndots-options-and-why-it-may-affect-application-performances .html )
  • 您可以为您的图像生成一个入口点脚本,该脚本将/etc/resolv.conf根据您的需要相应地修改,例如,如果您不依赖进程中集群的任何内部名称,cat /etc/resolv.conf | sed -r "s/^(search.*|options.*)/#1/" > /tmp/resolv && cat /tmp/resolv > /etc/resolv.conf将删除关于searchand 的所有内容options
  • /etc/host某些 FQDN 硬编码到其已知 IP 的直接版本
  • 远离 Alpine 镜像,转而使用基于 Ubi 或 Debian/Ubuntu 的镜像

我个人从 Alpine 开始,就像我们在 Docker 工业化初期的很多人一样,因为其他完整的操作系统映像非常大。对于 Ubuntu 或 Debian,甚至像 Ubi 这样以 Kubernetes 为中心的计划,经过严格测试的超薄映像大多不再是这种情况。这就是为什么我通常选择最后一个选项(远离 Alpine 图像)。


以上是Alpine在Kubernetes中是否有已知的DNS问题?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>