实时排查 AKS 群集中的 DNS 故障

Kubernetes 中的域名系统(DNS)问题可能会中断 Pod、服务和外部资源之间的通信,这会导致应用程序故障和性能下降。 本文介绍如何实时排查 Azure Kubernetes 服务 (AKS) 群集中的 DNS 故障。

注意

本文补充了 Pod 指南中的 DNS 解析故障疑难解答。

现象

下表概述了在 AKS 群集中可能观察到的常见症状:

症状 说明
错误率高 DNS 查询失败或返回意外结果,这可能会影响依赖于这些结果的应用程序的性能和可靠性。
无响应服务 DNS 查询的解决时间比平时要长,这可能会导致依赖于它们的应用程序中出现延迟或超时。
服务发现受到影响 应用程序由于 DNS 问题而无法在群集中找到其他应用程序,这可能会导致服务中断或故障。
外部通信受到影响 由于 DNS 问题,应用程序在访问群集外部的外部资源或终结点时遇到问题,这可能会导致错误或性能下降。

先决条件

若要排查 AKS 群集中的 DNS 故障,请使用以下部分中的说明。

步骤 1:确定群集中不成功的 DNS 响应

可以使用 DNS 小工具识别群集中所有不成功的 DNS 响应。 若要执行此检查,请跟踪所有节点上的 DNS 数据包,并使用以下命令筛选不成功的响应:

$ kubectl gadget trace dns --all-namespaces --output columns=k8s,name,qtype,rcode --filter qr:R --filter qtype:A --filter 'rcode:!No Error'
K8S.NODE         K8S.NAMESPACE    K8S.POD     K8S.CONTAINER    NAME                  QTYPE        RCODE 
aks-agen...      default          test-pod    nginx            myaks-troubleshoot.   A            Non-Existent Domain 
aks-agen...      default          test-pod    nginx            myaks-troubleshoot.   A            Non-Existent Domain 

下面是命令参数的说明:

  • --all-namespaces:显示来自所有命名空间中的 Pod 的数据。
  • -output columns=k8s,name,qtype,rcode:仅显示 Kubernetes 信息、DNS 名称、查询类型和 DNS 查询结果。
  • --filter qr:R:仅匹配 DNS 响应。
  • --filter qtype:A:仅匹配 IPv4 主机地址。
  • --filter 'rcode:!No Error':匹配不包含 No Error的 DNS 响应。 有关详细信息,请参阅 gopacket rcode相关 RFC 的可能值。

下面是 DNS 响应失败的一些原因:

  • 要解析的 DNS 名称具有拼写错误。
  • 上游 DNS 名称服务器遇到问题。
  • 扩展后,DNS 名称将变为无效。 若要了解如何使用 Pod /etc/resolv.conf扩展 DNS 查询,请参阅 服务命名空间。

步骤 2:确定群集中速度缓慢的 DNS 查询

可以使用 DNS 小工具识别群集中的所有慢速 DNS 查询。 若要执行此检查,请跟踪所有节点上的 DNS 数据包并筛选慢响应。

在以下示例中,你将使用延迟值 5ms 来定义慢数据包。 可以将它更改为所需的值,例如 5μs,, 20ms1s

$ kubectl gadget trace dns --all-namespaces --output columns=k8s,name,rcode,latency --filter 'latency:>5ms'
K8S.NODE        K8S.NAMESPACE      K8S.POD       K8S.CONTAINER      NAME                            RCODE              LATENCY            
aks-agen...     kube-system        coredn...     coredns            global.prod.micro...            No Error           5.373123ms 
aks-agen...     kube-system        coredn...     coredns            global.prod.micro...            No Error           5.373123ms 

下面是命令参数的说明:

  • --all-namespaces:显示来自所有命名空间中的 Pod 的数据。
  • --output columns=k8s,name,rcode,latency:仅显示 Kubernetes 信息、DNS 名称、DNS 响应结果和响应延迟。
  • --filter 'latency:>5ms':仅匹配至少 5 ms延迟为 DNS 响应的 DNS 响应。

下面是 DNS 查询速度缓慢的一些原因:

步骤 3:验证上游 DNS 服务器的运行状况

可以使用 DNS 小工具验证 CoreDNS 使用的上游 DNS 服务器的运行状况。 如果应用程序尝试访问外部域,则查询将通过 CoreDNS 转发到上游 DNS 服务器。 若要了解这些查询的运行状况,请跟踪离开 CoreDNS Pod 的 DNS 数据包,并按名称服务器进行筛选。

在以下示例中,默认的 Azure DNS 服务器 (IP 地址 168.63.129.16)用作上游名称服务器。 如果使用自定义 DNS 服务器,则可以将自定义 DNS 服务器的 IP 地址用作上游名称服务器。 可以通过在节点上查找 /etc/resolv.conf 来获取 IP 地址。

$ kubectl gadget trace dns -n kube-system -l k8s-app=kube-dns -o columns=k8s,id,qr,name,rcode,nameserver,latency -F nameserver:168.63.129.16
K8S.NODE    K8S.NAMESPACE   K8S.POD                        K8S.CONTAINER   ID        QR    NAME               RCODE           NAMESERVER              LATENCY
aks-agen... kube-system     coredns-6d5bb68c46-ntz2q       coredns         b256      Q     microsoft.com.                     168.63.129.16
aks-agen... kube-system     coredns-6d5bb68c46-ntz2q       coredns         b256      R     microsoft.com.     No Error        168.63.129.16           500.821223ms

