次の方法で共有


Azure Kubernetes Service で CoreDNS をカスタマイズする

Azure Kubernetes Service (AKS) では、すべての 1.12.x 以降のクラスターで、クラスター DNS の管理と解決に CoreDNS プロジェクトを使用します。 CoreDNS のカスタマイズと Kubernetes の詳細については、公式のアップ ストリーム ドキュメントを参照してください。

AKS はマネージド サービスであるため、CoreDNS のメイン構成 (CoreFile) を変更することはできません。 代わりに、既定の設定をオーバーライドするには、Kubernetes ConfigMap を使用してください。 既定の AKS CoreDNS ConfigMaps を表示するには、kubectl get configmaps --namespace=kube-system coredns -o yaml コマンドを使用します。

この記事では、AKS の 基本的な CoreDNS のカスタマイズ オプションに ConfigMaps を使用する方法を説明します。 この方法は、CoreFile のような他のコンテキストでの CoreDNS の構成とは異なります。

以前は kube-dns がクラスター DNS の管理と解決に使用されていましたが、現在は非推奨になりました。 kube-dns では、Kubernetes 構成マップを介してさまざまなカスタマイズ オプションが提供されていました。 CoreDNS には kube-dns との下位互換性はありません。 以前に使用していたカスタマイズはすべて、CoreDNS 用に更新する必要があります。

開始する前に

  • この記事では、既存の AKS クラスターがすでにあることを前提としています。 AKS クラスターが必要な場合は、Azure CLIAzure PowerShell、または Azure portal を使用して作成できます。
  • 実行している CoreDNS のバージョンを確認します。 構成値はバージョンによって変わることがあります。
  • 次の例のような構成を作成するとき、data セクション内の名前は .server または .override で終わる必要があります。 この名前付け規則は、kubectl get configmaps --namespace=kube-system coredns -o yaml コマンドを使用して表示できる既定の AKS CoreDNS ConfigMap で定義されています。

プラグインのサポート

組み込みの CoreDNS プラグインはすべてサポート対象です。 アドオン/サード パーティ製のプラグインはサポート対象外です。

DNS を書き換える

AKS を使用して CoreDNS をカスタマイズして、その場での DNS 名書き換えを行うことができます。

  1. corednsms.yaml という名前のファイルを作成し、次の構成例を貼り付けます。 必ず <domain to be rewritten> を独自の完全修飾ドメイン名に置き換えてください。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: kube-system
    data:
      test.server: |
        <domain to be rewritten>.com:53 {
        log
        errors
        rewrite stop {
          name regex (.*)\.<domain to be rewritten>\.com {1}.default.svc.cluster.local
          answer name (.*)\.default\.svc\.cluster\.local {1}.<domain to be rewritten>.com
        }
        forward . /etc/resolv.conf # you can redirect this to a specific DNS server such as 10.0.0.10, but that server must be able to resolve the rewritten domain name
        }
    

    重要

    CoreDNS サービス IP などの DNS サーバーにリダイレクトする場合、その DNS サーバーは、書き換えられたドメイン名を解決できる必要があります。

  2. kubectl apply configmap コマンドを使用して ConfigMap を作成し、YAML マニフェストの名前を指定します。

    kubectl apply -f corednsms.yaml
    
  3. kubectl get configmaps を使用してカスタマイズが適用されていることを確認し、coredns-custom ConfigMap を指定します。

    kubectl get configmaps --namespace=kube-system coredns-custom -o yaml
    
  4. ConfigMap を再度読み込み、Kubernetes Scheduler がダウンタイムなしで CoreDNS を再起動できるようにするには、kubectl rollout restart を使用してローリング再起動を実行します。

    kubectl -n kube-system rollout restart deployment coredns
    

カスタム転送サーバー

ネットワーク トラフィックの転送サーバーを指定する必要がある場合は、ConfigMap を作成して DNS をカスタマイズできます。

  1. corednsms.yaml という名前のファイルを作成し、次の構成例を貼り付けます。 必ず、forward の名前とアドレスを自分の環境の値に置き換えてください。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: kube-system
    data:
      test.server: | # you may select any name here, but it must end with the .server file extension
        <domain to be rewritten>.com:53 {
            forward foo.com 1.1.1.1
        }
    
  2. kubectl apply configmap コマンドを使用して ConfigMap を作成し、YAML マニフェストの名前を指定します。

    kubectl apply -f corednsms.yaml
    
  3. ConfigMap を再度読み込み、Kubernetes Scheduler がダウンタイムなしで CoreDNS を再起動できるようにするには、kubectl rollout restart を使用してローリング再起動を実行します。

    kubectl -n kube-system rollout restart deployment coredns
    

