針對來自 Pod 內部但不是來自背景工作節點的 DNS 解析失敗進行疑難排解
本文討論當您嘗試從 Azure Kubernetes Service (AKS) 叢集建立來自Microsoft Azure Kubernetes Service (AKS) 叢集的輸出連線時,如何針對從 Pod 內部發生但不是從背景工作節點發生的功能變數名稱系統 (DNS) 解析失敗進行疑難解答。
必要條件
Kubernetes kubectl 工具,或連線至叢集的類似工具。 若要使用 Azure CLI 安裝 kubectl,請執行 az aks install-cli 命令。
用於處理封裝的 apt-get 命令行工具。
DNS 查閱的主機命令行工具。
Background
針對 DNS 解析,Pod 會將要求傳送至命名空間中的 kube-system
CoreDNS Pod。
如果 DNS 查詢適用於內部元件,例如服務名稱,則 CoreDNS Pod 會自行回應。 不過,如果要求是針對外部網域,CoreDNS Pod 會將要求傳送至上游 DNS 伺服器。
上游 DNS 伺服器是根據 Pod 執行所在的背景工作節點 resolv.conf 檔案取得。 resolv.conf 檔案 ( /run/systemd/resolve/resolv.conf) 會根據背景工作節點執行所在的虛擬網路 DNS 設定進行更新。
疑難排解檢查清單
若要針對Pod內的 DNS 問題進行疑難解答,請使用下列各節中的指示。
步驟 1:針對 Pod 內的 DNS 問題進行疑難解答
您可以使用 kubectl 命令來針對 Pod 內的 DNS 問題進行疑難解答,如下列步驟所示:
確認 CoreDNS Pod 正在執行:
kubectl get pods -l k8s-app=kube-dns -n kube-system
檢查 CoreDNS Pod 是否過度使用:
$ kubectl top pods -n kube-system -l k8s-app=kube-dns NAME CPU(cores) MEMORY(bytes) coredns-dc97c5f55-424f7 3m 23Mi coredns-dc97c5f55-wbh4q 3m 25Mi
確認裝載 CoreDNS Pod 的節點未過度使用。 此外,取得裝載 CoreDNS Pod 的節點:
kubectl get pods -n kube-system -l k8s-app=kube-dns -o jsonpath='{.items[*].spec.nodeName}'
檢查這些節點的使用方式:
kubectl top nodes
確認 CoreDNS Pod 的記錄:
kubectl logs -l k8s-app=kube-dns -n kube-system
注意
若要查看更多偵錯資訊,請在 CoreDNS 中啟用詳細信息記錄。 若要在 CoreDNS 中啟用詳細資訊記錄,請參閱 針對 AKS 中的 CoreDNS 自定義進行疑難解答。
步驟 2:建立測試 Pod 以執行命令
如果 DNS 解析失敗,請遵循下列步驟:
在叢集中啟動測試 Pod:
kubectl run -it --rm aks-ssh --namespace <namespace> --image=debian:stable
當測試 Pod 正在執行時,您將取得 Pod 的存取權。
執行下列命令來安裝所需的套件:
apt-get update -y apt-get install dnsutils -y
確認 resolv.conf 檔案有正確的專案:
cat /etc/resolv.conf search default.svc.cluster.local svc.cluster.local cluster.local 00idcnmrrm4edot5s2or1onxsc.bx.internal.cloudapp.net nameserver 10.0.0.10 options ndots:5
host
使用 命令來判斷是否已將 DNS 要求路由傳送至上游伺服器:$ host -a microsoft.com Trying "microsoft.com.default.svc.cluster.local" Trying "microsoft.com.svc.cluster.local" Trying "microsoft.com.cluster.local" Trying "microsoft.com.00idcnmrrm4edot5s2or1onxsc.bx.internal.cloudapp.net" Trying "microsoft.com" Trying "microsoft.com" ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62884 ;; flags: qr rd ra; QUERY: 1, ANSWER: 27, AUTHORITY: 0, ADDITIONAL: 5 ;; QUESTION SECTION: ;microsoft.com. IN ANY ;; ANSWER SECTION: microsoft.com. 30 IN NS ns1-39.azure-dns.com. ... ... ns4-39.azure-dns.info. 30 IN A 13.107.206.39 Received 2121 bytes from 10.0.0.10#53 in 232 ms
檢查 Pod 中的上游 DNS 伺服器,以判斷 DNS 解析是否正常運作。 例如,針對 Azure DNS,請執行下列 nslookup 命令:
$ nslookup microsoft.com 168.63.129.16 Server: 168.63.129.16 Address: 168.63.129.16#53 ... ... Address: 20.81.111.85
步驟 3:在明確指定上游 DNS 伺服器時,檢查 DNS 要求是否正常運作
如果您明確指定上游 DNS 伺服器時,來自 Pod 的 DNS 要求正在運作,請確認下列條件:
檢查 CoreDNS 的自訂 ConfigMap:
kubectl describe cm coredns-custom -n kube-system
如果自定義 ConfigMap 存在,請確認組態正確無誤。 如需詳細資訊,請參閱 使用 Azure Kubernetes Service 自定義 CoreDNS。
檢查網路原則是否封鎖用戶數據報通訊協定 (UDP) 埠 53 到命名空間中 CoreDNS Pod 的
kube-system
流量。檢查 CoreDNS Pod 是否位於不同的節點集區(系統節點集區)。 如果是,請檢查網路安全組 (NSG) 是否與封鎖 UDP 連接埠 53 上流量的系統節點集區相關聯。
檢查虛擬網路是否最近更新,以新增 DNS 伺服器。
如果發生虛擬網路更新,請檢查下列其中一個事件是否也已發生:
- 節點已重新啟動。
- 節點中的網路服務已重新啟動。
若要讓 DNS 設定中的更新生效,必須重新啟動節點上的網路服務和 CoreDNS Pod。 若要重新啟動網路服務或 Pod,請使用下列其中一種方法:
重新啟動節點。
調整新的節點。 (新的節點將會有更新的組態。
重新啟動節點中的網路服務,然後重新啟動 CoreDNS Pod。 執行下列步驟:
建立與節點的安全殼層 (SSH) 連線。 如需詳細資訊,請參閱連線到 Azure Kubernetes Service (AKS) 叢集節點以進行維護或疑難排解。
從節點內重新啟動網路服務:
systemctl restart systemd-networkd
檢查設定是否已更新:
cat /run/systemd/resolve/resolv.conf
重新啟動網路服務之後,請使用 kubectl 重新啟動 CoreDNS Pod:
kubectl delete pods -l k8s-app=kube-dns -n kube-system
檢查虛擬網路 DNS 設定中是否指定多個 DNS 伺服器。
如果在 AKS 虛擬網路中指定多個 DNS 伺服器,就會發生下列其中一個順序:
AKS 節點會將要求傳送至上游 DNS 伺服器作為數列的一部分。 在此序列中,要求會傳送至虛擬網路中設定的第一部 DNS 伺服器(如果 DNS 伺服器可連線並執行)。 如果無法連線到第一部 DNS 伺服器且未回應,則會將要求傳送至下一個 DNS 伺服器。
AKS 節點會使用 解析程式 命令將要求傳送至 DNS 伺服器。 您可以在 AKS 節點的 /run/systemd/resolve/resolve.conf 找到此解析程式的組態檔。
是否有多部伺服器? 在此情況下,解析程式連結庫會依列出的順序加以查詢。 (使用的策略是先嘗試名稱伺服器。如果查詢逾時,請嘗試下一個名稱伺服器,並繼續直到名稱伺服器清單用盡為止。然後,查詢會繼續嘗試連線到名稱伺服器,直到進行重試次數上限為止。
CoreDNS 會 使用轉寄 外掛程式將要求傳送至上游 DNS 伺服器。 此外掛程式會使用隨機演算法來選取上游 DNS 伺服器。 在此序列中,要求可以移至虛擬網路中提及的任何 DNS 伺服器。 例如,您可能會收到下列輸出:
$ kubectl describe cm coredns -n kube-system Name: coredns Namespace: kube-system Labels: addonmanager.kubernetes.io/mode=Reconcile k8s-app=kube-dns kubernetes.io/cluster-service=true Annotations: <none> Data ==== Corefile: ---- .:53 { errors ready health kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa } prometheus :9153 forward . /etc/resolv.conf # Here! cache 30 loop reload loadbalance import custom/*.override } import custom/*.server BinaryData ==== Events: <none>
在 CoreDNS
forward
外掛程式中,policy
會指定要用於選取上游伺服器的原則。 原則如下表所定義。原則名稱 描述 random
實作隨機上游選取範圍的原則。 此原則是預設原則。 round_robin
根據循環配置資源排序來選取主機的原則。 sequential
根據循序順序選取主機的原則。 如果 AKS 虛擬網路包含多個 DNS 伺服器,則來自 AKS 節點的要求可能會移至第一部 DNS 伺服器。 不過,來自 Pod 的要求可能會移至第二部 DNS 伺服器。
原因:DNS 要求的多個目的地
如果指定了兩部自定義 DNS 伺服器,而第三部 DNS 伺服器則指定為 Azure DNS(168.63.129.16),如果節點正在執行且可連線,則會將要求傳送至第一部自定義 DNS 伺服器。 在此設定中,節點可以解析自定義網域。 不過,某些來自 Pod 的 DNS 要求可能會導向至 Azure DNS。 這是因為 CoreDNS 可以隨機選取上游伺服器。 在此案例中,無法解析自定義網域。 因此,DNS 要求會失敗。
解決方案:從虛擬網路設定移除 Azure DNS
建議您不要在虛擬網路設定中結合 Azure DNS 與自定義 DNS 伺服器。 如果您想要使用自定義 DNS 伺服器,請在虛擬網路設定中只新增自訂 DNS 伺服器。 然後,在自定義 DNS 伺服器的轉寄站設定中設定 Azure DNS。
如需詳細資訊,請參閱使用自有 DNS 伺服器的名稱解析。
協力廠商連絡資訊免責聲明
Microsoft 提供協力廠商連絡資訊,以協助您尋找有關此主題的其他資訊。 此連絡資訊可能會變更而不另行通知。 Microsoft 不保證協力廠商連絡資訊的準確性。
與我們連絡,以取得說明
如果您有問題或需要相關協助,請建立支援要求,或詢問 Azure community 支援。 您也可以向 Azure 意見反應社群提交產品意見反應。