Kubernetes 缺陷之 DNS 延迟问题

Introduction:

由于 Linux 内核中的缺陷,在 Kubernetes 集群中你很可能会碰到恼人的 DNS 间歇性 5 秒延迟问题,可能出现 DNS 查询超时,可能如现 getaddrinfo failed: System error

conclusion:

要避免 DNS 延迟的问题,就要设法绕开上述三个问题,所以就有下面几种方法:

  1. 禁止并发 DNS 查询,比如在 Pod 配置中开启 single-request-reopen 选项强制 A 查询和 AAAA 查询使用相同的 socket:
dnsConfig:
  options:
    - name: single-request-reopen
  1. 禁用 IPv6 从而避免 AAAA 查询,比如可以给 Grub 配置 ipv6.disable=1 来禁止 ipv6(需要重启节点才可以生效)。

  2. 使用 TCP 协议,比如在 Pod 配置中开启 use-vc 选项强制 DNS 查询使用 TCP 协议:

dnsConfig:
  options:
    - name: single-request-reopen
    - name: ndots
      value: "5"
    - name: use-vc
  1. 使用 Nodelocal DNS Cache[5],所有 Pod 的 DNS 查询都通过本地的 DNS 缓存查询,避免了 DNAT,从而也绕开了内核中的竞争问题。你可以执行下面的命令来部署它(注意它会修改 Kubelet 配置并重启 Kubelet):
kubectl apply -f https://github.com/feiskyer/kubernetes-handbook/raw/master/examples/nodelocaldns/nodelocaldns-kubenet.yaml

Reference:

https://zhuanlan.zhihu.com/p/127348780

https://www.weave.works/blog/racy-conntrack-and-dns-lookup-timeouts

https://tech.kujiale.com/k8s-nodejs-dns-timeout-issue/