カスタム ドメインを使用する

内部的にしか解決できないカスタム ドメインを構成する必要が生じる場合があります。 たとえば、有効なトップレベル ドメインではないカスタム ドメイン puglife.local を解決する必要がある場合があります。 カスタム ドメインの ConfigMap がないと、AKS クラスターではアドレスを解決できません。

  1. corednsms.yaml という名前の新しいファイルを作成し、次の構成例を貼り付けます。 かならず、カスタム ドメイン と IP アドレスを、自分の環境の値で更新します。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: kube-system
    data:
      puglife.server: | # you may select any name here, but it must end with the .server file extension
        puglife.local:53 {
            errors
            cache 30
            forward . 192.11.0.1  # this is my test/dev DNS server
        }
    
  2. kubectl apply configmap コマンドを使用して ConfigMap を作成し、YAML マニフェストの名前を指定します。

    kubectl apply -f corednsms.yaml
    
  3. ConfigMap を再度読み込み、Kubernetes Scheduler がダウンタイムなしで CoreDNS を再起動できるようにするには、kubectl rollout restart を使用してローリング再起動を実行します。

    kubectl -n kube-system rollout restart deployment coredns 
    

スタブ ドメイン

CoreDNS を使用してスタブ ドメインを構成することもできます。

  1. corednsms.yaml という名前のファイルを作成し、次の構成例を貼り付けます。 かならず、カスタム ドメイン と IP アドレスを、自分の環境の値で更新します。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: kube-system
    data:
      test.server: | # you may select any name here, but it must end with the .server file extension
        abc.com:53 {
         errors
         cache 30
         forward . 1.2.3.4
        }
        my.cluster.local:53 {
            errors
            cache 30
            forward . 2.3.4.5
        }
    
    
  2. kubectl apply configmap コマンドを使用して ConfigMap を作成し、YAML マニフェストの名前を指定します。

    kubectl apply -f corednsms.yaml
    
  3. ConfigMap を再度読み込み、Kubernetes Scheduler がダウンタイムなしで CoreDNS を再起動できるようにするには、kubectl rollout restart を使用してローリング再起動を実行します。

    kubectl -n kube-system rollout restart deployment coredns
    

ホストのプラグイン

すべての組み込みプラグインがサポートされるので、CoreDNS hosts プラグインを使用して /etc/hosts もカスタマイズできます。

  1. corednsms.yaml という名前のファイルを作成し、次の構成例を貼り付けます。 IP アドレスとホスト名は、必ず実際の環境に合わせた値に更新してください。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom # this is the name of the configmap you can overwrite with your changes
      namespace: kube-system
    data:
        test.override: | # you may select any name here, but it must end with the .override file extension
              hosts { 
                  10.0.0.1 example1.org
                  10.0.0.2 example2.org
                  10.0.0.3 example3.org
                  fallthrough
              }
    
  2. kubectl apply configmap コマンドを使用して ConfigMap を作成し、YAML マニフェストの名前を指定します。

    kubectl apply -f corednsms.yaml
    
  3. ConfigMap を再度読み込み、Kubernetes Scheduler がダウンタイムなしで CoreDNS を再起動できるようにするには、kubectl rollout restart を使用してローリング再起動を実行します。

    kubectl -n kube-system rollout restart deployment coredns
    

internal.cloudapp.net と reddog.microsoft.com の検索ドメイン補完が無効です

Azure DNS は、仮想ネットワーク内の <vnetId>.<region>.internal.cloudapp.net の既定検索ドメインを構成する際には Azure DNS を使用し、仮想ネットワーク内の機能しないスタブ reddog.microsoft.com を構成する際にはカスタム DNS サーバーを使用します (詳細については、リソースの名前解決に関するドキュメントを参照してください)。 Kubernetes は、ポッドの DNS 設定を構成する際、クラスター サービスのホスト名解決を適切にサポートするために ndots: 5 を使用します。 これら 2 つの構成の組み合わせは、システムによってドメイン検索リストが処理される際、決して成功しない無効な検索ドメイン補完クエリがアップストリーム ネーム サーバーに送信される結果を引き起こします。 それらの無効なクエリは、名前解決に遅延が発生する原因になり、アップストリーム DNS サーバーに余分な負荷をかける可能性もあります。

