实时 DNS 流量分析,以排查 AKS 中的 DNS 解析失败

本文介绍如何实时排查 Azure Kubernetes 服务 (AKS) 群集中的域名系统(DNS)故障。

注释

本文是 AKS DNS 解析问题基本故障排除指南 的补充。

症状

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

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

先决条件

若要排查 AKS 群集中的 DNS 故障,请使用以下部分中的说明。 在开始之前,将小工具版本导出为变量。 本文中的所有命令都使用此变量。

GADGET_VERSION=$(kubectl gadget version | grep Server | awk '{print $3}')

请随意选择其他版本。 例如,可以使用 latestmain 分别获取小工具的最新稳定版本或开发版本。

步骤 1:确定群集中的 DNS 响应失败

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

kubectl gadget run trace_dns:$GADGET_VERSION \
  --all-namespaces \
  --fields k8s.node,src,dst,name,qtype,rcode \
  --filter "qr==R,rcode!=Success"

下面是命令参数的说明:

  • --all-namespaces:显示来自所有命名空间中的 Pod 的数据。
  • --fields k8s.node,src,dst,name,qtype,rcode:仅显示 DNS 数据包、DNS 名称、DNS 查询类型和 DNS 响应代码的 Kubernetes 信息、源和目标。
  • --filter "qr==R,rcode!=Success":仅将 DNS 响应 (qr==R) 与除其他 Success响应代码匹配。

输出应如下所示:

K8S.NODE                      SRC                                    DST                                    NAME                         QTYPE           RCODE   
aks-agentpool-…919-vmss000000 p/kube-system/coredns-57d886c994-r2ts… p/default/mypod:38480                  myaks-troubleshoot.          A               NameError
aks-agentpool-…919-vmss000000 s/kube-system/kube-dns:53              p/default/mypod:38480                  myaks-troubleshoot.          A               NameError

DNS 响应代码的位置 RCODE 有助于确定 DNS 故障的类型。

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

  • 要解析的 DNS 名称具有拼写错误。

  • 上游 DNS 名称服务器遇到问题。

  • 配置错误的网络配置(例如 NetworkPolicy(NetPol)、防火墙或 NSG 规则)会阻止 DNS 流量。

  • 扩展后,DNS 名称将变为无效。

    若要了解如何使用 /etc/resolv.conf Pod 文件扩展 DNS 查询,请参阅 服务命名空间

步骤 2:识别群集中速度缓慢的 DNS 查询

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

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

kubectl gadget run trace_dns:$GADGET_VERSION \
  --all-namespaces \
  --fields k8s.node,src,dst,name,qtype,rcode,latency_ns \
  --filter "latency_ns_raw>5000000"

下面是命令参数的说明:

  • --all-namespaces:显示来自所有命名空间中的 Pod 的数据。
  • --fields k8s.node,src,dst,name,qtype,rcode,latency_ns:仅显示 DNS 数据包、DNS 名称、DNS 查询类型、DNS 响应代码和延迟的 Kubernetes 信息、源和目标(以纳秒为单位)。
  • --filter "latency_ns_raw>5000000":仅匹配延迟大于 5ms5000000 nanoseconds) 的 DNS 响应。

输出应如下所示:

K8S.NODE                   SRC                                DST                               NAME                      QTYPE         RCODE          LATENCY_NS
aks-agentpool…9-vmss000001 168.63.129.16:53                   p/kube-system/coredns-57d886c994… microsoft.com.            A             Success           14.02ms
aks-agentpool…9-vmss000000 s/kube-system/kube-dns:53          p/default/mypod:39168             microsoft.com.            A             Success           15.40ms
aks-agentpool…9-vmss000000 168.63.129.16:53                   p/kube-system/coredns-57d886c994… microsoft.com.            AAAA          Success            5.90ms
aks-agentpool…9-vmss000000 s/kube-system/kube-dns:53          p/default/mypod:38953             microsoft.com.            AAAA          Success            6.41ms

下面是 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 run trace_dns:$GADGET_VERSION \
  --all-namespaces \
  --fields src,dst,id,qr,name,nameserver,rcode,latency_ns \
  --filter "nameserver.addr==168.63.129.16"

下面是命令参数的说明:

  • --all-namespaces:显示来自所有命名空间中的 Pod 的数据。
  • --fields src,dst,id,qr,name,nameserver,rcode,latency_ns:仅显示 DNS 数据包的源和目标、DNS 查询 ID、查询/响应、DNS 名称、名称服务器、DNS 响应结果以及 nanoseconds 中的延迟。
  • --filter "nameserver.addr==168.63.129.16" :仅匹配具有名称服务器 IP 地址 168.63.129.16 的 DNS 数据包。

