すべてのプロダクト
Search
ドキュメントセンター

Container Service for Kubernetes:安定かつ高性能なアンマネージド CoreDNS のデプロイ

最終更新日:Sep 02, 2026

アンマネージドモードでの CoreDNS の停止を防ぐために、Pod 数、リソース、スケジューリング、およびノードの隔離を設定します。

アンマネージドモードでは、CoreDNS の可用性とパフォーマンスは、Pod 数、リソース制限、スケジューリング、およびノード分散に依存します。デフォルト設定は小規模なクラスターに適していますが、本番ワークロードではチューニングが必要です。

潜在的リスク

CoreDNS の設定ミスやリソース不足は、以下の 2 種類の問題を引き起こします:

  • 可用性:スケジューリングが不適切な場合、ノードレベルまたはゾーンレベルで単一障害点が発生します。リソースが不足すると、Pod のエビクションや DNS の停止が発生します。

  • パフォーマンス:共有ノードでのリソースの競合は、レスポンスレイテンシーを増加させます。ノードの負荷が高いと、I/O パケット損失や DNS リクエストの失敗が発生します。

CoreDNS Pod 数の調整

重要

UDP には再送メカニズムがないため、CoreDNS のスケールインや再起動を行うと (特に IPVS の不具合によってパケット損失が発生する場合)、クラスター全体で最大 5 分間の DNS 名前解決のタイムアウトや失敗が発生する可能性があります。詳細については、「DNS 名前解決の問題のトラブルシューティング」をご参照ください。

重要

CoreDNS には Horizontal Pod Autoscaling (HPA) や CronHPA を使用しないでください。頻繁なスケールインは、名前解決の失敗を引き起こします。

DNS 負荷の評価

レプリカ数を調整する前に、DNS 負荷を評価します。DNSPerf などのツールを使用して、DNS 負荷を測定できます。

DNS 負荷を直接測定できない場合は、以下のガイドラインに従ってください:

  • 少なくとも 2 つの CoreDNS Pod を実行し、リソース制限を 1 コア、1 GB メモリ以上に設定してください。

  • DNS 名前解決の 1 秒あたりのクエリ数 (QPS) は、CPU 使用量に比例して増加します。NodeLocal DNSCache を使用すると、各 CPU コアは 1 秒あたり 10,000 を超えるクエリ数 (QPS) を処理できます。ワークロードによって QPS の要件は大きく異なるため、各 CoreDNS Pod のピーク時の CPU 使用量を監視してください。いずれかの Pod がピーク時に 1 コアを超えた場合は、レプリカをスケールアウトしてください。

  • 負荷データがない場合は、ベースラインとしてノード 8 台あたり 1 Pod から開始してください。

説明

スケールアウトが有効なのは、ノードに十分なリソースがある場合のみです。ノードのメモリが不足している場合は、代わりにノードを追加するか、ノードごとのリソースを増やしてください。

目標のレプリカ数が決まったら、自動調整 (推奨) を使用するか、手動でスケーリングしてください。

自動調整の設定 (推奨)

cluster-proportional-autoscaler は、クラスターのサイズに基づいて CoreDNS のレプリカを調整します。HPA とは異なり、CPU メトリクスに依存したり、中断を伴うスケールインを実行したりすることはありません。デフォルトの比率:ノード 8 台あたり 1 Pod。

レプリカ数の計算式: replicas = max(ceil(cores × 1/coresPerReplica), ceil(nodes × 1/nodesPerReplica))min および max パラメーターは、カウントを 2~100 に制限します。

オートスケーラーをデプロイします:

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

手動でのスケーリング

特定のレプリカ数を設定するには:

kubectl scale --replicas=<target> deployment/coredns -n kube-system # <target> を Pod の目標数に置き換えます。

CoreDNS Pod 仕様の調整

ACK Pro マネージドクラスターでは、デフォルトの CoreDNS Pod 設定は次のとおりです:

リソース デフォルトの制限
CPU 制限なし
メモリ 2 GiB

観測されたピーク使用量に基づいて、CPU 制限を 4096 m (最小 1024 m) に設定してください。

重要

CoreDNS Pod の仕様を変更すると Pod が再起動し、DNS レイテンシーの一時的な急増や失敗が発生する可能性があります。この操作はオフピーク時に実行してください。

  1. ACK コンソールにログインします。左側メニューで、[クラスター] をクリックします。

  2. [クラスター] ページで、対象のクラスター名をクリックします。左側メニューで、[アドオン] をクリックします。

  3. [ネットワーク] タブで [CoreDNS] を見つけて、[設定] をクリックします。

  4. CoreDNS の設定を変更して、[OK] をクリックします。

    [CoreDNS パラメーター設定] ダイアログボックスで、次のパラメーターを設定します:

    • [MemoryRequest]:メモリリクエスト。例:100 Mi

    • [CpuRequest]:CPU リクエスト。例:100 m

    • [MemoryLimit]:メモリ制限。例:2 Gi。メモリ制限が低すぎると、Pod が OOMKilled される可能性があります。

    • [CpuLimit]:CPU 制限。CpuRequest の値の 2 倍に設定することを推奨します。

    • [NodeSelector]:ノードセレクターのラベル。例:キーを kubernetes.io/os に、値を linux に設定します。

専用ノードプールへのデプロイ

専用ノードプールは、CoreDNS を他のワークロードから隔離し、リソースの競合を防ぎます。

重要

CoreDNS Pod を再スケジューリングすると Pod が再起動し、DNS レイテンシーの一時的な急増や失敗が発生する可能性があります。この操作はオフピーク時に実行してください。

