CoreDNS は、ACK クラスターのデフォルトの DNS サーバーです。クラスター内のすべてのサービス名と外部ドメインを解決します。すべてのワークロードは DNS に依存しているため、CoreDNS の障害はクラスター全体で広範なサービス中断を引き起こします。
アンマネージドモードでは、CoreDNS は他のワークロードと同様に実行されます。その信頼性は、Pod 数、リソース制限、スケジューリングポリシー、およびノード分散に依存します。デフォルトの構成は、小規模または低トラフィックのクラスターに適しています。大規模または本番ワークロードの場合は、ご利用のスケールと可用性要件に基づいてこれらの設定を調整してください。
潜在的な影響
設定ミスまたはリソース不足の CoreDNS は、次の 2 種類の問題を引き起こします。
可用性: 不適切なスケジューリング構成は、ノードレベルまたはゾーンレベルの単一障害点を作成します。不十分なリソース制限は Pod のエビクションを引き起こし、DNS サービスを中断させます。
パフォーマンス: 同じノード上の他のワークロードとのリソース競合は、レスポンスレイテンシーを増加させます。高いノード負荷はネットワーク I/O パケット損失を引き起こし、DNS リクエストの失敗につながります。
CoreDNS Pod 数の調整
UDP パケットには再送信メカニズムがないため、CoreDNS Pod のスケールインまたは再起動は、特に IPVS の欠陥がクラスターノードで UDP パケット損失を引き起こす場合、最大 5 分間続くクラスター全体のドメイン名解決のタイムアウトまたは失敗を引き起こす可能性があります。詳細については、「DNS 解決の問題のトラブルシューティング」をご参照ください。
水平 Pod 自動スケーリング (HPA) または CronHPA を使用して CoreDNS Pod 数を管理しないでください。これらのコントローラーは頻繁に Pod をスケールインするため、解決の失敗を引き起こします。
コンポーネントの圧力を評価する
レプリカ数を調整する前に、ご利用のクラスターの DNS 負荷を評価してください。DNSPerf などのツールは、全体的な DNS 負荷を測定できます。
DNS 負荷を直接測定できない場合は、次のガイドラインを使用してください。
少なくとも 2 つの CoreDNS Pod を実行し、それぞれに少なくとも 1 CPU コアと 1 GB のメモリのリソース制限を設定します。
NodeLocal DNSCache を有効にすると、各 CPU コアは 10,000 秒間クエリ数 (QPS) を超える処理を行います。Pod ごとのピーク CPU 使用率を監視してください。ピーク時にいずれかの Pod が継続的に 1 CPU コアを超える使用量を示す場合は、スケールアウトしてください。
負荷データがない場合は、控えめなベースラインとして、クラスターノード 8 台あたり 1 CoreDNS Pod から開始してください。
Pod のスケールアウトは、ノードに十分な利用可能なリソースがある場合にのみ役立ちます。クラスターノードのメモリが不足している場合、Pod を追加しても問題は解決しません。代わりに、ノードを追加するか、ノードごとのリソースを増やす必要があります。
ターゲットとするレプリカ数がわかったら、自動調整 (推奨) を使用するか、手動でスケーリングしてください。
自動調整の構成 (推奨)
cluster-proportional-autoscaler コンポーネントは、クラスターサイズに基づいて CoreDNS レプリカ数をリアルタイムで調整します。HPA とは異なり、CoreDNS の CPU メトリックに依存せず、DNS を中断させる可能性のあるスケールイン操作を実行しません。デフォルトでは、クラスターノード 8 台あたり 1 Pod をターゲットとします。
レプリカ数式は次のとおりです。replicas = max(ceil(cores × 1/coresPerReplica), ceil(nodes × 1/nodesPerReplica))。min および max パラメーターは、Pod 数を 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 レイテンシースパイクや解決の失敗を引き起こす可能性があります。この操作はオフピーク時間中に実行してください。
専用ノードプールへのデプロイ
CoreDNS Pod を専用ノードプールにスケジューリングすると、他のワークロードから分離され、リソース競合が防止されます。
CoreDNS Pod を専用ノードプールに再スケジューリングすると Pod が再起動され、短時間の DNS レイテンシースパイクや解決の失敗を引き起こす可能性があります。この操作はオフピーク時間中に実行してください。
専用ノードプールの作成
ノードプールを作成する際は、次のガイドラインに従ってください。
CoreDNS はネットワーク集約型ですが、コンピューティング集約型ではありません。少なくとも 4 CPU コアと 8 GB のメモリを持つネットワーク拡張型インスタンスを使用してください。
CoreDNS はデフォルトで 2 つの Pod を実行するため、ノードプールには少なくとも 2 つのノードが必要です。
他の Pod がこれらのノードにスケジューリングされるのを防ぐために、Taint とラベルを追加してください。たとえば、Taint のキーと値のペアおよびラベルの両方として
system-addon: system-addonを使用します。Taint のEffectをNoScheduleに設定してください。
詳細な手順については、「ノードプールの作成および管理」をご参照ください。
CoreDNS Pod のノードプールへのスケジューリング
「アドオン」ページで、「CoreDNS」カードを見つけ、「設定」をクリックします。
[NodeSelector] セクションで、専用ノードプールの label を追加します。
既存の NodeSelector ラベルを削除しないでください。

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

