全部產品
Search
文件中心

Container Service for Kubernetes:DNS解析異常問題排查

更新時間:Sep 11, 2025

本文介紹關於DNS解析異常的診斷流程、排查思路、常見解決方案和排查方法。

診斷流程

注意事項

由於網路架構的多層性和動態性,Kubernetes環境中的DNS問題排查較為複雜。除CoreDNS與NodeLocal DNSCache組件的錯誤外,還有以下原因會導致DNS解析錯誤的現象。

重要

DNS最佳實務針對不同情境提供了DNS使用建議,這些建議可以協助您更合理地配置DNS,從而減少遭遇DNS相關問題的可能性。

  • 網路架構負載

    DNS的解析鏈路涉及多個模組,包含CoreDNS/kube-dns、kube-proxy、CNI外掛程式等,任意一層故障均可能導致問題,因此需要逐層排查多個環節才能確定問題源頭。完整的排查鏈路,請參見排查DNS鏈路中其他模組的問題

  • 服務發現機制與命名空間的隱蔽性

    • FQDN依賴:跨命名空間訪問需使用完整網域名稱(如 service.namespace.svc.cluster.local),在網域名稱中未指定命名空間時,DNS僅在當前命名空間中尋找服務,跨命名空間訪問失敗但無明確報錯。

    • Headless Services的特殊性:Headless Services直接返回Pod IP,若配置不當會導致DNS記錄不完整或缺失。

  • 網路原則的限制

    • 隱性阻斷:若Pod NetworkPolicy未允許存取DNS連接埠(預設 53/UDP、TCP),Pod將無法與CoreDNS通訊。

    • VPC安全性群組幹擾:主機防火牆或安全性群組規則可能丟棄DNS流量,尤其是VPC安全性群組配置。

    • 排查思路:檢查kube-system命名空間下CoreDNS Pod的網路連通性,驗證策略是否允許進出。

  • 調試工具與日誌的局限性

    • 工具缺失:容器鏡像預設不包含dig、nslookup,需手動安裝或使用臨時調試容器。

    • 日誌分散性:CoreDNS 日誌需手動開啟Debug模式(添加 log 外掛程式),且分散在多個副本執行個體中。

    • 調試技巧:通過臨時Pod執行快速DNS測試:

      kubectl run -it --rm debug --image=nicolaka/netshoot -- dig

      或使用:

      nslookup  <目標網域名稱>

基本概念

  • 叢集內部網域名稱:CoreDNS會將叢集中的服務暴露為叢集內部網域名稱,預設以.cluster.local結尾,這類網域名稱的解析通過CoreDNS內部緩衝完成,不會從上遊DNS伺服器查詢。

  • 叢集外部網域名稱:在第三方DNS服務商、阿里雲DNS雲解析、PrivateZone等產品註冊的權威解析,這類網域名稱由CoreDNS的上遊DNS伺服器負責解析,CoreDNS僅做解析請求轉寄。

  • 業務Pod:您部署在Kubernetes叢集中的容器Pod,不包含Kubernetes自身系統組件的容器。

  • 接入CoreDNS的業務Pod:容器內DNS伺服器指向了CoreDNS的業務Pod。

  • 接入NodeLocal DNSCache的業務Pod:叢集中安裝了NodeLocal DNSCache外掛程式後,通過自動或手動方式注入DNSConfig的業務Pod。這類Pod在解析網域名稱時,會優先訪問本機快取組件。如果訪問本機快取組件不通時,會訪問CoreDNS提供的kube-dns服務。

CoreDNS與NodeLocal DNSCache異常診斷流程

故障手冊流程.png

  1. 判斷當前的異常原因。具體資訊,請參見常見用戶端報錯

    • 如果異常原因是網域名稱不存在,請參見排查思路《按解析異常的網域名稱類型》

    • 如果異常原因是無法串連至網域名稱伺服器,請參見排查思路《按解析異常出現頻次》

  2. 如果以上排查無果,請按以下步驟排查。

常見用戶端報錯

用戶端

報錯日誌

可能異常

ping

ping: xxx.yyy.zzz: Name or service not known

網域名稱不存在或無法串連網域名稱伺服器。如果解析延遲大於5秒,一般是無法串連網域名稱伺服器。