専用ノードプールの作成

ノードプールを作成する際は、以下のガイドラインに従ってください:

  • CoreDNS はコンピューティング集約型ではなく、ネットワーク集約型です。推奨サイズが 4 コア、8 GB メモリのネットワーク強化型インスタンスを使用してください。

  • CoreDNS はデフォルトで 2 つの Pod を実行するため、ノードプールには少なくとも 2 つのノードが必要です。

  • 他のポッドがこれらのノードで実行されないように、テイントとラベルを追加します。たとえば、テイントのキーと値のペアとラベルの両方として system-addon: system-addon を使用し、EffectNoSchedule に設定します。

詳細については、「ノードプールの作成と管理」をご参照ください。

CoreDNS Pod のノードプールへのスケジューリング

  1. [アドオン] ページで [CoreDNS] カードを見つけて、[設定] をクリックします。

  2. [NodeSelector] セクションで、専用ノードプールのラベルを追加します。

    既存の NodeSelector ラベルは削除しないでください。
  3. [Tolerations] セクションで、ノードプールの Taint に一致する Toleration を追加します。

    [Tolerations] に Toleration エントリを追加します: [effect] を NoSchedule に、[key] を system-addon に、[operator] を Equal に、[value] を system-addon に設定します。

  4. [OK] をクリックして、CoreDNS Pod が専用ノードで実行されていることを確認します:

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

高可用性のためのスケジューリングポリシーの使用

DNS の可用性を保護するため、CoreDNS はデフォルトで 2 つのスケジューリングポリシーを使用します:

  • Pod アンチアフィニティ (ノードレベル):2 つの CoreDNS Pod が同じノードで実行されないようにします。あるノードで障害が発生しても、他のノードで DNS は利用可能なままです。

  • トポロジーを意識したスケジューリング (ゾーンレベル):CoreDNS Pod を複数のアベイラビリティーゾーンに分散させ、Pod アンチアフィニティだけでは対処できないゾーンレベルの単一障害点を防ぎます。

重要

これらのポリシーは、初期スケジューリング中にのみ適用されます。ノードまたはゾーンの設定が変更された場合は、ACK コンソールcoredns デプロイメントを見つけ、[再デプロイ] をクリックします。

Pod アンチアフィニティ

CoreDNS は、requiredDuringSchedulingIgnoredDuringExecution アンチアフィニティルールを使用して、2 つの CoreDNS ポッドがノードを共有しないようにします。これには、以下を除き、十分なリソースを持つノードが少なくとも 2 つ必要です。

  • k8s.aliyun.com: trueノードの自動スケーリングが有効になっているノード (優先度低下)

  • type: virtual-kubelet — 仮想ノード (除外)

  • alibabacloud.com/lingjun-worker: true — Lingjun ノード (除外)

デフォルトのアフィニティ設定は次のとおりです:

      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              # 仮想ノードにはこのラベルがあります
              - key: type
                operator: NotIn
                values:
                - virtual-kubelet
              # lingjun ワーカーノードにはこのラベルがあります
              - key: alibabacloud.com/lingjun-worker
                operator: NotIn
                values:
                - "true"
          preferredDuringSchedulingIgnoredDuringExecution:
          - preference:
              matchExpressions:
              # 自動スケーリングされたノードにはこのラベルがあります
              - 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 は トポロジー対応スケジューリングを使用して、ポッドをゾーン間に分散させます。 whenUnsatisfiable: DoNotSchedule 設定はこれを強制します。この設定により、ゾーンバランス条件が満たされない場合、ポッドはスケジューリングされません。

これを確実に機能させるには:

  • クラスターには、少なくとも 2 つの異なるアベイラビリティーゾーンにノードが必要で、各アベイラビリティーゾーンには CoreDNS 用の十分なリソースを持つノードが少なくとも 1 つ必要です。

  • すべてのノードには topology.kubernetes.io/zone ラベルが付いている必要があります (デフォルトで適用されます)。ラベルがないか、一貫性がない場合、スケジューリングの失敗や不均一な分散が発生します。

  • クラスターを v1.27 以降に、CoreDNS を v1.12.1.3 以降にアップグレードしてください。以前のクラスターバージョンは matchLabelKeys をサポートしていないため、CoreDNS のローリングアップデートを行うと、Pod がゾーン間で不均等に分散されたり、一部のゾーンがカバーされないままになったりする可能性があります。以下で説明するmatchLabelKeys の設定をご参照ください。

v1.12.1.3 より前のバージョンの CoreDNS は、次のトポロジースプレッド制約を使用します:

topologySpreadConstraints:
- labelSelector:
    matchLabels:
      k8s-app: kube-dns
  maxSkew: 1
  topologyKey: topology.kubernetes.io/zone
  whenUnsatisfiable: DoNotSchedule
重要

任意の 2 つのゾーン間のポッド数の差は、 maxSkew (デフォルトは 1) を超えることはできません。 labelSelector は新旧両方の ReplicaSet のポッドをカウントするため、 maxSkew=1 を満たすように、スケジューラは合計ポッド数が少ないゾーンを優先します。 古いポッドが終了すると、新しいポッドが一部のゾーンに集中する可能性があります。

CoreDNS v1.12.1.3 以降では、matchLabelKeys (Kubernetes v1.27 以降) を使用してこの問題を修正しています:

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

matchLabelKeys: [pod-template-hash] を追加すると、制約が現在の ReplicaSet に限定されるため、ローリングアップデートによってポッドがゾーン全体に均等に分散されます。