全部產品
Search
文件中心

Container Service for Kubernetes:非託管CoreDNS穩定性與高效能部署建議

更新時間:Nov 06, 2025

CoreDNS是叢集中的預設DNS Server,叢集中Service和叢集外網域名稱的解析全部需要通過CoreDNS完成。CoreDNS的服務不可用會嚴重影響叢集內的其他服務。在不同情境中,CoreDNS效能和可用性的要求有所區別,預設配置無法適配所有情境。請根據實際業務情境,採用本文中的建議對CoreDNS組件進行配置。

影響評估

在非託管模式下,CoreDNS如同叢集中的其他工作負載,其可用性與效能取決於Pod數量、資源限制、調度策略、節點分布等因素。

在高負載或配置不當的情況下,都會直接影響叢集的DNS服務品質。CoreDNS可能面臨兩類主要問題:

  • 可用性問題:

    • 配置不正確的情況下,無法實現節點級和可用性區域級的高可用,形成單點故障風險。

    • 資源不足引發Pod被驅逐,服務中斷。

  • 效能問題:

    • 與同節點工作負載資源爭用,響應延遲增加。

    • 節點負載過高導致網路I/O丟包,從而導致DNS請求失敗。

調整CoreDNS Pod數量

重要
  • 由於UDP報文缺少重傳機制,當叢集節點存在IPVS UDP缺陷導致的丟包風險時,CoreDNS Pod的縮容或重啟可能會導致長達五分鐘的整個叢集網域名稱解析逾時或異常。關於IPVS缺陷導致解析異常的解決方案,請參見DNS解析異常問題排查

  • 請勿使用工作負載自動調整:雖然工作負載自動調整,例如容器水平伸縮(HPA)、容器定時水平伸縮(CronHPA)等也可以自動調整Pod數量,但是它們會頻繁執行擴縮容。由於Pod縮容時導致的解析異常,請勿使用工作負載自動調整控制CoreDNS Pod數量。

評估組件壓力

包括DNSPerf在內的許多開源工具可評估叢集內的整體DNS壓力。如果無法準確評估,推薦參照下方的標準:

  • 在任何情況下,建議設定CoreDNS Pod數應至少為2,單個Pod的資源limit不小於1核1G。

  • CoreDNS所能提供的網域名稱解析QPS與CPU消耗成正相關,使用NodeLocal DNSCache的情況下,每CPU核可以支撐10000+ QPS的網域名稱解析請求。不同類型的業務對網域名稱請求的QPS需求存在較大差異,可以觀察每個CoreDNS Pod的峰值CPU使用量,如果其在業務峰值期間佔用CPU大於一核,建議對CoreDNS進行副本擴容。無法確定峰值CPU使用量時,可以保守地採用Pod數和叢集節點數1:8的比值來部署,即每擴容8個叢集節點,增加一個CoreDNS Pod。

評估完成後,請參照配置自動調整(推薦)手動調整執行調整。

配置自動調整(推薦)

下方的cluster-proportional-autoscaler會參照上方的推薦策略(Pod數和叢集節點數1:8)即時自動調整CoreDNS的Pod數量。相較於容器水平伸縮(HPA),它不依賴CoreDNS CPU負載指標,適用於副本數量需求與叢集規模成正比的服務。

樣本中Pod數量的計算公式為replicas = max (ceil (cores × 1/coresPerReplica), ceil (nodes × 1/nodesPerReplica) ),且通過min、max限制了最小Pod數量為2,最大為100。

cluster-proportional-autoscaler

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dns-autoscaler
  namespace: kube-system
  labels:
    k8s-app: dns-autoscaler
spec:
  selector:
    matchLabels:
      k8s-app: dns-autoscaler
  template:
    metadata:
      labels:
        k8s-app: dns-autoscaler
    spec:
      serviceAccountName: admin
      containers:
      - name: autoscaler
        image: registry.cn-hangzhou.aliyuncs.com/acs/cluster-proportional-autoscaler:1.8.4
        resources:
          requests:
            cpu: "200m"
            memory: "150Mi"
        command:
        - /cluster-proportional-autoscaler
        - --namespace=kube-system
        - --configmap=dns-autoscaler
        - --nodelabels=type!=virtual-kubelet
        - --target=Deployment/coredns
        - --default-params={"linear":{"coresPerReplica":64,"nodesPerReplica":8,"min":2,"max":100,"preventSinglePointFailure":true}}
        - --logtostderr=true
        - --v=9

手動調整

也可通過下方的命令手動調整CoreDNS所屬的Pod數量。

kubectl scale --replicas=<target> deployment/coredns -n kube-system # target替換為目標Pod數量

調整CoreDNS Pod規格

ACK託管叢集Pro版中,CoreDNS Pod預設的記憶體限制為2Gi,CPU則未限制。推薦將CPU Limit設定為4096m, 最小應不低於1024m。可通過控制台對CoreDNS Pod配置進行調整。

重要

調整CoreDNS Pod規格的操作可能導致Pod暫時失效,可能會導致叢集中出現機率性DNS延遲逾時、解析失敗的情況,建議在業務低峰期進行操作。

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

  2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,單擊組件管理

  3. 單擊網路頁簽,找到CoreDNS卡片。單擊卡片上的配置

    image

  4. 修改CoreDNS配置,然後單擊確認

    image

採用獨佔節點池部署

將CoreDNS Pod組件使用獨佔節點池的方式部署,可使CoreDNS負載與叢集中其他應用完全隔離,不受資源搶佔的影響。

