如何在 EKS 集群中安装 NodeLocalDNS 并对问题进行故障排除?
我想在 Amazon Elastic Kubernetes Service (Amazon EKS) 集群中安装 NodeLocalDNS 并对问题进行故障排除。
解决方法
先决条件:
安装 NodeLocalDNS
NodeLocalDNS 使用链路本地 IP 地址在每个节点上提供 DNS 缓存。链路本地地址是 169.254.0.0/16 范围内的 IP 地址,仅在网段内有效。
**注意:**NodeLocalDNS 的标准链路本地 IP 地址是 169.254.20.10。除非您的环境中存在特定冲突,否则请勿更改此值。
要在您的 Amazon EKS 集群中安装 NodeLocalDNS,请完成以下步骤:
-
运行以下 curl 命令,从 Kubernetes 存储库下载 NodeLocalDNS 清单:
curl -Lo nodelocaldns.yaml.template https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml -
要检索集群的 kube-dns 服务 IP 地址,请运行以下命令:
kubectl get svc kube-dns -n kube-system -o jsonpath='{.spec.clusterIP}'**注意:**记下输出中的 IP 地址。
-
要检索集群的域,请运行以下命令:
kubectl get configmap coredns -n kube-system -o yaml | grep 'kubernetes'输出显示您的集群域。
-
要确定您的 kube-proxy 模式,请运行以下命令:
kubectl get configmap kube-proxy-config -n kube-system -o yaml | grep mode输出显示 iptables 或 ipvs 作为模式值。
-
根据您的 kube-proxy 模式编辑 NodeLocalDNS 清单。
对于 iptables 模式,请使用以下命令编辑清单:
# Set environment variables for node-local-dns kubedns=$(kubectl get svc kube-dns -n kube-system -o jsonpath={.spec.clusterIP}) domain=cluster.local localdns=`169.254.20.10` # Update the manifest with your cluster's specific values: sed "s/__PILLAR__LOCAL__DNS__/$localdns/g; s/__PILLAR__DNS__DOMAIN__/$domain/g; s/__PILLAR__DNS__SERVER__/$kubedns/g" nodelocaldns.yaml.template > nodelocaldns.yaml**注意:**如果您的集群使用不同的域,请将 cluster.local 替换为步骤 3 中的集群域。如果不同,请将 169.254.20.10 替换为您的集群的链路本地 IP 地址。
对于 IPVS 模式,请使用以下命令编辑清单:
# Set environment variables for node-local-dns kubedns=$(kubectl get svc kube-dns -n kube-system -o jsonpath={.spec.clusterIP}) domain=cluster.local localdns=169.254.20.10 # Update the manifest with your cluster's specific values: sed "s/__PILLAR__LOCAL__DNS__/$localdns/g; s/__PILLAR__DNS__DOMAIN__/$domain/g; s/,__PILLAR__DNS__SERVER__//g; s/__PILLAR__CLUSTER__DNS__/$kubedns/g" nodelocaldns.yaml.template > nodelocaldns.yaml**注意:**如果您的集群使用不同的域,请将 cluster.local 替换为步骤 3 中的集群域。如果不同,请将 169.254.20.10 替换为您的集群的链路本地 IP 地址。在 IPVS 模式下,您需要配置容器组 (pod) 以使用 NodeLocalDNS。请参阅“配置容器组 (pod) 以使用 NodeLocalDNS(仅限 IPVS 模式)”部分。
-
要应用 NodeLocalDNS 清单,请运行以下命令:
kubectl apply -f nodelocaldns.yaml -
要验证 NodeLocalDNS 容器是否处于 Running(正在运行)状态,请运行以下命令:
kubectl get pods -n kube-system -l k8s-app=node-local-dns
配置容器组 (pod) 以使用 NodeLocalDNS(仅限 IPVS 模式)
**重要事项:**本部分仅在您的集群为 kube-proxy 使用 IPVS 模式时适用。如果您的集群使用 iptables 模式,则 DNS 流量会自动重定向到 NodeLocalDNS。
对于 IPVS 模式集群,您必须手动配置容器组 (pod) 以使用 NodeLocalDNS。要将您的容器组 (pod) 定向到 NodeLocalDNS,您可以配置单个容器组 (pod) 或使用 kubelet 配置集群。
配置单个容器组 (pod)
要配置单个容器组 (pod),请将以下配置添加到您的容器组 (pod) 规范中:
spec: dnsPolicy: "None" dnsConfig: nameservers: - [169.254.20.10] searches: - default.svc.cluster.local - svc.cluster.local - cluster.local options: - name: ndots value: "5"
**注意:**请将 169.254.20.10 替换为您的集群的链路本地 IP 地址。如果您的集群使用不同的域,请将 cluster.local 替换为您的集群域。
使用 kubelet 配置集群
在 IPVS 模式下,NodeLocalDNS 仅在链路本地地址 169.254.20.10 上侦听。您必须修改 kubelet 配置以指向此链路本地地址。
要配置集群中的所有容器组 (pod) 以使用 NodeLocalDNS,同时修改每个节点上的 kubelet 配置,请完成以下步骤:
-
编辑 kubelet 配置文件。添加以下配置:
{ "clusterDNS": ["169.254.20.10"], "clusterDomain": "cluster.local" }**注意:**请将 169.254.20.10 替换为您的集群的链路本地 IP 地址。如果您的集群使用不同的域,请将 cluster.local 替换为您的集群域。
-
要在每个节点上重新启动 kubelet 服务,请运行以下 sudo 命令:
sudo systemctl restart kubelet -
要验证 kubelet 配置,请运行以下命令:
cat /etc/kubernetes/kubelet/config.json | grep clusterDNS**注意:**输出显示 169.254.20.10 作为 NodeLocalDNS 链路本地 IP 地址。
**注意:**对于自动部署,您可以在启动模板的用户数据部分修改 kubelet 配置。有关更多信息,请参阅如何将自定义用户数据与 AL2023 Amazon EKS 节点一起使用?
验证您是否已正确安装 NodeLocalDNS
要验证 NodeLocalDNS 是否正常运行,请完成以下步骤:
-
要创建测试容器组 (pod),请运行以下命令:
kubectl run test-dns --image=busybox:1.28 --restart=Never --rm -it -- nslookup kubernetes.default -
如果 NodeLocalDNS 容器组 (pod) 处于 CrashLoopBackOff 状态,并出现指示端口 53 已被占用的错误。请查看输出以确认 DNS 查询已正确解析。
-
要验证 DNS 查询是否正在使用 NodeLocalDNS,请运行以下命令:
kubectl logs -n kube-system -l k8s-app=node-local-dns --tail=50日志显示 DNS 查询正在由 NodeLocalDNS 进行处理。
**注意:**默认情况下,NodeLocalDNS 中未启用日志记录。要查看日志,请在 node-local-dns ConfigMap 中启用日志记录。
# kubectl edit configmaps -n kube-system node-local-dns apiVersion: v1 kind: ConfigMap metadata: name: node-local-dns namespace: kube-system data: Corefile: | cluster.local:53 { log # Enable logging errors cache 30 ... }
对 NodeLocalDNS 问题进行故障排除
**注意:**如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI。
解决由端口冲突引起的 CrashLoopBackOff 错误
如果 NodeLocalDNS 容器组 (pod) 进入 CrashLoopBackOff 状态并出现端口 53 错误,则会发生这种情况,这是因为 Amazon EKS 自动模式节点保留了端口 53。要解决此问题,请选择以下方法之一:
方法 1: 添加节点关联性规则以排除自动模式节点
完成以下步骤:
-
编辑 NodeLocalDNS 进程守护程序:
kubectl edit daemonset node-local-dns -n kube-system -
在 spec.template.spec 下添加以下关联性配置:
affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: eks.amazonaws.com/compute-type operator: NotIn values: - auto -
保存更改,然后验证容器组 (pod) 是否成功重新启动。
方法 2: 修改 NodeLocalDNS ConfigMap 以更改运行状况检查端口
完成以下步骤:
-
要查看当前的 NodeLocalDNS ConfigMap,请运行以下命令:
kubectl get configmap node-local-dns -n kube-system -o yaml -
要编辑 ConfigMap 以更改运行状况检查端口,请运行以下命令:
kubectl edit configmap node-local-dns -n kube-system -
在 ConfigMap 中,找到运行状况插件配置并修改端口。ConfigMap 结构如下所示:
apiVersion: v1 kind: ConfigMap metadata: name: node-local-dns namespace: kube-system data: Corefile: | cluster.local:53 { errors cache { success 9984 30 denial 9984 5 } reload loop bind IP_ADDRESS forward. __PILLAR__CLUSTER__DNS__ { force_tcp } prometheus :9253 health 169.254.20.10:8081 }**注意:**请将 health 行中的端口从 8081 替换为您所需的端口。如果不同,请将 169.254.20.10 替换为您的集群的链路本地 IP 地址。
-
保存更改。
-
要重新启动 NodeLocalDNS 容器组 (pod),请运行以下命令:
kubectl rollout restart daemonset node-local-dns -n kube-system -
要更新进程守护程序运行状况检查配置以匹配新端口,请运行以下命令:
kubectl edit daemonset node-local-dns -n kube-system -
找到 livenessProbe 和 readinessProbe 部分,更新端口以匹配新的运行状况检查端口。
解决 DNS 查询超时错误
如果您的容器组 (pod) 遇到 DNS 查询超时,请验证您的安全组和网络 ACL 是否允许端口 53 上的 TCP 和 UDP 流量。这些流量是容器组 (pod) 间通信所必需的。
完成以下步骤:
-
要识别附加到您的节点的安全组,请运行以下 AWS CLI 命令 describe-instances:
aws ec2 describe-instances --filters "Name=tag:eks:cluster-name,Values=YOUR-CLUSTER-NAME" --query "Reservations[*].Instances[*].SecurityGroups[*].[GroupId,GroupName]" --output table**注意:**请将 YOUR-CLUSTER-NAME 替换为您的 Amazon EKS 集群名称。
-
打开 Amazon EC2 控制台。
-
在导航窗格中,选择 Security Groups(安全组)。
-
选择本部分步骤 1 中确定的安全组。
-
选择 Inbound rules(入站规则)选项卡。
-
验证是否存在允许来自容器组 (pod) CIDR 范围的端口 53 上的 TCP 和 UDP 流量的规则。
**注意:**如果规则不存在,请选择 Edit inbound rules(编辑入站规则)。然后,在端口 53 上添加 TCP 和 UDP 规则,并将源设置为您的容器组 (pod) CIDR 范围。
解决 "Connection refused" 错误消息
如果容器组 (pod) 尝试使用 NodeLocalDNS 时收到 "Connection refused" 错误消息,请验证是否至少有一个 CoreDNS 容器组 (pod) 正在运行。
要检查 CoreDNS 容器组 (pod) 状态,请运行以下命令:
kubectl get pods -n kube-system -l k8s-app=kube-dns
如果没有 CoreDNS 容器组 (pod) 正在运行或容器组 (pod) 处于故障状态,请重新启动 CoreDNS 部署。要重新启动部署,请运行以下命令:
kubectl rollout restart deployment coredns -n kube-system
要验证 CoreDNS 容器组 (pod) 是否正在运行,请运行以下命令:
kubectl get pods -n kube-system -l k8s-app=kube-dns -w
要在 CoreDNS 容器组 (pod) 运行后重新启动 NodeLocalDNS 进程守护程序,请运行以下命令:
kubectl rollout restart daemonset node-local-dns -n kube-system
相关信息
Kubernetes 网站上的 Using CoreDNS for Service Discovery(使用 CoreDNS 进行服务发现)
Kubernetes 网站上的 Run kube-proxy in IPVS Mode(在 IPVS 模式下运行 kube-proxy)
- 语言
- 中文 (简体)

相关内容
AWS 官方已更新 8 个月前