curl

curl: (6) Could not resolve host: xxx.yyy.zzz

PHP HTTP用戶端

php_network_getaddresses: getaddrinfo failed: Name or service not known in xxx.php on line yyy

Golang HTTP用戶端

dial tcp: lookup xxx.yyy.zzz on 100.100.2.136:53: no such host

網域名稱不存在。

dig

;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: xxxxx

Golang HTTP用戶端

dial tcp: lookup xxx.yyy.zzz on 100.100.2.139:53: read udp 192.168.0.100:42922->100.100.2.139:53: i/o timeout

無法串連網域名稱伺服器。

dig

;; connection timed out; no servers could be reached

排查DNS鏈路中其他模組的問題

下方展示了DNS解析的整體鏈路,除CoreDNS及NodeLocal DNSCache以外,DNS鏈路中其他模組都有可能導致DNS解析錯誤:

  • DNS Resolver:在例如Go這樣的程式設計語言,以及glibc、musl這樣的庫中,它們對DNS解析的實現可能包含一定的缺陷,在小機率情況下導致DNS解析故障。

  • /etc/resolv.conf檔案:容器中的DNS設定檔,其中包含了DNS伺服器的IP和DNS搜尋域。對此檔案的錯誤配置會導致DNS解析失敗。

  • kube-proxy:kube-proxy使用IPVS/Iptables轉寄請求,如果在CoreDNS配置發生變更時,kube-proxy沒有及時更新,會導致無法訪問CoreDNS,出現偶發的DNS解析失敗。

  • Upstream DNS Servers:CoreDNS僅解析叢集內的網域名稱,對於不符合clusterDomain的網域名稱,CoreDNS將會詢問更上級DNS伺服器,例如VPC內網DNS。如果上級DNS伺服器中配置出錯,會導致Pod訪問非叢集網域名稱時出錯。

排查思路

排查思路

排查依據

問題及解決方案

按解析異常的網域名稱類型排查

叢集內外網域名稱都異常

僅叢集外部網域名稱異常

叢集外部網域名稱解析異常

僅PrivateZone 、vpc-proxy網域名稱解析異常

PrivateZone網域名稱解析異常

僅Headless類型服務網域名稱異常

按解析異常出現頻次排查

完全無法解析

異常僅出現在業務高峰時期

異常出現頻次非常高

異常出現頻次非常低

異常僅出現在節點擴縮容或CoreDNS縮容時

IPVS模式下CoreDNS Pod異常後可能出現DNS解析失敗的情況

常見檢查方法

檢查業務Pod的DNS配置

  • 命令

    #查看foo容器的YAML配置,並確認DNSPolicy欄位是否符合預期。
    kubectl get pod foo -o yaml
    
    #當DNSPolicy符合預期時,可以進一步進入Pod容器中,查看實際生效的DNS配置。
    
    #通過bash命令進入foo容器,若bash不存在可使用sh代替。
    kubectl exec -it foo bash
    
    #進入容器後,可以查看DNS配置,nameserver後面為DNS伺服器位址。
    cat /etc/resolv.conf
  • DNS Policy配置說明

    DNS Policy樣本如下所示。

    apiVersion: v1
    kind: Pod
    metadata:
      name: <pod-name>
      namespace: <pod-namespace>
    spec:
      containers:
      - image: <container-image>
        name: <container-name>
    
    #預設情境下的DNS Policy。
      dnsPolicy: ClusterFirst
    #使用了NodeLocal DNSCache時的DNS Policy。
      dnsPolicy: None
      dnsConfig:
        nameservers:
        - 169.254.20.10
        - 172.21.0.10
        options:
        - name: ndots
          value: "3"
        - name: timeout
          value: "1"
        - name: attempts
          value: "2"
        searches:
        - default.svc.cluster.local
        - svc.cluster.local
        - cluster.local
    
      securityContext: {}
      serviceAccount: default
      serviceAccountName: default
      terminationGracePeriodSeconds: 30

    DNSPolicy欄位值

    使用的DNS伺服器

    Default

    只適用於不需要訪問叢集內部服務的情境。Pod建立時會從ECS節點/etc/resolv.conf檔案繼承DNS伺服器列表。

    ClusterFirst

    此為DNSPolicy預設值,Pod會將CoreDNS提供的kube-dns服務IP作為DNS伺服器。開啟HostNetwork的Pod,如果選擇ClusterFirst模式,效果等同於Default模式。

    ClusterFirstWithHostNet

    開啟HostNetwork的Pod,如果選擇ClusterFirstWithHostNet模式,效果等同於ClusterFirst。

    None

    配合DNSConfig欄位,可用於自訂DNS伺服器和參數。在NodeLocal DNSCache開啟注入時,DNSConfig會將DNS伺服器指向本機快取IP及CoreDNS提供的kube-dns服務IP。