v20241025 AKS リリースにおいて、AKS は、そうした無効な検索ドメイン補完クエリがアップストリーム DNS に転送されるのを防ぐために、以下 2 つの場合には NXDOMAIN で応答するよう CoreDNS を構成します。

  • reddog.microsoft.com のルート ドメインまたはサブドメインに対する任意のクエリ。
  • internal.cloudapp.net のサブドメインで、ドメイン名に 7 個以上のラベルが含まれるクエリ。
    • ホスト名による仮想マシンの解決は、この構成においても従来と同じように成功します。 たとえば、aks12345.myvnetid.myregion.internal.cloudapp.net (ラベル 6 個) は CoreDNS から Azure DNS に送信されますが、mcr.microsoft.com.myvnetid.myregion.internal.cloudapp.net (ラベル 8 個) は拒否されます

このブロックは、クラスターの Corefile で既定のサーバー ブロック内に実装されています。 この拒否構成を無効にすることが必要な場合は、以下のように、転送プラグインが有効になっている適切なドメイン用にカスタム サーバー ブロックを作成することで対応できます。

  1. corednsms.yaml という名前のファイルを作成し、次の構成例を貼り付けます。 IP アドレスとホスト名は、必ず実際の環境に合わせた値に更新してください。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom # this is the name of the configmap you can overwrite with your changes
      namespace: kube-system
    data:
        override-block.server:
           internal.cloudapp.net:53 {
               errors
               cache 30
               forward . /etc/resolv.conf
           }
           reddog.microsoft.com:53 {
               errors
               cache 30
               forward . /etc/resolv.conf
           }
    
  2. kubectl apply configmap コマンドを使用して ConfigMap を作成し、YAML マニフェストの名前を指定します。

    kubectl apply -f corednsms.yaml
    
  3. ConfigMap を再度読み込み、Kubernetes Scheduler がダウンタイムなしで CoreDNS を再起動できるようにするには、kubectl rollout restart を使用してローリング再起動を実行します。

    kubectl -n kube-system rollout restart deployment coredns
    

トラブルシューティング

エンドポイントや解決策を調べるなど、CoreDNS の一般的なトラブルシューティング手順については、「DNS 解決のデバッグ」を参照してください。

CoreDNS のポッドの水平スケーリングを構成する

AKS クラスター内の DNS トラフィックの突然の増加は、一般的な事象です。これは、AKS がワークロードに提供する柔軟性によるものです。 これらの増加により、CoreDNS ポッドによるメモリ消費量が増加する可能性があります。 場合によっては、このメモリ消費量の増加がOut of memory問題の原因となる可能性があります。 この問題を回避するために、AKS クラスターは CoreDNS ポッドを自動スケーリングして、ポッドあたりのメモリ使用量を減らします。 この自動スケーリング ロジックの既定の設定は、coredns-autoscalerConfigMap に保存されます。 ただし、CoreDNS ポッドの既定の自動スケーリングが、CoreDNS ポッドのOut of memory問題を防ぐのに常に有効であるとは限りません。 この場合は、coredns-autoscalerConfigMap を直接変更できます。 Out of memory問題の根本原因に対処せずに CoreDNS ポッドの数を増やすことは、一時的な解決にしかならない場合があることに注意してください。 CoreDNS ポッドが実行されているノードで十分なメモリが使用できない場合、CoreDNS ポッドの数を増やすことは役に立ちません。 さらに調査し、リソース使用量の最適化、リソース要求と制限の調整、ノードへのメモリの追加など、適切な解決策を実行することが必要になる場合があります。

CoreDNS では、ポッドの自動スケーリングに、水平クラスターに比例する自動スケーラーが使用されます。 coredns-autoscalerConfigMap を編集して、CoreDNS ポッドの数のスケーリング ロジックを構成できます。 現在、coredns-autoscalerConfigMap では 2 つの異なる ConfigMap キー値、linearladder がサポートされています。これらは、サポートされている 2 つの制御モードに対応しています。 linearコントローラーは、max( ceil( cores * 1/coresPerReplica ) , ceil( nodes * 1/nodesPerReplica ) ) と同じ [最小値,最大値] の範囲で多数のレプリカを生成します。 ladderコントローラーは、コア スケーリング用とノード スケーリング用の 2 つの異なるステップの関数を参照してレプリカの数を計算し、2 つのレプリカ値の最大値を生成します。 制御モードと ConfigMap のフォーマットの詳細については、上流のドキュメントを参照してください。

