Pod 数、リソース、スケジューリング、およびノードの隔離を設定して、マネージドされていないモードでの CoreDNS の停止を防止します。
マネージドされていないモードでは、CoreDNS の可用性とパフォーマンスは Pod 数、リソース制限、スケジューリング、およびノードの分散に依存します。デフォルト設定は小規模クラスター向けであり、本番ワークロードでは調整が必要です。
潜在的な影響
誤った設定やリソース不足の CoreDNS は、以下の 2 種類の問題を引き起こします。
-
可用性:不適切なスケジューリングにより、ノードレベルまたはゾーンレベルで単一障害点が発生します。リソース不足により Pod がエビクションされ、DNS が停止します。
-
パフォーマンス:共有ノード上のリソース競合により、レスポンスレイテンシーが増加します。ノード負荷が高いと I/O パケット損失が発生し、DNS リクエストが失敗します。
CoreDNS Pod 数の調整
UDP には再送機能がないため、特に IPVS の欠陥によりパケット損失が発生している状況で CoreDNS をスケールインまたは再起動すると、クラスター全体で最大 5 分間の DNS 解決タイムアウトまたは失敗が発生する可能性があります。「DNS 解決の問題のトラブルシューティング」をご参照ください。
CoreDNS には水平ポッド自動スケーリング (HPA) や CronHPA を使用しないでください。頻繁なスケールインにより解決失敗が発生します。
DNS 負荷の評価
レプリカ数を調整する前に、DNS 負荷を評価します。DNSPerf などのツールを使用して DNS 負荷を測定できます。
DNS 負荷を直接測定できない場合は、以下のガイドラインを使用します。
-
CPU コア 1 個以上、メモリ 1 GB 以上のリソース制限を持つ CoreDNS Pod を少なくとも 2 個実行します。
-
DNS 解決の秒間クエリ数 (QPS) は CPU 使用量に比例してスケーリングします。NodeLocal DNSCache を使用すると、各 CPU コアで 1 秒あたり 10,000 件以上のクエリを処理できます。ワークロードによって QPS 要件は大きく異なるため、各 CoreDNS Pod のピーク時の CPU 使用率をモニターし、業務ピーク時にいずれかの Pod が 1 コアを超える場合はレプリカをスケールアウトしてください。
-
負荷データがない場合は、ベースラインとしてノード 8 台につき Pod 1 個から開始します。
ノードに十分なリソースがある場合にのみ、スケールアウトが効果的です。ノードのメモリが不足している場合は、代わりにノードを追加するか、ノードあたりのリソースを増やしてください。
目標とするレプリカ数が決まったら、自動調整(推奨)または手動でスケーリングを行います。
自動調整の設定(推奨)
cluster-proportional-autoscaler はクラスターのサイズに基づいて CoreDNS のレプリカ数を調整します。HPA とは異なり、CPU メトリックに依存せず、破壊的なスケールインも行いません。デフォルト比率はノード 8 台につき Pod 1 個です。
レプリカ数の数式: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 制限を 4096m(最小値 1024m)に設定します。
CoreDNS Pod 仕様の変更により Pod が再起動され、一時的に DNS レイテンシーが急増したり、失敗が発生したりする可能性があります。この操作はオフピーク時間帯に行ってください。
-
ACK コンソール にログインします。左側のナビゲーションウィンドウで [クラスター] をクリックします。
-
[クラスター] ページで、対象のクラスター名をクリックします。左側のナビゲーションウィンドウで [アドオン] をクリックします。
-
[ネットワーク] タブで、CoreDNS を見つけ、[構成] をクリックします。

-
CoreDNS の構成を変更し、[OK] をクリックします。