檢查CoreDNS Pod運行狀態

命令

  • 執行以下命令,查看容器組資訊。

    kubectl -n kube-system get pod -o wide -l k8s-app=kube-dns

    預期輸出:

    NAME                      READY   STATUS    RESTARTS   AGE   IP            NODE
    coredns-xxxxxxxxx-xxxxx   1/1     Running   0          25h   172.20.6.53   cn-hangzhou.192.168.0.198
  • 執行以下命令,查看Pod的即時資源使用方式。

    kubectl -n kube-system top pod -l k8s-app=kube-dns

    預期輸出:

    NAME                      CPU(cores)   MEMORY(bytes)
    coredns-xxxxxxxxx-xxxxx   3m           18Mi
  • 如果Pod不處於Running狀態,可以通過kubectl -n kube-system describe pod <CoreDNS Pod名稱>命令,查詢問題原因。

檢查CoreDNS作業記錄

命令

執行以下命令,檢查CoreDNS作業記錄。

kubectl -n kube-system logs -f --tail=500 --timestamps coredns-xxxxxxxxx-xxxxx

參數

描述

f

持續輸出。

tail=500

輸出最後500行日誌。

timestamps

同時顯示日誌列印的時間。

coredns-xxxxxxxxx-xxxxx

CoreDNS Pod副本的名稱。

檢查CoreDNS DNS查詢請求日誌

命令

DNS查詢請求日誌僅會在開啟CoreDNS的Log外掛程式後,才會列印到容器日誌中。關於開啟Log外掛程式的具體操作,請參見CoreDNS配置說明

命令與檢查CoreDNS作業記錄相同,請參見檢查CoreDNS作業記錄

檢查CoreDNS Pod的網路連通性

您可以使用控制台或命令列方式檢查CoreDNS Pod的網路連通性。

控制台

您可以通過叢集下提供的網路診斷能力進行診斷。

  1. 登入Container Service管理主控台,在左側導覽列選擇叢集列表

  2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇巡檢和診斷 > 故障診斷

  3. 故障診斷頁面,單擊網路診斷,然後單擊頁面左上方診斷按鈕。

  4. 網路診斷頁面單擊診斷,然後在訪問資訊面板,根據以下內容填寫診斷參數:

    • 源地址:輸入CoreDNS Pod的IP。

    • 目標地址:輸入上遊DNS伺服器位址,預設可選100.100.2.136或100.100.2.138。

    • 連接埠53

    • 協議udp

    填寫完成後仔細閱讀注意事項,選中我已知曉並同意,然後單擊發起診斷

  5. 診斷結果頁面,能夠查看網路診斷結果,並且在訪問全圖地區,會呈現出本次診斷訪問鏈路的全景。

    image

命令列

操作步驟

  1. 登入CoreDNS Pod所在叢集節點。

  2. 執行ps aux | grep coredns,查詢CoreDNS的進程ID。

  3. 執行nsenter -t <pid> -n -- <相關命令>,進入CoreDNS所在容器網路命名空間,其中pid為上一步得到的coredns進程ID。

  4. 測試網路連通性。

    1. 運行telnet <apiserver_clusterip> 6443,測試Kubernetes API Server的連通性。

      其中apiserver_clusterip為default命名空間下Kubernetes服務的IP地址。

    2. 運行dig <domain> @<upstream_dns_server_ip>,測試CoreDNS Pod到上遊DNS伺服器的連通性。

      其中domain為測試網域名稱,upstream_dns_server_ip為上遊DNS伺服器位址,預設為100.100.2.136和100.100.2.138。

常見問題

現象

原因

處理方案