重要

調度CoreDNS Pod部署到獨佔節點池的操作可能導致Pod暫時失效,可能會導致叢集中出現機率性DNS延遲逾時、解析失敗的情況,建議在業務低峰期進行操作。

建立CoreDNS專屬節點池

為CoreDNS Pod建立專屬節點池。請注意下列事項:

  • CoreDNS對計算資源要求不高,但是需要較高網路效能。建議選擇網路增強型執行個體,規格可選4核8GB。

  • CoreDNS預設部署兩個Pod,節點池中至少需要兩個節點。

  • 節點池需要進行汙點和標籤配置以避免其他Pod調度。例如,可在汙點和標籤中都添加system-addon: system-addon索引值對,將汙點Effect設定為NoSchedule,並在下一步驟中使用。

建立節點池的具體操作,請參見建立和管理節點池

配置CoreDNS組件調度Pod

  1. 組件管理頁面找到CoreDNS卡片,單擊配置

  2. NodeSelector中添加專屬節點池標籤。

    請勿刪除已有的NodeSelector標籤

    image.png

  3. Tolerations中添加專屬節點池標籤

    image.png

  4. 單擊確認儲存組件配置。然後執行下方命令,確認CoreDNS Pod是否已調度到專屬節點池。

    kubectl -n kube-system get pod -o wide --show-labels | grep coredns

使用調度策略實現CoreDNS高可用

重要

CoreDNS的節點親和性策略、Pod反親和性策略、拓撲感知調度策略僅在部署時生效。如果節點和可用性區域配置發生了變化,請通過Container Service管理主控台找到coredns Deployment,在其右側選擇重新部署,以保證CoreDNS Pod分布符合高可用預期。

Pod反親和性

CoreDNS預設部署2個Pod,並通過Pod反親和性(Pod Anti-Affinity)策略,將Pod分布在不同的節點上,從而實現節點層級的容災。為實現Pod反親和性策略,在叢集中至少保留2個可用且資源充足(基於Pod資源request)的節點。同時節點不包含下欄標籤:

  • k8s.aliyun.com: true(開啟了節點伸縮功能的節點)

  • type: virtual-kubelet(虛擬節點)

  • alibabacloud.com/lingjun-worker: true(靈駿節點)

CoreDN預設親和性配置

      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              # virtual nodes have this label
              - key: type
                operator: NotIn
                values:
                - virtual-kubelet
              # lingjun worker nodes have this label
              - key: alibabacloud.com/lingjun-worker
                operator: NotIn
                values:
                - "true" 
          preferredDuringSchedulingIgnoredDuringExecution:
          - preference:
              matchExpressions:
              # autoscaled nodes have this label
              - key: k8s.aliyun.com
                operator: NotIn
                values:
                - "true"
            weight: 100
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: k8s-app
                operator: In
                values:
                - kube-dns
            topologyKey: kubernetes.io/hostname

拓撲感知調度

CoreDNS預設通過拓撲感知調度,儘可能將Pod均勻分布到不同的可用性區域,並在無法滿足均衡條件時拒絕調度 (DoNotSchedule),以實現可用性區域級容災。此機制有一定的限制,為確保機制有效,請執行下列操作:

  • 確保叢集中的節點至少處於兩個不同可用性區域中,且所有可用性區域都需要至少一台可供CoreDNS調度、資源充足的節點。

  • 確認節點擁有正確且一致的 topology.kubernetes.io/zone 標籤(預設擁有),否則會導致拓撲感知錯誤,或Pod集中式部署在一個可用性區域。

  • 升級叢集版本至v1.27或更高,升級CoreDNS版本至v1.12.1.3或更高。叢集版本低於v1.27時,拓撲感知調度不支援matchLabelKeys,CoreDNS發生變換時,可能會導致Pod最終分布並不均衡,甚至未能覆蓋所有可用性區域。

CoreDNS預設拓撲感知調度策略

  • 版本低於v1.12.1.3的CoreDNS中,拓撲感知調度策略如下:

    topologySpreadConstraints:
    - labelSelector:
        matchLabels:
          k8s-app: kube-dns
      maxSkew: 1
      topologyKey: topology.kubernetes.io/zone
      whenUnsatisfiable: DoNotSchedule
    不同可用性區域之間的Pod數差不超過maxSkew(預設為1)
    重要

    在CoreDNS變換期間,拓撲均衡約束(topologySpreadConstraints)的行為可能導致Pod分布不均。

    根本原因在於,labelSelector會同時統計新、舊兩個版本的Pod。為了滿足maxSkew=1,調度器會優先將新Pod調度到當前Pod總數(新舊之和)最少的可用性區域。當變換完成、舊Pod被銷毀後,新Pod集合可能已集中在部分可用性區域,從而導致Pod最終分布並不均衡,甚至未能覆蓋所有可用性區域。

  • 針對上述問題,Kubernetes在v1.27和更高版本中提供了matchLabelKeys特性,對拓撲約束配置進行最佳化。因此,在CoreDNS v1.12.1.3和更高版本中,拓撲感知調度策略調整如下:

    topologySpreadConstraints:
    - labelSelector:
        matchLabels:
          k8s-app: kube-dns
      matchLabelKeys:
      - pod-template-hash
      nodeTaintsPolicy: Honor
      maxSkew: 1
      topologyKey: topology.kubernetes.io/zone
      whenUnsatisfiable: DoNotSchedule