本文介绍如何实时排查 Azure Kubernetes 服务 (AKS) 群集中的域名系统(DNS)故障。
注释
本文是 AKS DNS 解析问题基本故障排除指南 的补充。
症状
下表概述了在 AKS 群集中可能观察到的常见症状:
症状 | DESCRIPTION |
---|---|
错误率高 | DNS 查询失败或返回意外结果,这可能会影响依赖于这些结果的应用程序的性能和可靠性。 |
没有响应的服务 | DNS 查询的解决时间比平时要长,这可能会导致依赖于它们的应用程序中出现延迟或超时。 |
服务发现受到影响 | 应用程序由于 DNS 问题而无法在群集中找到其他应用程序,这可能会导致服务中断或故障。 |
外部通信受到影响 | 由于 DNS 问题,应用程序在访问群集外部的外部资源或终结点时遇到问题,这可能会导致错误或性能下降。 |
先决条件
Azure CLI。
若要安装 Azure CLI,请参阅 如何安装 Azure CLI。
连接到群集的工具,例如 Kubernetes 命令行工具 kubectl。
若要使用 Azure CLI 安装 kubectl,请运行 az aks install-cli 命令。
-
此工具用于本文介绍的大多数故障排除步骤中,因此请确保将其安装在群集上。 若要在 AKS 群集上安装它,请参阅 如何在 AKS 群集中安装 Inspektor 小工具。
熟悉 电子设备。
-
它用于以下所有故障排除步骤。
若要排查 AKS 群集中的 DNS 故障,请使用以下部分中的说明。 在开始之前,将小工具版本导出为变量。 本文中的所有命令都使用此变量。
GADGET_VERSION=$(kubectl gadget version | grep Server | awk '{print $3}')
请随意选择其他版本。 例如,可以使用 latest
或 main
分别获取小工具的最新稳定版本或开发版本。
步骤 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
,, 20ms
, 1s
:
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"
:仅匹配延迟大于5ms
(5000000
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_ANSWERS
和 ADDRESSES
值来匹配从 kubectl get ep myheadless
中获取的值。
kubectl get ep myheadless
NAME ENDPOINTS AGE
myheadless 10.244.0.146:80,10.244.1.207:80 10d
第三方信息免责声明
本文讨论的第三方产品由独立于微软的公司制造。 Microsoft对这些产品的性能或可靠性不作任何明示或暗示的保证。