CoreDNS無法連通Kubernetes API Server

APIServer異常、機器負載高、kube-proxy 沒有正常運行等。

提交工單排查。

CoreDNS無法連通上遊DNS伺服器

機器負載高、CoreDNS配置錯誤、專線路由問題等。

提交工單排查。

檢查業務Pod到CoreDNS的網路連通性

您可以使用控制台或命令列方式檢查業務Pod到CoreDNS的網路連通性。

控制台

  1. 登入Container Service管理主控台,在左側導覽列選擇叢集列表

  2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇巡檢和診斷 > 故障診斷

  3. 故障診斷頁面,單擊網路診斷,然後單擊頁面左上方診斷按鈕。

  4. 網路診斷頁面單擊診斷,然後在訪問資訊面板,根據以下內容填寫診斷參數:

    • 源地址:輸入業務Pod的IP。

    • 目標地址:輸入CoreDNS執行個體的PodIP或者ClusterIP。

    • 連接埠53

    • 協議udp

    填寫完成後仔細閱讀注意事項,選中我已知曉並同意,然後單擊發起診斷

  5. 診斷結果頁面,能夠查看網路診斷結果,並且在訪問全圖地區,會呈現出本次診斷訪問鏈路的全景。

    image

命令列

操作步驟

  1. 選擇以下任意一種方式,進入用戶端Pod容器網路。

    • 方法一:使用kubectl exec命令。

    • 方法二:

      1. 登入業務Pod所在叢集節點。

      2. 執行ps aux | grep <業務進程名>命令,查詢業務容器的進程ID。

      3. 執行nsenter -t <pid> -n bash命令,進入業務Pod所在容器網路命名空間。

        其中pid為上一步得到的進程ID。

    • 方法三:如果頻繁重啟,請按以下步驟操作。

      1. 登入業務Pod所在叢集節點。

      2. 執行docker ps -a | grep <業務容器名>命令,查詢k8s_POD_ 開頭的沙箱容器,記錄容器ID。

      3. 執行docker inspect <沙箱容器 ID> | grep netns命令,查詢/var/run/docker/netns/xxxx的容器網路命名空間路徑。

      4. 執行nsenter -n<netns 路徑> bash命令,進入容器網路命名空間。

        其中netns 路徑為上一步得到的路徑。

        說明

        -n<netns 路徑>之間不加空格。

  2. 測試網路連通性。

    1. 執行dig <domain> @<kube_dns_svc_ip>命令,測試業務Pod到CoreDNS服務kube-dns解析查詢的連通性。

      其中<domain>為測試網域名稱,<kube_dns_svc_ip>為kube-system命名空間中kube-dns的服務IP。

    2. 執行ping <coredns_pod_ip>命令,測試業務Pod到CoreDNS容器副本的連通性。

      其中<coredns_pod_ip>為kube-system命名空間中CoreDNS Pod的IP。

    3. 執行dig <domain> @<coredns_pod_ip>命令,測試業務Pod到CoreDNS容器副本解析查詢的連通性。

      其中<domain>為測試網域名稱,<coredns_pod_ip>為kube-system命名空間中CoreDNS Pod的IP。

常見問題

現象

原因

處理方案

業務Pod無法通過CoreDNS服務kube-dns解析

機器負載高、kube-proxy沒有正常運行、安全性群組沒有放開UDP協議53連接埠等。

檢查安全性群組是否放開UDP 53連接埠,若已放開請提交工單排查。

業務Pod無法連通CoreDNS容器副本

容器網路異常或安全性群組沒有放開ICMP。

檢查安全性群組是否放開ICMP,若已放開請提交工單排查。

業務Pod無法通過CoreDNS容器副本解析

機器負載高、安全性群組沒有放開UDP協議53連接埠等。

檢查安全性群組是否放開UDP 53連接埠,若已放開請提交工單排查。

抓包

當無法定位問題時,需要抓包進行輔助診斷。

  1. 登入出現異常的業務Pod、CoreDNS Pod所在節點。

  2. 在ECS(非容器內)執行以下命令,可以將最近所有的53連接埠資訊抓取到檔案中。

    tcpdump -i any port 53 -C 20 -W 200 -w /tmp/client_dns.pcap
  3. 結合業務日誌的報錯定位到精準的報錯時間的報文資訊。

    說明
    • 在正常情況下,抓包對業務無影響,僅會增加小部分的CPU負載和磁碟寫入。

    • 以上命令會對抓取到的包進行rotate,最多可以寫200個20MB的.pcap檔案。

