如何在 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 Pod 處於 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 位址。
**注意:**對於自動化部署,您可以在啟動範本的 userdata 區段中修改 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 Command Line Interface (AWS CLI) 命令時收到錯誤訊息,請參閱對 AWS CLI 錯誤進行疑難排解。此外,請確定您使用的是最新的 AWS CLI 版本。
解決由連接埠衝突導致的 CrashLoopBackOff 錯誤
如果 NodeLocalDNS Pod 因連接埠 53 錯誤而進入 CrashLoopBackOff,則這是因為 Amazon EKS 自動模式節點會保留連接埠 53。若要解決此問題,請選擇以下其中一種方法:
方法 1: 新增節點同質規則以排除自動模式節點
請完成以下步驟:
-
編輯 NodeLocalDNS daemonset:
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 中,找出 health 外掛程式組態並修改連接埠。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 -
若要更新 daemonset 運作狀態檢查組態以符合新的連接埠,請執行以下命令:
kubectl edit daemonset node-local-dns -n kube-system -
找出 livenessProbe 和 readinessProbe 區段,並將連接埠更新為符合新的運作狀態檢查連接埠。
解決 DNS 查詢逾時錯誤
如果您的 Pod 發生 DNS 查詢逾時,請確認您的安全群組和網路 ACL 允許連接埠 53 上的 TCP 與 UDP 流量。Pod 對 Pod 通訊需要此流量。
請完成以下步驟:
-
若要識別附加到您節點的安全群組,請執行以下 describe-instances AWS CLI 命令:
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 console (Amazon EC2 主控台)。
-
在導覽窗格中,選擇 Security Groups (安全群組)。
-
選取本節步驟 1 中識別出的安全群組。
-
選擇 Inbound rules (傳入規則) 索引標籤。
-
確認有規則可允許來自 Pod CIDR 範圍、連接埠 53 上的 TCP 與 UDP 流量。
**注意:**如果規則不存在,請選擇 Edit inbound rules (編輯傳入規則)。接著,新增 TCP 與 UDP 的連接埠 53 規則,並將來源設為您的 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 daemonset,請執行以下命令:
kubectl rollout restart daemonset node-local-dns -n kube-system
相關資訊
Kubernetes 網站上的使用 CoreDNS 進行服務探索
Kubernetes 網站上的以 IPVS 模式執行 kube-proxy
- 語言
- 中文 (繁體)

相關內容
- 已提問 1 年前
- 已提問 1 年前
- 已提問 1 年前
- 已提問 3 年前