重要

クラスターあたり少なくとも 2 個の CoreDNS ポッド レプリカが推奨されます。 構成する CoreDNS ポッド レプリカの数が最小で 1 個の場合、クラスターのアップグレード操作など、ノードのドレインを必要とする操作中にエラーが発生する可能性があります。

coredns-autoscalerConfigMap を取得するには、以下の結果を返すkubectl get configmap coredns-autoscaler -n kube-system -o yamlコマンドを実行することができます。

apiVersion: v1
data:
  ladder: '{"coresToReplicas":[[1,2],[512,3],[1024,4],[2048,5]],"nodesToReplicas":[[1,2],[8,3],[16,4],[32,5]]}'
kind: ConfigMap
metadata:
  name: coredns-autoscaler
  namespace: kube-system
  resourceVersion: "..."
  creationTimestamp: "..."

CoreDNS 垂直ポッドの自動スケール動作

CoreDNS は、AKS によって管理され、既定で有効になっている重要なアドオンです。 CoreDNS サービスの可用性を維持するために、CoreDNS では、CoreDNS ポッドの再起動プロセスによってサービスが利用できなくなるのを防ぐために 、アドオンの自動スケール機能を 有効にするときに、提供された元のリソース要求/制限の使用が維持されます。

AKS マネージド CoreDNS アドオンの場合、既定の CPU 要求/制限は 100m/3 コア、メモリ要求/制限は 70Mi/500Mi に設定されます。 これらの既定値に基づいて、CPU の要求対制限の比率は約 1:30 で、メモリの場合は約 1/7 です。 推奨される CPU 要求が 500m の場合、VPA はこの比率を維持するために CPU 制限を 15 に調整します。 同様に、推奨されるメモリ要求が 700Mi の場合、VPA はメモリ制限を 5000Mi に調整します。

VPA は、VPA 推奨 CPU/Mem 要求と AKS 定義の要求対制限比に基づいて、CoreDNS CPU とメモリの制限を大きな値に設定します。 これらの調整は、サービスのピーク時に複数の要求を処理する場合に役立ちます。 欠点は、コアDNSがサービス時間のピーク時にノード上のすべての CPU およびメモリ利用可能なリソースを消費する可能性があるということです。

大規模クラスターと小規模クラスターの両方の要件を同時に満たすために、単一の理想的な CPU とメモリの要求/制限値を設定することは困難です。 最適化されたアドオン スケーリングを有効にすると、CoreDNS の CPU とメモリの要求/制限をカスタマイズしたり、VPA を使用して特定のクラスター要件を満たすために CoreDNS を自動スケールしたりできます。 考慮すべきいくつかのシナリオを次に示します。

  • VPA が CoreDNS サービスに適しているかどうか、および VPA の推奨事項のみを表示することを検討しています。 VPA でポッドを自動的に更新しない場合は、オーバーライド VPA 更新モードを オフ にすることで、CoreDNS の VPA を無効にすることができます。 デプロイのリソース構成をカスタマイズ して、CPU/メモリ要求/制限を好みの値に設定します。
  • VPA の使用を検討していますが、VPA が CPU とメモリの制限を一度に大きな値にバンプしないように、要求対制限の比率を制限する必要があります。 デプロイのリソースをカスタマイズし、CPU とメモリの要求/制限の値を更新して、要求対制限の比率を 1/2 または 1/3 に維持できます。
  • VPA コンテナー ポリシーで maxAllowed CPU とメモリが設定されている場合、推奨されるリソース要求はこれらの制限を超えるものではありません。 リソース構成をカスタマイズすると、maxAllowed 値を増減し、VPA の推奨事項を制御できます。

詳細については、「 AKS クラスターでアドオンの自動スケールを有効にする (プレビュー)」を参照してください

DNS クエリのログ記録を有効にする

  1. 次の構成を coredns-custom ConfigMap に追加します。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: kube-system
    data:
      log.override: | # you may select any name here, but it must end with the .override file extension
            log
    
  2. 次のコマンドを使用して、構成の変更を適用し、CoreDNS を強制的に ConfigMap を再読み込みさせます。

    # Apply configuration changes
    kubectl apply -f corednsms.yaml
    
    # Force CoreDNS to reload the ConfigMap
    kubectl -n kube-system rollout restart deployment coredns
    
  3. kubectl logs コマンドを使用して CoreDNS デバッグ ログを表示します。

    kubectl logs --namespace kube-system -l k8s-app=kube-dns
    