叢集外部網域名稱解析異常

問題現象

業務Pod可以正常解析叢集內部網域名稱,但無法解析某些叢集外部網域名稱。

問題原因

上遊伺服器網域名稱解析返回異常。

解決方案

檢查CoreDNS DNS查詢請求日誌。

常見請求日誌

CoreDNS接收到請求並回複用戶端後會列印一行日誌,樣本如下:

# 其中包含狀態代碼RCODE NOERROR,代表解析結果正常返回。
[INFO] 172.20.2.25:44525 - 36259 "A IN redis-master.default.svc.cluster.local. udp 56 false 512" NOERROR qr,aa,rd 110 0.000116946s

常見返回碼RCODE

關於返回碼RCODE定義的具體資訊,請參見規範

返回碼RCODE

含義

原因

NXDOMAIN

網域名稱不存在

容器內請求網域名稱時,會被拼接上search尾碼,若拼接的結果網域名稱不存在,則會出現該請求碼。如果確認日誌中請求的網域名稱內容存在,則說明存在異常。

SERVFAIL

上遊伺服器異常

常見於無法串連上遊DNS伺服器等情況。

REFUSED

拒絕應答

常見於CoreDNS配置或叢集節點/etc/resolv.conf檔案指向的上遊DNS伺服器無法處理該網域名稱的情況,請排查CoreDNS設定檔。

當CoreDNS DNS查詢請求日誌中顯示叢集外部網域名稱返回為NXDOMAINSERVFAILREFUSED時,說明CoreDNS的上遊DNS伺服器返回異常。

預設情況下,叢集中CoreDNS的上遊DNS伺服器是VPC提供的DNS伺服器(100.100.2.136 和 100.100.2.138)。您可以提交工單至Elastic Compute Service產品。提交工單時請註明以下資訊。

欄位

含義

樣本

受損網域名稱

CoreDNS日誌中返回碼RCODE異常的叢集外部網域名稱

www.aliyun.com

解析返回碼RCODE

具體解析報錯(NXDOMAIN、SERVFAIL、REFUSED)

NXDOMAIN

受損時間

日誌出現的時間(精確到秒)

2022-12-22 20:00:03

受損ECS

CoreDNS各副本Pod所處的ECS執行個體ID

i-xxxxx i-yyyyy

新增Headless類型網域名稱無法解析

問題現象

接入CoreDNS的業務Pod無法解析新增的Headless類型網域名稱。

問題原因

1.7.0以前版本CoreDNS會在API Server抖動時異常退出,導致Headless網域名稱停止更新。

解決方案

升級CoreDNS至1.7.0以上。具體操作,請參見【組件升級】CoreDNS升級公告

Headless類型網域名稱解析失敗

問題現象

接入CoreDNS的業務Pod無法解析Headless類型的網域名稱。使用dig解析時,返回中顯示tc標誌,表示響應訊息過大。

問題原因

當Headless類型的網域名稱對應的IP條目數量過多時,用戶端通過UDP方式發送DNS請求可能會超出UDP DNS報文的大小限制,導致解析失敗。

解決方案

為了避免解析失敗,您可以將用戶端業務調整為使用TCP方式進行DNS查詢。CoreDNS同時支援TCP和 UDP查詢,以下是根據不同業務情境的修改方式:

  • 使用glibc相關的解析器。

    如果您的用戶端業務使用的是glibc相關的Resolve解析器,可以在dnsConfig 中增加use-vc配置使用TCP進行DNS查詢。這些設定將在/etc/resolv.conf中的映射到相應的options配置。關於options配置詳細說明請參見Linux man pages

    dnsConfig:
      options:
      - name: use-vc
  • Golang實現的業務代碼邏輯

    如果您使用Golang進行開發,可以參考以下代碼,使用TCP進行DNS查詢。

    package main
    
    import (
    	"fmt"
    	"net"
    	"context"
    )
    
    func main() {
    	resolver := &net.Resolver{
    		PreferGo: true,
    		Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
    			return net.Dial("tcp", address)
    		},
    	}
    
    	addrs, err := resolver.LookupHost(context.TODO(), "example.com")
    	if err != nil {
    		fmt.Println("Error:", err)
    		return
    	}
    	fmt.Println("Addresses:", addrs)
    }