输出应如下所示:

SRC                                        DST                                        ID                QR NAME                           NAMESERVER       RCODE              LATENCY_NS
p/kube-system/coredns-57d886c994-vsj7g:60… r/168.63.129.16:53                         4828              Q  qasim-cluster-dns-sqia0j5i.hc… 168.63.129.16                              0ns
p/kube-system/coredns-57d886c994-pcv59:51… r/168.63.129.16:53                         5015              Q  qasim-cluster-dns-sqia0j5i.hc… 168.63.129.16                              0ns
r/168.63.129.16:53                         p/kube-system/coredns-57d886c994-pcv59:51… 5015              R  qasim-cluster-dns-sqia0j5i.hc… 168.63.129.16    Success                5.06ms
r/168.63.129.16:53                         p/kube-system/coredns-57d886c994-vsj7g:60… 4828              R  qasim-cluster-dns-sqia0j5i.hc… 168.63.129.16    Success               23.01ms

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

  • 具有 ID(例如)的 DNS 查询(QR=Q例如 4828)没有匹配的响应。
  • DNS 响应(QR=R)在 LATENCY_NS 列(例如, 23.01ms)下具有较高的值。
  • DNS 响应(QR=R)具有一个RCODE,而不是Success,例如,“ServerFailure”和“Refused”。

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

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

kubectl gadget run trace_dns:$GADGET_VERSION \
    -l app=test-pod \
    --fields k8s.node,k8s.namespace,k8s.podname,id,qtype,qr,name,rcode,latency_ns \
    --filter name==microsoft.com.

下面是命令参数的说明:

  • -l app=test-pod:仅显示在默认命名空间中,标签为 app=test-pod 的 Pod 与 Pod 之间的数据。
  • --fields k8s.node,k8s.namespace,k8s.podname,id,qtype,qr,name,rcode,latency_ns:仅显示 Kubernetes 信息、DNS 查询 ID、查询类型、查询/响应、DNS 名称、DNS 响应结果以及 nanoseconds 中的延迟。
  • --filter name==microsoft.com.:仅匹配具有 DNS 名称 microsoft.com. 的 DNS 数据包,确保筛选器值为完全限定的域名(FQDN),需在名称末尾添加一个点(.)。

输出应如下所示:

K8S.NODE                  K8S.NAMESPACE             K8S.PODNAME               ID             QTYPE          QR NAME                     RCODE          LATENCY_NS
aks-agentpoo…9-vmss000000 default                   mypod                     102d           A              Q  microsoft.com.                                 0ns
aks-agentpoo…9-vmss000000 default                   mypod                     102d           A              R  microsoft.com.           Success           11.87ms
aks-agentpoo…9-vmss000000 default                   mypod                     d482           AAAA           Q  microsoft.com.                                 0ns
aks-agentpoo…9-vmss000000 default                   mypod                     d482           AAAA           R  microsoft.com.           Success            9.27ms

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

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

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

kubectl gadget run trace_dns:$GADGET_VERSION \
  --fields k8s.podname,id,qtype,qr,name,rcode,num_answers,addresses  \
  --filter name~myheadless

下面是命令参数的说明:

  • --fields k8s.podname,id,qtype,qr,name,rcode,num_answers,addresses:仅显示 Kubernetes 信息、DNS 查询 ID、查询类型、查询/响应、DNS 名称、DNS 响应结果、响应中的答案数和 IP 地址。
  • --filter name~myheadless:仅匹配包含 DNS 名称 myheadless的 DNS 数据包。 运算符 ~ 用于匹配正则表达式。

输出应如下所示:

K8S.PODNAME                           ID                   QTYPE                QR NAME                                 RCODE     NUM_ANSWERS ADDRESSES          
mypod                                 f8b0                 A                    Q  myheadless.default.svc.cluster.loca…           0                              
mypod                                 f8b0                 A                    R  myheadless.default.svc.cluster.loca… Success   2           10.244.0.146,10.24…
mypod                                 abcd                 AAAA                 Q  myheadless.default.svc.cluster.loca…           0                              
mypod                                 abcd                 AAAA                 R  myheadless.default.svc.cluster.loca… Success   0                              

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

kubectl get ep myheadless 
NAME                  ENDPOINTS                           AGE 
myheadless            10.244.0.146:80,10.244.1.207:80   10d 

第三方信息免责声明

本文讨论的第三方产品由独立于微软的公司制造。 Microsoft对这些产品的性能或可靠性不作任何明示或暗示的保证。

联系我们以获得帮助

如果您有任何疑问或需要帮助,可以创建支持请求,或咨询Azure社区支持。 您还可以向Azure反馈社区提交产品反馈。