本页面介绍如何在 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。
您无需修改 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。
访问 Cloud Console 中的 Google Kubernetes Engine 菜单。
点击 add_box 创建。
对于名称,输入 cluster-name。
在区域部分,选择 us-central1-a。
在节点数部分,输入
1
。在导航窗格的集群下,点击网络。
在高级网络选项下,选中启用 NodeLocal DNSCache 复选框。
点击创建。
验证 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 不匹配。
后续步骤
- 简要了解 GKE 如何提供托管式 DNS。
- 阅读服务和 Pod 的 DNS,大致了解如何在 Kubernetes 集群中使用 DNS。