發(fā)現(xiàn)核心:CoreDNS架構(gòu)原理與實(shí)戰(zhàn)配置指南)
1. 項(xiàng)目概述為什么Kubernetes離不開(kāi)自己的DNS在Kubernetes集群里服務(wù)發(fā)現(xiàn)是個(gè)基礎(chǔ)到不能再基礎(chǔ)卻又至關(guān)重要的問(wèn)題。想象一下你部署了一個(gè)名為my-api的微服務(wù)它可能會(huì)因?yàn)閿U(kuò)縮容、節(jié)點(diǎn)故障或滾動(dòng)更新其Pod的IP地址隨時(shí)都在變。如果另一個(gè)服務(wù)my-frontend需要通過(guò)IP來(lái)調(diào)用my-api那簡(jiǎn)直就是一場(chǎng)運(yùn)維災(zāi)難你需要不斷更新配置這完全違背了云原生的彈性與自動(dòng)化理念。這就是Kubernetes內(nèi)置DNS服務(wù)存在的核心價(jià)值。它不是一個(gè)可選項(xiàng)而是集群的“神經(jīng)系統(tǒng)”負(fù)責(zé)將穩(wěn)定的服務(wù)名Service Name解析為動(dòng)態(tài)變化的Pod IP地址。默認(rèn)情況下從Kubernetes 1.13版本開(kāi)始這個(gè)“神經(jīng)系統(tǒng)”的核心組件就是CoreDNS。它取代了早期的kube-dns以其更高的性能、更靈活的插件化架構(gòu)成為了Kubernetes服務(wù)發(fā)現(xiàn)的官方標(biāo)準(zhǔn)。簡(jiǎn)單來(lái)說(shuō)沒(méi)有CoreDNSKubernetes集群內(nèi)的服務(wù)間通信將退回到原始的、手動(dòng)維護(hù)IP地址的“石器時(shí)代”集群的自動(dòng)化管理和微服務(wù)架構(gòu)的優(yōu)勢(shì)將無(wú)從談起。無(wú)論你是剛接觸k8s的開(kāi)發(fā)者還是負(fù)責(zé)維護(hù)生產(chǎn)集群的運(yùn)維工程師深入理解CoreDNS的工作原理、配置和排錯(cuò)都是構(gòu)建穩(wěn)定、可觀測(cè)的云原生應(yīng)用的必修課。2. CoreDNS在Kubernetes中的架構(gòu)與核心原理2.1 CoreDNS的核心工作流程要理解CoreDNS首先要明白它在Kubernetes集群中扮演的角色。它不是一個(gè)獨(dú)立于集群外的傳統(tǒng)DNS服務(wù)器而是一個(gè)以Pod形式運(yùn)行在kube-system命名空間下的集群附加組件。其工作流程可以概括為以下幾個(gè)核心步驟監(jiān)聽(tīng)與查詢接收CoreDNS Pod通過(guò)一個(gè)名為kube-dns的Service對(duì)外暴露服務(wù)其ClusterIP通常是10.96.0.10可配置。集群內(nèi)所有Pod的/etc/resolv.conf文件中的nameserver都被配置指向這個(gè)IP。當(dāng)Pod內(nèi)的應(yīng)用程序發(fā)起一個(gè)DNS查詢例如查詢my-api.default.svc.cluster.local時(shí)請(qǐng)求首先到達(dá)CoreDNS。插件鏈處理這是CoreDNS設(shè)計(jì)的精髓。它不像傳統(tǒng)DNS服務(wù)器那樣有固定的處理邏輯而是通過(guò)一個(gè)可配置的插件鏈Plugin Chain來(lái)處理請(qǐng)求。一個(gè)查詢請(qǐng)求會(huì)像流水線一樣依次經(jīng)過(guò)配置文件中啟用的各個(gè)插件。每個(gè)插件可以決定是直接響應(yīng)、修改請(qǐng)求、轉(zhuǎn)發(fā)請(qǐng)求還是將請(qǐng)求傳遞給下一個(gè)插件。與Kubernetes API交互對(duì)于Kubernetes集群內(nèi)的域名查詢最關(guān)鍵的一個(gè)插件是kubernetes插件。當(dāng)查詢的域名匹配集群內(nèi)服務(wù)域名格式如.svc.cluster.local時(shí)kubernetes插件會(huì)向Kubernetes API Server發(fā)起查詢獲取對(duì)應(yīng)Service、Pod或Endpoints的真實(shí)IP地址信息。響應(yīng)返回kubernetes插件從API Server獲取到IP信息后將其封裝成標(biāo)準(zhǔn)的DNS響應(yīng)報(bào)文沿原路返回給發(fā)起查詢的Pod。對(duì)于集群外的域名如www.example.comCoreDNS通常會(huì)配置forward插件將查詢請(qǐng)求轉(zhuǎn)發(fā)到上游的DNS服務(wù)器如宿主機(jī)配置的DNS或公共DNS8.8.8.8。這個(gè)流程確保了服務(wù)名的解析是完全動(dòng)態(tài)的、實(shí)時(shí)的與Kubernetes的資源狀態(tài)保持嚴(yán)格一致。2.2 關(guān)鍵配置文件解析CorefileCoreDNS的所有行為都由一個(gè)名為Corefile的配置文件驅(qū)動(dòng)。在Kubernetes中這個(gè)配置文件通常以一個(gè)ConfigMap的形式存在名為coredns位于kube-system命名空間。我們可以通過(guò)kubectl get configmap coredns -n kube-system -o yaml來(lái)查看其內(nèi)容。一個(gè)典型的默認(rèn)配置如下apiVersion: v1 data: Corefile: | .:53 { errors health { lameduck 5s } ready kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa ttl 30 } prometheus :9153 forward . /etc/resolv.conf cache 30 loop reload loadbalance } kind: ConfigMap我們來(lái)逐段拆解這個(gè)核心配置.:53這定義了一個(gè)服務(wù)器塊Server Block監(jiān)聽(tīng)所有網(wǎng)卡.的53端口DNS標(biāo)準(zhǔn)端口。errors將錯(cuò)誤日志打印到標(biāo)準(zhǔn)輸出。health提供健康檢查端點(diǎn)默認(rèn)在http://localhost:8080/health。ready提供就緒檢查端點(diǎn)當(dāng)所有插件加載完成后該端點(diǎn)返回200 OK。這對(duì)于Kubernetes的Readiness Probe很重要。kubernetes cluster.local ...這是核心插件。它告訴CoreDNS負(fù)責(zé)解析cluster.local及其子域如svc.cluster.local以及反向解析域in-addr.arpa,ip6.arpa的查詢。pods insecure啟用Pod的DNS記錄格式為pod-ip.namespace.pod.cluster.local。insecure選項(xiàng)意味著即使Pod沒(méi)有關(guān)聯(lián)的Service也會(huì)為其創(chuàng)建A記錄。在生產(chǎn)環(huán)境中出于安全考慮有時(shí)會(huì)省略此選項(xiàng)或使用pods verified模式。fallthrough如果查詢的域名在kubernetes插件域內(nèi)但未找到記錄則將查詢“墜落”到插件鏈中的下一個(gè)插件例如forward插件處理。ttl 30為DNS記錄設(shè)置生存時(shí)間TTL為30秒。較短的TTL有助于客戶端更快地感知到后端Pod IP的變化。prometheus :9153在9153端口暴露Prometheus格式的指標(biāo)方便監(jiān)控CoreDNS的性能和查詢量。forward . /etc/resolv.conf這是處理集群外域名的關(guān)鍵。它將所有未在kubernetes插件域內(nèi)匹配的查詢用.表示轉(zhuǎn)發(fā)到CoreDNS Pod內(nèi)/etc/resolv.conf文件中定義的上游DNS服務(wù)器。這通常是宿主機(jī)或自定義的DNS。cache 30啟用緩存緩存時(shí)間為30秒可以顯著減少對(duì)上游DNS和Kubernetes API的重復(fù)查詢壓力。loop檢測(cè)到簡(jiǎn)單的DNS轉(zhuǎn)發(fā)循環(huán)時(shí)發(fā)出警告并停止CoreDNS進(jìn)程。reload允許自動(dòng)重新加載Corefile。當(dāng)ConfigMap內(nèi)容更改后CoreDNS會(huì)在一段時(shí)間后自動(dòng)加載新配置無(wú)需重啟Pod。loadbalance對(duì)于同一個(gè)服務(wù)名有多個(gè)后端IP即Service對(duì)應(yīng)多個(gè)Pod的情況以輪詢r(jià)ound-robin方式返回IP地址實(shí)現(xiàn)基本的DNS負(fù)載均衡。理解這個(gè)Corefile是掌握CoreDNS配置和故障排查的基礎(chǔ)。3. Kubernetes中的DNS域名解析規(guī)則詳解在Kubernetes集群內(nèi)DNS解析有一套完整的命名規(guī)范。理解這些規(guī)則是進(jìn)行服務(wù)調(diào)用和問(wèn)題診斷的前提。3.1 完整的服務(wù)域名格式一個(gè)Service在集群內(nèi)擁有一個(gè)完整的、可被DNS解析的域名Fully Qualified Domain Name, FQDN。其標(biāo)準(zhǔn)格式為service-name.namespace-name.svc.cluster.localservice-name你定義的Service資源名稱例如my-api。namespace-nameService所在的命名空間例如default。如果調(diào)用方Pod與被調(diào)用的Service在同一個(gè)命名空間可以省略命名空間及之后的部分直接使用service-name。svc.cluster.local這是Kubernetes集群的默認(rèn)集群域Cluster Domain。在大多數(shù)部署中它默認(rèn)為cluster.local但也可以在kubelet或kube-apiserver的啟動(dòng)參數(shù)中通過(guò)--cluster-domain進(jìn)行自定義。示例 假設(shè)在production命名空間下有一個(gè)名為redis-master的Service。在production命名空間內(nèi)的Pod可以直接使用redis-master來(lái)訪問(wèn)它。在其他命名空間如default的Pod則需要使用完整的FQDNredis-master.production.svc.cluster.local。3.2 Pod的DNS策略與解析配置每個(gè)Pod都可以通過(guò)dnsPolicy字段來(lái)指定其DNS配置策略這直接影響Pod內(nèi)/etc/resolv.conf文件的生成。主要有以下幾種策略ClusterFirst默認(rèn)這是最常用的策略。Pod的/etc/resolv.conf中的nameserver會(huì)被設(shè)置為集群DNS服務(wù)CoreDNS的ClusterIP。任何不匹配cluster.local后綴的DNS查詢都會(huì)被CoreDNS轉(zhuǎn)發(fā)到上游DNS服務(wù)器。apiVersion: v1 kind: Pod metadata: name: busybox spec: dnsPolicy: ClusterFirst # 默認(rèn)值通常無(wú)需顯式指定 containers: - name: busybox image: busybox:1.28 command: [sh, -c, sleep 3600]ClusterFirstWithHostNet對(duì)于使用主機(jī)網(wǎng)絡(luò)hostNetwork: true的Pod如果希望它仍然使用集群DNS則需要指定此策略。因?yàn)槭褂弥鳈C(jī)網(wǎng)絡(luò)的Pod默認(rèn)會(huì)繼承宿主機(jī)的/etc/resolv.conf。DefaultPod直接從其運(yùn)行的節(jié)點(diǎn)上繼承DNS配置。即Pod內(nèi)的/etc/resolv.conf文件與節(jié)點(diǎn)上的文件一致。這通常意味著Pod會(huì)使用宿主機(jī)配置的公共DNS或企業(yè)內(nèi)網(wǎng)DNS而無(wú)法解析集群內(nèi)的Service域名。None此策略允許你通過(guò)dnsConfig字段完全自定義Pod的DNS配置。它提供了最高的靈活性。apiVersion: v1 kind: Pod metadata: name: custom-dns-pod spec: dnsPolicy: None dnsConfig: nameservers: - 8.8.8.8 - 1.1.1.1 searches: - ns1.svc.cluster.local - my.dns.search.suffix options: - name: ndots value: 2 - name: edns0nameservers自定義DNS服務(wù)器列表。searchesDNS搜索域列表。當(dāng)查詢的主機(jī)名不是FQDN時(shí)系統(tǒng)會(huì)依次嘗試附加這些搜索域。Kubernetes默認(rèn)會(huì)為Pod添加namespace.svc.cluster.local、svc.cluster.local和cluster.local等搜索域。optionsDNS解析器選項(xiàng)。其中ndots尤為重要它指定了一個(gè)域名中必須包含的點(diǎn)號(hào).數(shù)量少于這個(gè)數(shù)量的查詢會(huì)先嘗試附加搜索域。默認(rèn)值為ndots:5在Kubernetes環(huán)境下過(guò)高的ndots值可能導(dǎo)致不必要的搜索域查詢影響解析效率。有時(shí)為了優(yōu)化會(huì)將其設(shè)置為2或3。3.3 Headless Service與StatefulSet的特殊解析對(duì)于無(wú)頭服務(wù)Headless Service即spec.clusterIP: None和StatefulSetDNS解析行為有所不同這對(duì)于有狀態(tài)應(yīng)用至關(guān)重要。Headless Service當(dāng)查詢一個(gè)Headless Service的域名時(shí)CoreDNS返回的不是一個(gè)單一的ClusterIP而是該Service后端所有Pod的IP地址列表。這允許客戶端直接與Pod通信常用于實(shí)現(xiàn)自定義的負(fù)載均衡或主從選舉等場(chǎng)景。StatefulSetStatefulSet管理的Pod擁有穩(wěn)定的、可預(yù)測(cè)的網(wǎng)絡(luò)標(biāo)識(shí)。其Pod主機(jī)名的格式為statefulset-name-ordinal。同時(shí)每個(gè)Pod會(huì)獲得一個(gè)唯一的DNS記錄pod-name.service-name.namespace.svc.cluster.local。這使得在StatefulSet的Pod之間可以通過(guò)固定的DNS名稱相互發(fā)現(xiàn)例如在Redis Sentinel或MongoDB副本集中非常有用。4. CoreDNS的部署、配置與優(yōu)化實(shí)操4.1 部署與基礎(chǔ)檢查在通過(guò)kubeadm等工具部署的Kubernetes集群中CoreDNS通常是默認(rèn)安裝的。你可以通過(guò)以下命令檢查其狀態(tài)# 檢查CoreDNS的Deployment和Pod狀態(tài) kubectl get deployment coredns -n kube-system kubectl get pods -l k8s-appkube-dns -n kube-system -o wide # 檢查CoreDNS的Service kubectl get svc kube-dns -n kube-system # 查看CoreDNS的配置ConfigMap kubectl get configmap coredns -n kube-system -o yaml # 查看CoreDNS Pod的日志排查啟動(dòng)或運(yùn)行時(shí)錯(cuò)誤 kubectl logs -f deployment/coredns -n kube-system如果CoreDNS沒(méi)有運(yùn)行或者你想自定義部署可以參考官方提供的部署清單。但更常見(jiàn)的操作是修改其ConfigMap來(lái)調(diào)整行為。4.2 自定義CoreDNS配置常見(jiàn)場(chǎng)景場(chǎng)景一添加自定義域名解析如解析內(nèi)網(wǎng)服務(wù)假設(shè)公司內(nèi)網(wǎng)有一個(gè)數(shù)據(jù)庫(kù)域名為internal-db.corp.comIP為10.10.10.100。我們希望集群內(nèi)所有Pod都能通過(guò)這個(gè)域名訪問(wèn)它。我們可以修改CoreDNS的ConfigMap添加hosts插件。編輯ConfigMapkubectl edit configmap coredns -n kube-system在Corefile的服務(wù)器塊中添加hosts插件。注意插件順序通常hosts插件應(yīng)放在kubernetes插件之前以確保優(yōu)先使用靜態(tài)映射。Corefile: | .:53 { errors health ready # 添加hosts插件定義靜態(tài)映射 hosts { 10.10.10.100 internal-db.corp.com # 可以添加更多映射 fallthrough } kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa } prometheus :9153 forward . /etc/resolv.conf cache 30 loop reload loadbalance }fallthrough指令表示如果hosts插件中沒(méi)有找到匹配項(xiàng)則繼續(xù)執(zhí)行插件鏈中的下一個(gè)插件即kubernetes或forward。場(chǎng)景二配置上游DNS服務(wù)器默認(rèn)情況下CoreDNS使用Pod內(nèi)的/etc/resolv.conf通常是宿主機(jī)的DNS配置作為上游轉(zhuǎn)發(fā)器。如果你想指定特定的上游DNS比如使用8.8.8.8和114.114.114.114可以修改forward插件forward . 8.8.8.8 114.114.114.114 { max_concurrent 1000 prefer_udp }這里max_concurrent限制了最大并發(fā)查詢數(shù)prefer_udp表示優(yōu)先使用UDP協(xié)議。場(chǎng)景三啟用日志記錄以調(diào)試DNS查詢?cè)谂挪镈NS問(wèn)題時(shí)啟用查詢?nèi)罩痉浅S杏谩?梢蕴砑觢og插件log這會(huì)將所有經(jīng)過(guò)CoreDNS的查詢?nèi)罩敬蛴〉綐?biāo)準(zhǔn)輸出。在生產(chǎn)環(huán)境中為了避免日志量過(guò)大可以結(jié)合filter插件或僅在有問(wèn)題的Pod上臨時(shí)啟用。4.3 性能優(yōu)化與監(jiān)控調(diào)整緩存時(shí)間cache插件的TTL值默認(rèn)30秒可以根據(jù)集群服務(wù)變更頻率調(diào)整。對(duì)于極其穩(wěn)定的服務(wù)可以適當(dāng)增加緩存時(shí)間如300秒以減少API Server壓力。對(duì)于頻繁變更的服務(wù)保持較低TTL。監(jiān)控CoreDNS利用其內(nèi)置的prometheus插件暴露的指標(biāo)進(jìn)行監(jiān)控是關(guān)鍵。你需要部署Prometheus并配置抓取kube-system命名空間下CoreDNS Pod的9153端口。需要關(guān)注的指標(biāo)包括coredns_dns_request_count_total總請(qǐng)求數(shù)按類型A AAAA SRV等和區(qū)域zone區(qū)分。coredns_dns_request_duration_seconds請(qǐng)求延遲分布。coredns_dns_response_rcode_count_total響應(yīng)碼計(jì)數(shù)NOERROR NXDOMAIN SERVFAIL等SERVFAIL增多通常意味著上游或API Server問(wèn)題。coredns_panic_count_totalCoreDNS進(jìn)程崩潰次數(shù)。資源請(qǐng)求與限制確保為CoreDNS的Deployment設(shè)置合適的資源請(qǐng)求和限制防止其因資源不足被驅(qū)逐或OOMKilled。通常建議內(nèi)存從128Mi起步根據(jù)負(fù)載調(diào)整。resources: limits: memory: 256Mi cpu: 200m requests: memory: 128Mi cpu: 100m副本數(shù)與反親和性對(duì)于生產(chǎn)集群至少運(yùn)行2個(gè)CoreDNS Pod副本以確保高可用。并配置Pod反親和性讓它們調(diào)度到不同的節(jié)點(diǎn)上避免節(jié)點(diǎn)故障導(dǎo)致DNS服務(wù)完全中斷。spec: replicas: 2 strategy: type: RollingUpdate affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: k8s-app operator: In values: - kube-dns topologyKey: kubernetes.io/hostname5. 常見(jiàn)DNS問(wèn)題排查與修復(fù)實(shí)錄在實(shí)際運(yùn)維中DNS問(wèn)題是導(dǎo)致Pod網(wǎng)絡(luò)連通性故障的常見(jiàn)原因。下面是一個(gè)系統(tǒng)性的排查流程和常見(jiàn)問(wèn)題案例。5.1 系統(tǒng)性排查流程當(dāng)遇到服務(wù)間無(wú)法通過(guò)域名通信時(shí)可以按照以下步驟排查檢查Pod本身網(wǎng)絡(luò)與DNS配置# 進(jìn)入出問(wèn)題的Pod或啟動(dòng)一個(gè)臨時(shí)調(diào)試Pod如busybox kubectl exec -it problem-pod-name -- sh # 檢查DNS配置 cat /etc/resolv.conf # 正常應(yīng)看到 nameserver 指向集群DNS IP (如 10.96.0.10) # 測(cè)試基礎(chǔ)網(wǎng)絡(luò)連通性 ping 10.96.0.10 # 測(cè)試是否能ping通CoreDNS Service IP nc -zv 10.96.0.10 53 # 測(cè)試53端口是否可達(dá) # 使用nslookup或dig進(jìn)行DNS查詢測(cè)試 nslookup kubernetes.default.svc.cluster.local # 或安裝dig后使用 dig 10.96.0.10 kubernetes.default.svc.cluster.local short檢查CoreDNS服務(wù)狀態(tài)# 確認(rèn)CoreDNS Pod是否Running且Ready kubectl get pods -n kube-system -l k8s-appkube-dns # 查看CoreDNS Pod日志是否有錯(cuò)誤 kubectl logs -n kube-system deployment/coredns --tail50 # 確認(rèn)kube-dns Service是否存在且Endpoints正常 kubectl get svc kube-dns -n kube-system kubectl get endpoints kube-dns -n kube-system檢查Kubernetes網(wǎng)絡(luò)插件CNIDNS依賴底層網(wǎng)絡(luò)。確保Calico、Flannel等CNI插件工作正常Pod IP分配和路由沒(méi)有問(wèn)題。檢查Node節(jié)點(diǎn)DNS配置CoreDNS的forward插件依賴節(jié)點(diǎn)DNS。檢查節(jié)點(diǎn)/etc/resolv.conf確保上游DNS服務(wù)器可達(dá)且沒(méi)有配置錯(cuò)誤。5.2 典型問(wèn)題案例與解決方案案例一Pod內(nèi)/etc/resolv.conf的ndots值過(guò)高導(dǎo)致解析延遲癥狀應(yīng)用調(diào)用內(nèi)部服務(wù)域名時(shí)偶爾出現(xiàn)超時(shí)但直接使用完整FQDN如service.namespace.svc.cluster.local則正常。 原因分析Pod內(nèi)/etc/resolv.conf默認(rèn)options ndots:5。當(dāng)應(yīng)用查詢一個(gè)包含少于5個(gè)點(diǎn)如redis-master的域名時(shí)解析器會(huì)依次嘗試附加所有搜索域如redis-master.default.svc.cluster.localredis-master.svc.cluster.localredis-master.cluster.local等直到成功或全部失敗。這會(huì)增加不必要的查詢次數(shù)和延遲。 解決方案在Pod或Deployment的dnsConfig中降低ndots值或鼓勵(lì)應(yīng)用使用完整的FQDN。spec: dnsPolicy: None dnsConfig: options: - name: ndots value: 2案例二CoreDNS Pod內(nèi)存不足OOMKilled癥狀CoreDNS Pod頻繁重啟kubectl describe pod顯示原因?yàn)镺OMKilled。 原因分析查詢量過(guò)大、緩存設(shè)置不當(dāng)或存在內(nèi)存泄漏的插件可能導(dǎo)致內(nèi)存使用量激增。 解決方案增加CoreDNS Pod的內(nèi)存限制limits.memory。檢查并優(yōu)化Corefile配置例如減少不必要的日志輸出log插件調(diào)整緩存大小。監(jiān)控內(nèi)存使用趨勢(shì)排查是否有異常的查詢流量如DNS放大攻擊。案例三無(wú)法解析集群外域名如公網(wǎng)域名癥狀Pod內(nèi)可以解析kubernetes.default.svc.cluster.local但無(wú)法解析www.baidu.com。 排查步驟進(jìn)入Pod嘗試dig 10.96.0.10 www.baidu.com。如果失敗說(shuō)明CoreDNS的上游轉(zhuǎn)發(fā)有問(wèn)題。檢查CoreDNS ConfigMap中的forward插件配置確認(rèn)其指向的上游DNS服務(wù)器如/etc/resolv.conf或指定的IP是否可達(dá)且正確。登錄到CoreDNS Pod所在節(jié)點(diǎn)檢查節(jié)點(diǎn)的網(wǎng)絡(luò)連通性和DNS配置。檢查網(wǎng)絡(luò)策略NetworkPolicy是否阻止了CoreDNS Pod或節(jié)點(diǎn)向上游DNS服務(wù)器53端口的出口流量。案例四Headless Service解析返回多個(gè)IP但連接失敗癥狀通過(guò)nslookup查詢Headless Service域名能返回所有Pod IP但應(yīng)用連接其中某些IP時(shí)失敗。 原因分析DNS只負(fù)責(zé)解析不檢查Pod的健康狀態(tài)。返回的IP中可能包含處于NotReady狀態(tài)的Pod。 解決方案應(yīng)用端需要實(shí)現(xiàn)連接重試和健康檢查機(jī)制。或者考慮使用readinessProbe并結(jié)合publishNotReadyAddresses: false的Service此配置控制不健康的Pod IP是否從Service的Endpoints中移除從而影響DNS解析結(jié)果。5.3 調(diào)試工具箱準(zhǔn)備一些常用的調(diào)試鏡像和命令能極大提升效率# 1. 啟動(dòng)一個(gè)包含dig, nslookup, curl等工具的臨時(shí)調(diào)試Pod kubectl run dns-debug --imagebusybox:1.28 --restartNever --rm -it -- sh # 2. 在Pod內(nèi)進(jìn)行DNS查詢 nslookup kubernetes.default.svc.cluster.local dig dns-service-ip service-name.namespace.svc.cluster.local A # 3. 從集群外部測(cè)試Service需要kubectl端口轉(zhuǎn)發(fā)或Ingress # 通常用于測(cè)試ClusterIP類型的Service是否工作正常 # 4. 檢查CoreDNS的Prometheus指標(biāo) # 假設(shè)已配置Prometheus可以在Grafana中查看或直接查詢 # 例如查詢最近5分鐘SERVFAIL錯(cuò)誤率 sum(rate(coredns_dns_response_rcode_count_total{rcodeSERVFAIL}[5m])) by (pod) / sum(rate(coredns_dns_response_rcode_count_total[5m])) by (pod)DNS問(wèn)題排查往往需要耐心從Pod內(nèi)部到CoreDNS自身再到上游和底層網(wǎng)絡(luò)逐層縮小范圍。掌握CoreDNS的原理和這些排查工具能讓你在遇到服務(wù)發(fā)現(xiàn)故障時(shí)快速定位并解決問(wèn)題保障集群的穩(wěn)定運(yùn)行。