下面是命令参数的说明:

  • -n kube-system:仅显示命名空间中的数据 kube-system
  • -l k8s-app=kube-dns:仅显示具有标签 k8s-app=kube-dns (CoreDNS Pod)的 Pod 与 Pod 的数据。
  • -o columns=k8s,id,name,rcode,nameserver,latency:仅显示 Kubernetes 信息、DNS 查询 ID、查询/响应、DNS 名称、DNS 响应结果、名称服务器和响应延迟。
  • -F nameserver:168.63.129.16:用于筛选事件的上游 DNS 服务器。

可以使用和IDRCODELATENCY值来确定上游 DNS 服务器的运行状况。 例如,如果上游服务器运行不正常,则会看到以下输出:

  • DNS ID 查询(QR=Q例如,b256)没有匹配的响应。
  • DNS 响应(QR=R)在 LATENCY 列(例如, 500.821223ms)下具有较高的值。
  • DNS 响应(QR=R)除“服务器故障”和“查询被拒绝”外No Error,还有一个RCODE。有关详细信息,请参阅 gopacket rcode 的可能值。

步骤 4:验证 DNS 查询是否及时获取响应

可以使用 DNS 小工具验证特定 DNS 查询是否及时获取响应。 若要执行此检查,请使用 DNS 名称筛选事件,并匹配查询/响应 ID:

$ kubectl gadget trace dns -l app=test-pod --output columns=k8s,id,qtype,qr,name,rcode,latency --filter name:microsoft.com.
K8S.NODE       K8S.NAMESPACE   K8S.POD     K8S.CONTAINER   ID          QTYPE     QR  NAME              RCODE               LATENCY
aks-agen...    default         test-pod    nginx           97b3        A         Q   microsoft.com.
aks-agen...    default         test-pod    nginx           97b3        A         R   microsoft.com.    No Error            1.954413ms
aks-agen...    default         test-pod    nginx           97b3        A         R   microsoft.com.    No Error
aks-agen...    default         test-pod    nginx           c6c5        AAAA      Q   microsoft.com.
aks-agen...    default         test-pod    nginx           c6c5        AAAA      R   microsoft.com.    No Error            1.885412ms
aks-agen...    default         test-pod    nginx           c6c5        AAAA      R   microsoft.com.    No Error

下面是命令参数的说明:

  • -l app=test-pod:仅显示具有标签 app=test-pod的 Pod 与 Pod 的数据。
  • --output columns=k8s,id,qtype,qr,name,rcode,latency:仅显示 Kubernetes 信息、DNS 查询 ID、查询类型、查询/响应、DNS 名称、DNS 响应结果和响应延迟。
  • --filter name:microsoft.com.:仅匹配 DNS 名称的 DNS microsoft.com. 数据包,以确保筛选器值是完全限定的域名(FQDN),在名称末尾添加一个点(.)。

ID (例如, 97b3)可用于将查询与响应相关联。 还可以使用 LATENCY 该值来验证是否及时获取响应。

步骤 5:验证 DNS 响应是否包含预期的 IP 地址

可以使用 DNS 小工具验证特定 DNS 查询是否获得预期响应。 例如,对于 无外设服务 (名为 myheadless),你期望响应包含所有 Pod 的 IP 地址。

$ kubectl gadget trace dns -l app=test-pod  -o columns=k8s,id,qtype,qr,name,rcode,numAnswers,addresses  -F name:~myheadless 
K8S.NODE         K8S.NAMESPACE      K8S.POD         K8S.CONTAINER   ID    QTYPE   QR  NAME                 RCODE           NUMANSWERS     ADDRESSES
aks-agen...      default            test-pod        nginx           f930  A       R   myheadless.defau...  No Error        2              10.244.2.18,10.244.2.19 
aks-agen...      default            test-pod        nginx           f930  A       R   myheadless.defau...  No Error        2              10.244.2.18,10.244.2.19 
aks-agen...      default            test-pod        nginx           f930  A       Q   myheadless.defau...                  0                              

下面是命令参数的说明:

  • -l app=test-pod:仅显示具有标签 app=test-pod的 Pod 与 Pod 的数据。
  • -o columns=k8s,id,qtype,qr,name,rcode,numAnswers,addresses:仅显示 Kubernetes 信息、DNS 查询 ID、查询类型、查询/响应、DNS 名称、DNS 响应结果、响应中的答案数和 IP 地址。
  • -F name:~myheadless:仅包括通过正则表达式检查的 ~myheadless DNS 数据包。

可以使用 NUMANSWERSADDRESSES 值来匹配从 kubectl get ep myheadless中获取的值。

$ kubectl get ep myheadless 
NAME                  ENDPOINTS                           AGE 
myheadless            10.244.2.18:8080,10.244.2.19:8080   10d 

第三方信息免责声明

本文中提到的第三方产品由 Microsoft 以外的其他公司提供。 Microsoft 不对这些产品的性能或可靠性提供任何明示或暗示性担保。

联系我们寻求帮助

如果你有任何疑问或需要帮助,请创建支持请求联系 Azure 社区支持。 你还可以将产品反馈提交到 Azure 反馈社区