升級CoreDNS後Headless類型網域名稱無法解析

問題現象

部分較低版本開源組件(低版本etcd、nacos、kafka等)在K8s 1.20及以上版本和 CoreDNS 1.8.4及以上版本的環境中無法正常工作。

問題原因

1.8.4及以上版本的CoreDNS優先使用EndpointSlice API同步K8s內服務IP資訊。一些開源組件在初始化階段會使用Endpoint API 提供的註解service.alpha.kubernetes.io/tolerate-unready-endpoints來發布尚未就緒的服務。該註解在EndpointSlice API中已經廢棄,並被publishNotReadyAddresses所替代。因此CoreDNS升級後,無法發布未就緒的服務,導致這些組件無法進行服務發現。

解決方案

檢查開源組件的YAML或Helm Chart中是否包含service.alpha.kubernetes.io/tolerate-unready-endpoints註解,如果包含則可能無法正常工作,您需要升級開源組件或諮詢開源組件社區。

StatefulSets Pod網域名稱無法解析

問題現象

Headless服務無法通過Pod網域名稱解析。

問題原因

StatefulSets Pod YAML中ServiceName必須和其暴露的SVC名字一致,否則無法訪問Pod網域名稱(例如pod.headless-svc.ns.svc.cluster.local),只能訪問到服務網域名稱(例如headless-svc.ns.svc.cluster.local)。

解決方案

修改StatefulSets Pod YAML中ServiceName名稱。

安全性群組、交換器ACL配置錯誤

問題現象

部分節點或全部節點上接入CoreDNS的業務,Pod解析網域名稱持久性失敗。

問題原因

修改了ECS或容器使用的安全性群組(或交換器ACL),攔截了UDP協議下53連接埠的通訊。

解決方案

恢複安全性群組、交換器ACL的配置,放開其以UDP協議對53連接埠的通訊。

容器網路連通性異常

問題現象

部分節點或全部節點上接入CoreDNS的業務,Pod解析網域名稱持久性失敗。

問題原因

由於容器網路或其它原因導致的UDP協議53連接埠持續不通。

解決方案

您可以使用網路診斷對業務Pod和CoreDNS地址直接的網路連通性進行診斷

CoreDNS Pod負載高

問題現象

  • 部分節點或全部節點接入CoreDNS的業務,Pod解析網域名稱的延遲增加,出現機率性或持久性失敗。

  • 檢查CoreDNS Pod運行狀態發現各副本CPU、Memory使用量接近其資源限制。

問題原因

由於CoreDNS副本數不足、業務請求量高等情況導致的CoreDNS負載高。

解決方案

  • 考慮採用NodeLocal DNSCache緩衝方案,提升DNS解析效能,降低CoreDNS負載。具體操作,請參見使用NodeLocal DNSCache組件

  • 適當擴充CoreDNS副本數,使每個Pod的峰值CPU始終低於節點空閑CPU數量。

CoreDNS Pod負載不均

問題現象

  • 部分接入CoreDNS的業務Pod解析網域名稱的延遲增加,出現機率性或持久性失敗。

  • 檢查CoreDNS Pod運行狀態發現各副本CPU使用量負載不均衡。

  • CoreDNS副本數少於兩個,或多個CoreDNS副本位於同節點上。

問題原因

由於CoreDNS副本調度不均、Service親和性設定導致CoreDNS Pod負載不均衡。

解決方案

  • 擴容並打散CoreDNS副本到不同的節點上。

  • 負載不均衡時,可禁用kube-dns服務的親和性屬性。具體操作,請參見CoreDNS自動升級

CoreDNS Pod運行狀態異常

問題現象

  • 部分接入CoreDNS的業務Pod解析網域名稱的延遲增加,出現機率性或持久性失敗。

  • CoreDNS副本狀態Status不處於Running狀態,或重啟次數RESTARTS持續增加。

  • CoreDNS作業記錄中出現異常。

