如何使用 Amazon EKS 排查 DNS 故障?
我的 Amazon Elastic Kubernetes Service (Amazon EKS) 集群中使用 CoreDNS 的应用程序或容器组(pod)在进行内部或外部 DNS 名称解析时失败。
简短描述
在 Amazon EKS 集群内运行的 pod 使用 CoreDNS 服务的集群 IP 作为原定设置的名称服务器,以查询内部和外部的 DNS 记录。如果 CoreDNS pod 、服务配置或连接遇到问题,应用程序的 DNS 解析可能会失败。
一项名为 kube-dns 的服务对象会提取 CoreDNS pod。要排查您的 CoreDNS 一组容器(pod)的问题,请验证 kube-dns 服务的所有组件都正常运行。这些组件包括,但不限于,服务终端节点选项和 iptables 规则。
解决方法
以下解决方法适用于 CoreDNS ClusterIP 10.100.0.10。
1. 获取 CoreDNS 服务的 ClusterIP:
kubectl get service kube-dns -n kube-system
2. 验证 DNS 端点是否已被公开而且指向 CoreDNS 容器组(pod):
kubectl -n kube-system get endpoints kube-dns
输出:
NAME ENDPOINTS AGE kube-dns 192.168.2.218:53,192.168.3.117:53,192.168.2.218:53 + 1 more... 90d
**注意:**若端点列表为空,则检查 CoreDNS 一组容器(pod)的一组容器(pod)状态。
3. 验证安全组或网络访问控制列表(网络 ACL)在与 CoreDNS 通信时不会阻止 pod。
如需更多信息,见为什么我的一组容器 (pod) 不会连接到 Amazon EKS 中的其他一组容器 (pod)?
验证 kube-proxy 一组容器 (pod) 正常运行
检查您的控制面板超时错误日志,以验证 kube-proxy 一组容器 (pod) 具有集群的 API 服务器访问权限。另外,检查 403 未授权错误。
获取 kube-proxy 日志:
kubectl logs -n kube-system --selector 'k8s-app=kube-proxy'
**注意:**kube-proxy 从控制面板获取端点,并且在每个节点上创建 iptables 规则。
连接至应用程序一组容器(pod)以排查 DNS 问题
1. 要在您的应用程序 pod 中运行命令,运行以下命令以访问正在运行的一组容器 pod 内部的 shell:
$ kubectl exec -it your-pod-name -- sh
当应用程序 pod 没有可用的 shell 二进制时,您将收到与以下类似的错误消息:
OCI runtime exec failed: exec failed: container_linux.go:348: starting container process caused "exec: \"sh\": executable file not found in $PATH": unknown command terminated with exit code 126
要进行调试,请将您的清单文件中所使用的映像更新为其他映像,如 busybox 镜像(来自 Docker 网站)。
2. 要验证 kube-dns 服务的集群 IP 位于您的 pod 的 /etc/resolv.conf 中,在 pod 内的 shell 中运行以下命令:
cat /etc/resolv.conf
以下示例 resolv.conf 显示的是为 DNS 请求被配置指向 10.100.0.10 的 pod。IP 必须与您的 kube-dns 服务的 ClusterIP 匹配:
nameserver 10.100.0.10 search default.svc.cluster.local svc.cluster.local cluster.local ec2.internal options ndots:5
**注意:**您可以通过 pod 规范中的 dnsPolicy 字段管理您的 pod 的 DNS 配置。若此字段未被填充,则将默认使用 ClusterFirst DNS 策略。
3. 要验证您的 pod 是否可以使用默认 ClusterIP 解析内部域,请在 pod 内的 shell 中运行以下命令:
nslookup kubernetes.default 10.100.0.10
输出:
Server: 10.100.0.10 Address: 10.100.0.10#53 Name: kubernetes.default.svc.cluster.local Address: 10.100.0.1
4. 要验证您的 pod 是否可以使用默认 ClusterIP 解析外部域,请在 pod 内的 shell 中运行以下命令:
nslookup amazon.com 10.100.0.10
输出:
Server: 10.100.0.10 Address: 10.100.0.10#53 Non-authoritative answer: Name: amazon.com Address: 176.32.98.166 Name: amazon.com Address: 205.251.242.103 Name: amazon.com Address: 176.32.103.205
5. 要验证您的 pod 是否可以直接使用 CoreDNS pod 的 IP 地址进行解析,请在 pod 内的 shell 中运行以下命令:
nslookup kubernetes COREDNS_POD_IP nslookup amazon.com COREDNS_POD_IP
**注意:**将 COREDNS_POD_IP 替换为终端节点 IP,而且此类终端节点 IP 是您之前使用的 kubectl 获取的终端节点之一。
从 CoreDNS pod 获取更多详细日志以进行调试
1. 开启 CoreDNS 容器组(pod)的调试日志,并添加日志插件至 CoreDNS ConfigMap:
kubectl -n kube-system edit configmap coredns
2. 在输出的编辑器屏幕中,添加日志字符串。例如:
kind: ConfigMap apiVersion: v1 data: Corefile: | .:53 { log # Enabling CoreDNS Logging errors health kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure upstream fallthrough in-addr.arpa ip6.arpa } ... ...
**注意:**重新加载配置 CoreDNS 需要几分钟时间。要立即应用更改,您可以逐个重新启动 pod。
3. 检查 CoreDNS 日志是否失败,或获得来自应用程序 pod 的任何命中结果:
kubectl logs --follow -n kube-system --selector 'k8s-app=kube-dns'
更新 ndots 值
DNS 将 nameserver 用于名称解析,后者通常为 kube-dns 服务的 ClusterIP。DNS 使用搜索补充查询名称,使其成为完全限定域名。ndots 的值为在初次绝对查询前名称中必须出现的用于解析查询的点数。
例如,您可以在未完全限定的域名中将 ndots 选项设置为默认值 5。然后,所有不属于内部域 cluster.local 的外部域将在查询前附加到搜索域。
见以下应用程序 pod 设置为 /etc/resolv.conf 的示例:
nameserver 10.100.0.10 search default.svc.cluster.local svc.cluster.local cluster.local ec2.internal options ndots:5
CoreDNS 会在被查询的域中查找五个点。如果 pod 为 amazon.com 发起 DNS 解析调用,则您的日志将类似于以下内容:
[INFO] 192.168.3.71:33238 - 36534 "A IN amazon.com.default.svc.cluster.local. udp 54 false 512" NXDOMAIN qr,aa,rd 147 0.000473434s [INFO] 192.168.3.71:57098 - 43241 "A IN amazon.com.svc.cluster.local. udp 46 false 512" NXDOMAIN qr,aa,rd 139 0.000066171s [INFO] 192.168.3.71:51937 - 15588 "A IN amazon.com.cluster.local. udp 42 false 512" NXDOMAIN qr,aa,rd 135 0.000137489s [INFO] 192.168.3.71:52618 - 14916 "A IN amazon.com.ec2.internal. udp 41 false 512" NXDOMAIN qr,rd,ra 41 0.001248388s [INFO] 192.168.3.71:51298 - 65181 "A IN amazon.com. udp 28 false 512" NOERROR qr,rd,ra 106 0.001711104s
**注意:**NXDOMAIN 指的是未找到域记录,而 NOERROR 是指已找到域记录。
在最终的绝对域上进行最后调用前,使用 amazon.com 对每个搜索域进行预置。最终域名以点 (.) 作为结尾,使其成为完全限定域名。这意味着每次外部域名查询都会有四到五次额外调用,并可能导致 CoreDNS 容器组(pod)不堪重负。
要解决此问题,请将 ndots 更改为 1,这只会查找单点。或者,在查询或使用的域末尾附加一个点 (.)。例如:
nslookup example.com.
请考虑 VPC 解析器 (AmazonProvidedDNS) 的限制
Amazon Virtual Private Cloud (Amazon VPC) 解析器仅可接受在每个网络接口上每秒发送 1024 个数据包的最大硬限制。如果相同节点上有多个 CoreDNS 容器组(pod),则外部域查询达到此限制的几率更大。
要在独立实例上使用 PodAntiAffinity(来自 Kubernetes 网站)规则来安排 CoreDNS 容器组(pod),添加以下选项至 CoreDNS 部署:
podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - podAffinityTerm: labelSelector: matchExpressions: - key: k8s-app operator: In values: - kube-dns topologyKey: kubernetes.io/hostname weight: 100
使用 tcpdump 捕获来自 Amazon EKS Worker 节点的 CoreDNS 包
使用 tcpdump 工具执行包捕获,以帮助诊断 DNS 解析问题。此工具有助于验证 DNS 请求的网络流量是否会到达您的 CoreDNS 容器组(pod)以及是否存在潜在的网络连接问题。要使用 tcpdump,请完成以下步骤。
1. 查找正在运行 CoreDNS pod 的 Worker 节点:
kubectl get pod -n kube-system -l k8s-app=kube-dns -o wide
2. 使用 SSH 连接到正在运行 CoreDNS pod 的 Worker 节点,然后安装 tcpdump 工具:
sudo yum install tcpdump –y
3. 查找 Worker 节点上的 CoreDNS pod 进程 ID:
ps ax | grep coredns
4. 在 Worker 节点上,对 CoreDNS pod 网络执行包捕获操作,以监控 UDP 端口 53 的网络流量:
sudo nsenter -n -t PID tcpdump udp port 53
5. 从单独的终端获取 CoreDNS 服务和 pod IP:
kubectl describe svc kube-dns -n kube-system
**注意:**请记下在“IP”字段中找到的服务 IP 以及在“端点”字段中找到的 pod IP。
6. 启动一个您将从中测试 DNS 服务的 pod。以下示例使用 Ubuntu 容器镜像:
kubectl run ubuntu --image=ubuntu sleep 1d kubectl exec -it ubuntu sh
7. 使用 nslookup 工具对域执行 DNS 查询,例如 amazon.com:
nslookup amazon.com
对步骤 5 中的 CoreDNS 服务 IP 显式执行相同查询:
nslookup amazon.com COREDNS_SERVICE_IP
对步骤 5 中的每个 CoreDNS pod IP 执行查询:
nslookup amazon.com COREDNS_POD_IP
**注意:**如果您正运行多个 CoreDNS pod,请执行多个查询,以便使得至少有一个查询发送至从中捕获流量的 pod。
8. 检查包捕获结果。
如果您遇到监控的 CoreDNS pod 出现 DNS 查询超时并且没有看到包捕获中的查询,则您可能存在网络连接问题。请务必检查 Worker 节点之间的网络可达性。
如果您在未捕获的容器组(pod)IP 上观察到 DNS 查询超时,请按照步骤 2-4 在相关 Worker 节点上执行另一次包捕获。
要保存包捕获的结果以供后续参考,请在 tcpdump 命令中添加 -w FILE_NAME 标志。以下示例将结果写入到名为 capture.pcap 的文件:
tcpdump -w capture.pcap udp port 53
相关信息
相关内容
- 已提问 6 个月前lg...
- 已提问 1 个月前lg...
- 已提问 2 个月前lg...
- 已提问 23 天前lg...
- 已提问 1 个月前lg...
- AWS 官方已更新 2 年前
- AWS 官方已更新 7 个月前
- AWS 官方已更新 10 个月前
- AWS 官方已更新 1 年前