[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 アンチアフィニティのみが使用され、両方の Pod が同じゾーンに配置された場合、ゾーン障害は依然として DNS を中断させます。トポロジーアウェアスケジューリングは、クロスゾーン分散を強制することでこれを解決します。
これらのスケジューリングポリシーは、Pod が最初にスケジューリングされるときにのみ有効になります。ノードまたはゾーンの構成が変更された場合は、ACK コンソールに移動し、coredns Deployment を見つけ、[再デプロイ] をクリックして Pod を再配布します。
Pod アンチアフィニティ
CoreDNS は、2 つの CoreDNS Pod が同じノードを共有しないように、requiredDuringSchedulingIgnoredDuringExecution Pod アンチアフィニティルールを使用します。これが機能するには、ご利用のクラスターに、次のものを除く、十分なリソースリクエストが利用可能な少なくとも 2 つのノードが必要です。
k8s.aliyun.com: true— ノードの自動スケーリングが有効なノードtype: virtual-kubelet— 仮想ノードalibabacloud.com/lingjun-worker: true— Lingjun ノード
デフォルトのアフィニティ構成は次のとおりです。
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 をゾーン全体に分散します。whenUnsatisfiable: DoNotSchedule 設定はこれを強制します。ゾーンバランス条件が満たされない場合、Pod はスケジューリングされません。
これが確実に機能するには、次の条件を満たす必要があります。
ご利用のクラスターには、少なくとも 2 つの異なるゾーンにノードがあり、各ゾーンに CoreDNS に十分なリソースを持つノードが少なくとも 1 つあること。
すべてのノードに
topology.kubernetes.io/zoneラベル (デフォルトで適用) があること。ラベルの欠落または不整合は、スケジューリングの失敗や不均一な分散を引き起こす可能性があります。ご利用のクラスターを v1.27 以降に、CoreDNS を v1.12.1.3 以降にアップグレードして、以下で説明する
matchLabelKeysの修正を取得すること。
CoreDNS v1.12.1.3 以前のバージョンでは、このトポロジースプレッド制約を使用します。
topologySpreadConstraints:
- labelSelector:
matchLabels:
k8s-app: kube-dns
maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotScheduleローリングアップデート中、この構成は不均一な最終 Pod 分散を引き起こす可能性があります。labelSelector は、新旧両方の ReplicaSet からの Pod をカウントします。maxSkew=1 を満たすために、スケジューラは合計 Pod 数が少ないゾーン (新旧を組み合わせたもの) を優先します。古い Pod が削除された後、新しい Pod は少数のゾーンに集中する可能性があります。
CoreDNS v1.12.1.3 以降では、Kubernetes v1.27 で導入された matchLabelKeys 機能でこれを解決します。
topologySpreadConstraints:
- labelSelector:
matchLabels:
k8s-app: kube-dns
matchLabelKeys:
- pod-template-hash
nodeTaintsPolicy: Honor
maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedulematchLabelKeys: [pod-template-hash] を追加すると、スプレッド制約の範囲が現在の ReplicaSet の Pod のみに限定されるため、ローリングアップデートはすべてのゾーンで均一な分散を生成します。