問題原因

由於CoreDNS YAML模板、設定檔等導致CoreDNS運行異常。

解決方案

檢查CoreDNS Pod運行狀態和作業記錄。

常見異常日誌及處理方案

日誌中字樣

原因

處理方案

/etc/coredns/Corefile:4 - Error during parsing: Unknown directive 'ready'

設定檔和CoreDNS不相容,Unknown directive代表當前啟動並執行CoreDNS版本不支援ready外掛程式。

從kube-system命名空間中CoreDNS配置項中刪除ready外掛程式,其它報錯同理。

pkg/mod/k8s.io/client-go@v0.18.3/tools/cache/reflector.go:125: Failed to watch *v1.Pod: Get "https://192.168.0.1:443/api/v1/": dial tcp 192.168.0.1:443: connect: connection refused

日誌出現時間段內,API Server中斷。

如果是日誌出現時間和異常不吻合,可以排除該原因,否則請檢查CoreDNS Pod網路連通性。具體操作,請參見檢查CoreDNS Pod的網路連通性

[ERROR] plugin/errors: 2 www.aliyun.com. A: read udp 172.20.6.53:58814->100.100.2.136:53: i/o timeout

日誌出現時間段內,CoreDNS無法串連到上遊DNS伺服器。

用戶端負載原因導致解析失敗

問題現象

業務高峰期間或突然偶發的解析失敗,ECS監控顯示機器網卡重傳率、CPU負載異常。

問題原因

接入CoreDNS的業務Pod所在ECS負載達到100%等情況導致UDP報文丟失。

解決方案

建議採用NodeLocal DNSCache緩衝方案,提升DNS解析效能,降低CoreDNS負載。具體操作,請參見使用NodeLocal DNSCache組件

Conntrack表滿

問題現象

  • 部分節點或全部節點上接入CoreDNS的業務,Pod解析網域名稱在業務高峰時間段內出現大批量網域名稱解析失敗,高峰結束後失敗消失。

  • 運行dmesg -H,滾動到問題對應時段的日誌,發現出現conntrack full字樣的報錯資訊。

問題原因

Linux內Conntrack表條目有限,無法進行新的UDP或TCP請求。

解決方案

增加Conntrack表限制。具體操作,請參見如何提升Linux串連跟蹤Conntrack數量限制?

AutoPath外掛程式異常

問題現象

  • 解析叢集外部網域名稱時,機率性出現解析失敗或解析到錯誤的IP地址,解析叢集內部網域名稱無異常。

  • 高頻建立容器時,叢集內部服務網域名稱解析到錯誤的IP地址。

問題原因

CoreDNS處理缺陷導致AutoPath無法正常工作。

解決方案

按照以下步驟,關閉AutoPath外掛程式。

  1. 執行kubectl -n kube-system edit configmap coredns命令,開啟CoreDNS設定檔。

  2. 刪除autopath @kubernetes一行後儲存退出。

  3. 檢查CoreDNS Pod運行狀態和作業記錄,作業記錄中出現reload字樣後說明修改成功。

A記錄和AAAA記錄並發解析異常

問題現象

  • 接入CoreDNS的業務Pod解析網域名稱機率性失敗。

  • 從抓包或檢查CoreDNS DNS查詢請求日誌可以發現,A和AAAA通常在同一時間的出現,並且請求的源連接埠一致。

問題原因

  • 並發A和AAAA的DNS請求觸發Linux核心Conntrack模組缺陷,導致UDP報文丟失。

  • 低版本的libc(<2.33)在ARM機型上同時發起A和AAAA請求時存在並發問題,導致請求逾時重傳,請參見GLIBC#26600

解決方案

  • 考慮採用NodeLocal DNSCache緩衝方案,提升DNS解析效能,降低CoreDNS負載。具體操作,請參見使用NodeLocal DNSCache組件

  • CentOS、Ubuntu等使用libc的基礎鏡像,升級libc版本到2.33或以上版本避免A和AAAA並發解析問題。

  • CentOS、Ubuntu等基礎鏡像,可以通過options timeout:2 attempts:3 rotate single-request-reopen等參數最佳化。

  • 如果容器鏡像是以Alpine製作的,建議更換基礎鏡像。更多資訊,請參見Alpine

  • PHP類應用短串連解析問題較多,如果使用的是PHP Curl的調用,可以使用CURL_IPRESOLVE_V4參數僅發送IPv4解析。更多資訊,請參見函數說明