専用ノードプールへのデプロイ
専用ノードプールにより、CoreDNS を他のワークロードから隔離し、リソース競合を防止します。
CoreDNS Pod の再スケジューリングにより Pod が再起動され、一時的に DNS レイテンシーが急増したり、失敗が発生したりする可能性があります。この操作はオフピーク時間帯に行ってください。
専用ノードプールの作成
ノードプールを作成する際は、以下のガイドラインに従ってください。
-
CoreDNS はコンピューティング集約型ではなくネットワーク集約型です。推奨サイズは CPU コア 4 個、メモリ 8 GB のネットワーク拡張型インスタンスを使用します。
-
CoreDNS はデフォルトで 2 個の Pod を実行するため、ノードプールには少なくとも 2 台のノードが必要です。
-
これらのノード上で他の Pod が実行されないように、Taint とラベルを追加します。たとえば、Taint のキーと値のペアおよびラベルとして
system-addon: system-addonを使用し、EffectをNoScheduleに設定します。
「ノードプールの作成と管理」をご参照ください。
CoreDNS Pod をノードプールにスケジューリング
-
[アドオン] ページで、CoreDNS カードを見つけ、[構成] をクリックします。
-
[NodeSelector] セクションで、専用ノードプールのラベルを追加します。
既存の NodeSelector ラベルを削除しないでください。

-
[Tolerations] セクションで、ノードプールの Taint に一致する Toleration を追加します。

-
[OK] をクリックし、CoreDNS Pod が専用ノード上で実行されていることを確認します。
kubectl -n kube-system get pod -o wide --show-labels | grep coredns
高可用性のためのスケジューリングポリシーの使用
DNS の可用性を保護するために、CoreDNS はデフォルトで次の 2 つのスケジューリングポリシーを使用します。
-
ポッドアンチアフィニティ(ノードレベル):2 つの CoreDNS Pod が同じノード上で実行されないようにします。ノードが障害した場合でも、他のノードで DNS が利用可能になります。
-
トポロジー認識スケジューリング(ゾーンレベル):CoreDNS Pod を複数の可用性ゾーンに分散させ、ポッドアンチアフィニティだけでは対処できないゾーンレベルの単一障害点を防止します。
これらのポリシーは初期スケジューリング時のみ適用されます。ノードまたはゾーンの構成が変更された場合は、ACK コンソール で coredns デプロイメントを見つけ、[再デプロイ] をクリックしてください。
ポッドアンチアフィニティ
CoreDNS は、2 つの CoreDNS Pod が同一ノード上で共有されないようにするため、requiredDuringSchedulingIgnoredDuringExecution アンチアフィニティルールを使用します。これには、以下のノードを除き、十分なリソースを持つノードが少なくとも 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 は トポロジー認識スケジューリング を使用して Pod をゾーン間で分散させます。whenUnsatisfiable: DoNotSchedule 設定により、ゾーンバランス条件を満たせない場合は Pod がスケジューリングされません。
これを確実に機能させるには、以下の条件を満たす必要があります。
-
クラスターには、CoreDNS に十分なリソースを持つノードが少なくとも 1 台ずつ、2 つ以上の異なるゾーンに存在する必要があります。
-
すべてのノードに
topology.kubernetes.io/zoneラベルが付与されている必要があります(デフォルトで付与されます)。ラベルが欠落または不整合であると、スケジューリングが失敗したり、分散が不均等になったりします。 -
クラスターを v1.27 以降に、CoreDNS を v1.12.1.3 以降にアップグレードします。古いクラスターバージョンでは matchLabelKeys がサポートされていないため、CoreDNS のローリングアップデート後に Pod がゾーン間で不均等に分散されたり、一部のゾーンがカバーされないままになる可能性があります。以下に説明する
matchLabelKeys構成をご参照ください。
CoreDNS v1.12.1.3 より前のバージョン では、次のトポロジースプレッド制約を使用します。
topologySpreadConstraints:
- labelSelector:
matchLabels:
k8s-app: kube-dns
maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
任意の 2 つのゾーン間の Pod 数の差は、maxSkew(デフォルト値 1)を超えてはなりません。
labelSelector は新旧両方の ReplicaSet の Pod をカウントするため、maxSkew=1 を満たすために、スケジューラは合計 Pod 数が少ないゾーンを優先します。古い Pod が終了した後、新しい Pod が一部のゾーンに集中する可能性があります。
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 に限定され、ローリングアップデート中に Pod がゾーン間で均等に分散されるようになります。