CoreDNS ポッドのトラフィックの不均衡のトラブルシューティング

AKS クラスターで複数の CoreDNS ポッドが実行されている場合でも、1 つまたは 2 つの CoreDNS ポッドの CPU 使用率が大幅に高く、他のポッドよりも多くの DNS クエリを処理している場合があります。 これは Kubernetes の 既知の問題 であり、CoreDNS ポッドの 1 つが過負荷になり、クラッシュする可能性があります。

この不均一な DNS クエリの分散は、主に Kubernetes の UDP 負荷分散の制限によって発生します。 プラットフォームでは、5 タプル ハッシュ (ソース IP、送信元ポート、宛先 IP、宛先ポート、プロトコル) を使用して UDP トラフィックを分散するため、アプリケーションが DNS クエリに同じソース ポートを再利用する場合、そのクライアントからのすべてのクエリが同じ CoreDNS ポッドにルーティングされ、その結果、1 つのポッドで不均衡な量のトラフィックが処理されます。

さらに、一部のアプリケーションでは接続プールを使用し、DNS 接続を再利用します。 この動作により、単一の CoreDNS ポッドに DNS クエリをさらに集中させ、不均衡を悪化させ、オーバーロードや潜在的なクラッシュのリスクを高めることができます。

CoreDNS ポッドのトラフィック分散の確認

開始する前に、上記の「 DNS クエリ ログを有効にする 」セクションの手順に従って、CoreDNS ポッドから必要な DNS クエリ ログをキャプチャします。 これが有効になったら、次のコマンドを実行します。

  1. 次のコマンドを実行して、クラスター内のすべての CoreDNS ポッドの名前を取得します。

    kubectl get pods --namespace kube-system -l k8s-app=kube-dns
    
  2. 各 CoreDNS ポッドのログを確認して、DNS クエリ パターンを分析します。

    kubectl logs --namespace kube-system <coredns-pod1>
    kubectl logs --namespace kube-system <coredns-pod2>
    # Repeat on all CoreDNS pods
    
  3. 1 つの CoreDNS ポッドのログにのみ表示される繰り返しのクライアント IP アドレスとポートを探します。 これは、特定のクライアントからの DNS クエリが均等に分散されていないことを示します。

    ログ エントリの例:

    [INFO] 10.244.0.247:5556 - 42621 "A IN myservice.default.svc.cluster.local. udp 28" NOERROR qr,aa,rd 106 0.000141s
    
    • 10.244.0.247: DNS クエリを作成するクライアント IP アドレス
    • 5556: クライアント ソース ポート
    • 42621: クエリ ID

    1 つのポッドのログにのみ同じクライアント IP とポートが繰り返し表示される場合は、トラフィックの不均衡が確認されます。

この不均衡に気付いた場合、アプリケーションは UDP ソース ポートを再利用したり、接続をプールしたりする可能性があります。 根本原因に基づいて、次の軽減策を実行できます。

  • UDP ソース ポートの再利用が原因で発生します。

    UDP ソース ポートの再利用は、クライアント アプリケーションが同じ UDP ソース ポートから複数の DNS クエリを送信するときに発生します。 これが問題である場合は、アプリケーションまたは DNS クライアントを更新して、各 DNS クエリのソース ポートをランダム化します。これにより、ポッド間で要求をより均等に分散できます。

  • 接続プールが原因で発生:
    接続プールは、要求ごとに新しい接続を作成するのではなく、既存のネットワーク接続を再利用するためにアプリケーションによって使用されるメカニズムです。 これにより効率が向上しますが、アプリケーションからのすべての DNS クエリが同じ接続経由で送信され、同じ CoreDNS ポッドにルーティングされる可能性があります。 これを軽減するには、接続 TTL (Time to Live) を減らすか、接続の作成をランダム化して、クエリが 1 つの CoreDNS ポッドに集中しないようにすることで、アプリケーションの DNS 接続処理を調整します。

これらの変更は、よりバランスの取れた DNS クエリ分散を実現し、個々のポッドをオーバーロードするリスクを軽減するのに役立ちます。

次のステップ

この記事では、CoreDNS カスタマイズのシナリオ例をいくつか紹介しました。 CoreDNS プロジェクトについては、CoreDNS アップストリーム プロジェクト ページを参照してください。

コア ネットワークの概念の詳細については、「AKS でのアプリケーションに対するネットワークの概念」を参照してください。