AWS announces preview of AWS Interconnect - multicloud
AWS announces AWS Interconnect – multicloud (preview), providing simple, resilient, high-speed private connections to other cloud service providers. AWS Interconnect - multicloud is easy to configure and provides high-speed, resilient connectivity with dedicated bandwidth, enabling customers to interconnect AWS networking services such as AWS Transit Gateway, AWS Cloud WAN, and Amazon VPC to other cloud service providers with ease.
如何故障排除 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。
完成下面的步骤:
-
获取您的 CoreDNS 服务的 ClusterIP:
kubectl get service kube-dns -n kube-system -
验证 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)状态。
-
验证安全组或网络访问控制列表(网络 ACL)与 CoreDNS 通信时没有阻止容器组(pod)。
有关更多信息,请参阅为什么我的容器组无法连接到 Amazon EKS 中的其他容器组?
验证 kube-proxy 容器组(pod)是否正在运行
要验证 kube-proxy 容器组(pod)是否可以访问集群的 API 服务器,请检查控制面板的日志中是否存在超时错误。此外,请检查是否存在 403 未经授权错误。
获取 kube-proxy 日志:
kubectl logs -n kube-system --selector 'k8s-app=kube-proxy'
**注意:**kube-proxy 从控制面板获取端点并在每个节点上创建 iptables 规则。
检查问题发生时 CoreDNS 容器组(pod)的 CPU 利用率
Amazon EKS CoreDNS 插件仅为 CoreDNS 容器组(pod)的内存添加了 170Mi 的限制。CoreDNS 容器组(pod)没有定义 CPU 限制,因此容器可以使用其运行的节点上的所有可用 CPU 资源。如果节点 CPU 利用率达到 100%,那么您的 Amazon EKS 应用程序日志中可能会出现 DNS 超时错误。这是因为 CoreDNS 容器组(pod)没有足够的 CPU 资源来处理所有 DNS 查询。
连接到应用程序容器组(pod)以解决 DNS 问题
完成下面的步骤:
-
要在应用程序容器组(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
要进行调试,请将清单文件中使用的映像更新为另一个映像,例如 Docker 网站上的 busybox 映像。
-
验证 kube-dns 服务的集群 IP 地址是否在您的容器组(pod)的 /etc/resolv.conf 文件中。在容器组(pod)内的 Shell 中运行以下命令:
cat /etc/resolv.conf以下示例 resolv.conf 文件显示了一个容器组(pod),该容器组(pod)配置为将 DNS 请求指向 10.100.0.10。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 策略。有关 ClusterFirst DNS 策略的更多信息,请参阅 Kubernetes 网站上的 Pod 的 DNS 策略。
-
要验证您的容器组(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 -
要验证您的容器组(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 -
验证您的容器组(pod)是否可以直接使用 CoreDNS 容器组(pod)IP 地址进行解析。在容器组(pod)内的 Shell 中运行以下命令:
nslookup kubernetes COREDNS_POD_IP nslookup amazon.com COREDNS_POD_IP**注意:**将 COREDNS_POD_IP 替换为 kubectl 获取的端点中的某个端点的 IP 地址。
从 CoreDNS 容器组(pod)中获取更多详细日志以进行调试
完成下面的步骤:
-
打开 CoreDNS 容器组(pod)的调试日志,然后将日志插件添加到 CoreDNS ConfigMap 中:
kubectl -n kube-system edit configmap coredns**注意:**有关更多信息,请参阅 CoreDNS 网站上的 log plugin。
-
在输出中显示的编辑器界面中,添加日志字符串:
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)。
-
检查 CoreDNS 日志,查看应用程序容器组(pod)的解析请求是否有失败或成功记录:
kubectl logs --follow -n kube-system --selector 'k8s-app=kube-dns'
更新 ndots 值
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 规则在不同的实例上调度 CoreDNS 容器组(pod),请在 CoreDNS 部署中添加以下选项:
podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - podAffinityTerm: labelSelector: matchExpressions: - key: k8s-app operator: In values: - kube-dns topologyKey: kubernetes.io/hostname weight: 100
**注意:**有关 PodAntiAffinity 的更多信息,请参阅 Kubernetes 网站上的 Pod 间的亲和性和反亲和性。
使用 tcpdump 捕获来自 Amazon EKS Worker 节点的 CoreDNS 数据包
为了帮助您诊断 DNS 解析问题,请使用 tcpdump 工具来捕获数据包:
-
找到运行 CoreDNS 容器组(pod)的 Worker 节点:
kubectl get pod -n kube-system -l k8s-app=kube-dns -o wide -
使用 SSH 连接到运行 CoreDNS 容器组(pod)的 Worker 节点,然后安装 tcpdump 工具:
sudo yum install tcpdump –y -
在 Worker 节点上找到 CoreDNS 容器组(pod)进程 ID:
ps ax | grep coredns -
在 Worker 节点上,在 CoreDNS 容器组(pod)网络上捕获数据包,以监控 UDP 端口 53 上的网络流量:
sudo nsenter -n -t PID tcpdump udp port 53 -
从另一个终端获取 CoreDNS 服务和容器组(pod)IP 地址:
kubectl describe svc kube-dns -n kube-system注意:记下位于 IP 字段中的服务 IP 地址和位于端点字段中的容器组(pod)IP 地址。
-
启动一个容器组(pod)来测试其中的 DNS 服务。以下示例使用 Ubuntu 容器映像:
kubectl run ubuntu --image=ubuntu sleep 1d kubectl exec -it ubuntu sh -
使用 nslookup 工具对域名执行 DNS 查询,例如 amazon.com:
nslookup amazon.com对 CoreDNS 服务 IP 地址明确执行相同的查询:
nslookup amazon.com COREDNS_SERVICE_IP对每个 CoreDNS 容器组(pod)的 IP 地址执行查询:
nslookup amazon.com COREDNS\_POD\_IP**注意:**如果您正在运行多个 CoreDNS 容器组(pod),请执行多个查询,以便至少向您从中捕获流量的容器组(pod)发送一个查询。
-
查看数据包捕获结果。
如果您监控的 CoreDNS 容器组(pod)遇到 DNS 查询超时问题,并且您在数据包捕获中看不到相关查询,请检查您的网络连接。确保检查 Worker 节点之间的网络连通正常。
如果您看到针对没有捕获数据包的容器组(pod)IP 地址的 DNS 查询超时,则在相关 Worker 节点上执行另一次数据包捕获操作。
要保存数据包捕获的结果,请在 tcpdump 命令中添加 -w FILE_NAME 标志。以下示例将结果写入名为 capture.pcap 的文件中:
tcpdump -w capture.pcap udp port 53
相关信息
用于 Kubernetes 集群 DNS 的 CoreDNS GA 正式发布
这篇文章位于 Kubernetes 网站。