IPVS模式下CoreDNS Pod異常後可能出現DNS解析失敗的情況

問題現象

IPVS模式下CoreDNS Pod在某些特定情況,可能出現機率性DNS解析失敗,通常時間長度在五分鐘左右。

問題原因

在某些特定情況,DNS解析請求會被發送到出於非正常狀態的CoreDNS Pod上,導致解析失敗。

例如,CoreDNS Pod所在的節點被移除後,節點資源會被立即釋放,Pod隨即無法正常工作。但叢集需要約1分鐘檢測到節點的狀態更新並將其標記為NotReady狀態。在節點狀態更新前,此Pod仍舊會被認為是正常狀態而接受DNS解析請求,導致叢集中出現機率性DNS解析失敗。

節點被標記為NotReady後,此節點上的CoreDNS Pod會被立即從CoreDNS Service的後端移除,不再接收新的串連。而如果叢集的kube-proxy負載平衡模式為IPVS,IPVS UDP的會話保持策略會導致仍有部分DNS請求發送到Pod上,直到到達UDP逾時時間,因此會導致叢集中更長時間的DNS解析失敗情況。

說明

此問題可能會發生在核心版本小於4.19.91-25.1.al7.x86_64的CentOS、Alibaba Cloud Linux 2節點上。

解決方案

NodeLocal DNSCache未生效

問題現象

NodeLocal DNSCache沒有流量進入,所有請求仍在CoreDNS上。

問題原因

  • 未配置DNSConfig注入,業務Pod實際仍配置了CoreDNS kube-dns服務IP作為DNS伺服器位址。

  • 業務Pod採用Alpine作為基礎鏡像,Alpine基礎鏡像會並發請求所有nameserver,包括本機快取和CoreDNS。

解決方案

  • 配置DNSConfig自動注入。具體操作,請參見使用NodeLocal DNSCache組件

  • 如果容器鏡像是以Alpine製作的,建議更換基礎鏡像。更多資訊,請參見Alpine

PrivateZone網域名稱解析異常

問題現象

對於接入NodeLocal DNSCache的業務,Pod無法解析PrivateZone上註冊的網域名稱,或無法解析包含vpc-proxy字樣的阿里雲雲產品API網域名稱,或解析結果不正確。

問題原因

PrivateZone不支援TCP協議,需要使用UDP協議訪問。

解決方案

在CoreDNS中配置prefer_udp。具體操作,請參見CoreDNS配置說明

突發大流量導致的DNS解析問題

問題現象

流量出現突發增長後,部分DNS請求解析失敗。

問題原因

突發大流量導致DNS請求數量激增,進出CoreDNS的流量過高,可能會導致CoreDNS的CPU使用被限流,從而導致解析異常。您可以通過下列方式核實是否是這種情況:

  1. 在CoreDNS Pod所處的節點上執行檢查。

    在節點上執行以下命令。

    nsenter -t <coredns-pid> -n -- netstat -su

    查看是否有相關send或者recv buffer error資訊,如果有說明存在UDP丟包,例如:

    Udp:
        1090421 packets received
        850 packets to unknown port received
        15662 packet receive errors
        5607627 packets sent
        15662 receive buffer errors
        0 send buffer errors
  2. 查看CoreDNS Pod的CPU Throttled監控。

    若CoreDNS CPU被限流,有可能會出現DNS偶發解析失敗或者DNS響應延遲變高的問題,可以結合第一點是否有丟包一起來確認問題。

    說明

    因為CPU使用率的採樣和計算周期問題(15s),可能存在CPU使用率不高,但CPU被限流的情況。更多資訊,請參見啟用CPU Burst效能最佳化策略

    image

  3. 無論您採用Arms Promtheus還是採用自建Prometheus方案,建議總是採集CoreDNS指標,並結合CoreDNS大盤來查看相關監控是否異常,並找到問題時間點。您可登入Container Service管理主控台後,通過營運管理 > Prometheus 監控中的網路監控頁簽找到CoreDNS組件監控

    image.png

解決方案