设置 NodeLocal DNSCache

本页面介绍如何在 Google Kubernetes Engine (GKE) 集群上配置 NodeLocal DNSCache。通过在每个集群节点上运行 DNS 缓存,NodeLocal DNSCache 可以缩短 DNS 查找的延迟时间、使 DNS 查找时间更加一致,以及减少发送到 kube-dns 的 DNS 查询次数。

如需简要了解服务发现和托管式 DNS 在 GKE 上的工作原理,请参阅服务发现和 DNS

概览

NodeLocal DNSCache 是一个可选的 GKE 插件,除了 kube-dns 之外,您还可以运行该插件。NodeLocal DNSCache 是作为 DaemonSet 实现的,DaemonSet 会在集群中的每个节点上运行 DNS 缓存。当 Pod 发出 DNS 请求时,该请求会转到与 Pod 相同的节点上运行的 DNS 缓存。如果该缓存无法解析该 DNS 请求,则会将该请求转发到以下 DNS:

  • 用于外部主机名查询的 Cloud DNS。这些查询由与生成查询的 Pod 相同的节点上运行的本地元数据服务器转发到 Cloud DNS。
  • 用于所有其他 DNS 查询的 kube-dns。node-local-dns 使用 kube-dns-upstream 服务连接到 kube-dns Pod。

DNS 请求的路径图(如前一段所述)

您无需修改 Pod 即可使用 NodeLocal DNSCache。 NodeLocal DNSCache 会消耗集群的每个节点上的计算资源。

NodeLocal DNSCache 的优点

  • 减少了平均 DNS 查找时间
  • 从 Pod 到其本地缓存的连接不会创建 conntrack 表条目。这样可以防止由于 conntrack 表耗尽和竞态条件而导致连接中断和连接被拒绝。

详情

  • NodeLocal DNSCache 需要 GKE 1.15 或更高版本。
  • 本地 DNS 缓存和 kube-dns 之间的连接使用 TCP 而不是 UDP,以提高可靠性。
  • 外部网址(不引用集群资源的网址)的 DNS 查询会绕过 kube-dns 而直接转发到本地 Cloud DNS 元数据服务器。
  • 本地 DNS 缓存会自动选取 kube-dns ConfigMap 中指定的存根网域和上游域名服务器。

  • DNS 记录会缓存以下时长:

    • 记录的 TTL 或 30 秒(后者适用于 TTL 超过 30 秒的情况)。
    • 5 秒(如果 DNS 响应为 NXDOMAIN)。
  • NodeLocal DNSCache Pod 会侦听节点上的端口 53、9530 和 8080。使用上述端口运行任何其他 hostNetwork Pod 或使用上述端口配置 hostPort 会导致 NodeLocal DNSCache 失败并造成 DNS 错误。

启用 NodeLocal DNSCache

您可以在现有集群中或在创建新集群时启用 NodeLocal DNSCache。在现有集群中启用 NodeLocal DNSCache 是一个能够导致服务中断的过程;所有运行 GKE 1.15 及更高版本的集群节点都会重新创建。按照 GKE 节点升级过程重新创建节点。

gcloud

在新集群中启用 NodeLocal DNSCache

如需在新集群中启用 NodeLocal DNSCache,请使用 --addons NodeLocalDNS 标志:

gcloud container clusters create cluster-name \
  --zone compute-zone \
  --cluster-version cluster-version \
  --addons NodeLocalDNS

替换以下内容:

  • cluster-name:新集群的名称。
  • compute-zone:集群的区域
  • cluster-version:集群的版本(1.15 或更高版本)。

在现有集群中启用 NodeLocal DNSCache

如需在现有集群中启用 NodeLocal DNSCache,请使用 --update-addons=NodeLocalDNS=ENABLED 标志:

gcloud container clusters update cluster-name \
  --update-addons=NodeLocalDNS=ENABLED

控制台

您可以在创建新集群时使用 Google Cloud Console 启用 NodeLocal DNSCache。

  1. 访问 Cloud Console 中的 Google Kubernetes Engine 菜单。

    访问 Google Kubernetes Engine 菜单

  2. 点击 创建

  3. 对于名称,输入 cluster-name

  4. 区域部分,选择 us-central1-a

  5. 节点数部分,输入 1

  6. 在导航窗格的集群下,点击网络

  7. 高级网络选项下,选中启用 NodeLocal DNSCache 复选框。

  8. 点击创建

验证 NodeLocal DNSCache 是否已启用

您可以通过列出 node-local-dns Pod 来验证 NodeLocal DNSCache 是否正在运行。 每个运行 GKE 1.15 或更高版本的节点上都应该有一个 node-local-dns Pod 在运行。

kubectl get pods -n kube-system -o wide | grep node-local-dns

停用 NodeLocal DNSCache

您可以使用 gcloud 停用 NodeLocal DNSCache:

gcloud container clusters update cluster-name \
  --update-addons=NodeLocalDNS=DISABLED

排查 NodeLocal DNSCache 问题

如需了解有关诊断 Kubernetes DNS 问题的一般信息,请参阅排查 DNS 解析问题

验证 Pod 配置

如需验证 Pod 是否正在使用 NodeLocal DNSCache,请检查 Pod 上的 /etc/resolv.conf,以查看 Pod 是否已配置为使用正确的域名服务器:

kubectl exec -it pod-name -- cat /etc/resolv.conf | grep nameserver

域名服务器的 IP 地址应与以下命令输出的 IP 地址相匹配:

kubectl get svc -n kube-system kube-dns -o jsonpath="{.spec.clusterIP}"

如果在 /etc/resolv.conf 中配置的域名服务器的 IP 地址与以上命令输出的 IP 地址不匹配,则您需要将配置修改为使用正确的域名服务器的 IP 地址。

使用 NodeLocal DNSCache 的网络政策

将 NetworkPolicy 与 NodeLocalDNS 插件搭配使用时,需要额外的规则来允许 node-local-dns pod 发送和接收 DNS 查询。在 NetworkPolicy 中使用 ipBlock 规则以允许在 node-local-dns Pod 和 kube-dns 之间进行通信:

spec:
  egress:
  - ports:
    - port: 53
      protocol: TCP
    - port: 53
      protocol: UDP
    to:
    - ipBlock:
        cidr: kube-dns-cluster-ip/32
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

kube-dns-cluster-ip 替换为通过以下方式获取的 kube-dns 服务的 IP 地址:

kubectl get svc -n kube-system kube-dns -o jsonpath="{.spec.clusterIP}"

此示例使用 ipBlock 规则,因为 node-local-dns pod 以 hostNetwork:True 模式运行。matchLabels 规则与这些 pod 不匹配。

后续步骤