GKE 向け Cloud DNS について

このドキュメントは、GKE 用 Cloud DNS がクラスタに適した DNS ソリューションかどうかを判断する際に役立ちます。Cloud DNS を使用して、kube-dns などのクラスタホスト型の DNS プロバイダの代わりに Pod と Service の DNS 解決を処理できます。

Autopilot クラスタの場合、Cloud DNS はすでにデフォルトの DNS プロバイダです。Standard クラスタの場合は、kube-dns から Cloud DNS に切り替えることができます。

このドキュメントは、デベロッパー、管理者、アーキテクトなどの GKE ユーザーを対象としています。 Google Cloudの一般的なロールとタスクの例の詳細については、一般的な GKE Enterprise ユーザーロールとタスクをご覧ください。

このドキュメントでは、次のコンセプトを理解していることを前提としています。

GKE 向け Cloud DNS の仕組み

GKE の DNS プロバイダとして Cloud DNS を使用すると、Cloud DNS はクラスタでホストされる DNS プロバイダを必要とせずに、Pod と Service の DNS 解決を行います。Pod と Service の DNS レコードは、クラスタ IP アドレス、ヘッドレス、外部名の各 Service 向けに Cloud DNS に自動でプロビジョニングされます。

Cloud DNS は、完全な Kubernetes DNS 仕様をサポートし、GKE クラスタ内の Service の A、AAAA、SRV、PTR の各レコードの解決を行います。PTR レコードは、レスポンス ポリシー ルールを使用して実装されます。Cloud DNS を GKE 向け DNS プロバイダとして使用すると、クラスタでホストされる DNS と比べて次のメリットがあります。

  • オーバーヘッドの削減: クラスタでホストされる DNS サーバーを管理する必要がなくなります。Cloud DNS はフルマネージド サービスであるため、DNS インスタンスの手動スケーリング、モニタリング、管理は必要ありません。
  • 高いスケーラビリティとパフォーマンス: 各 GKE ノードのクエリをローカルで解決し、低レイテンシでスケーラビリティの高い DNS 解決を実現します。特に大規模なクラスタで最適なパフォーマンスを得るには、ノードに追加のキャッシュ保存レイヤを提供する NodeLocal DNSCache の有効化を検討してください。
  • Google Cloud Observability との統合: DNS のモニタリングとロギングが可能になります。詳細については、限定公開マネージド ゾーンのロギングを有効または無効にするをご覧ください。

アーキテクチャ

Cloud DNS が GKE 向け DNS プロバイダである場合、コントローラは GKE マネージド Pod として動作します。この Pod は、クラスタのコントロール プレーン ノードで実行され、クラスタの DNS レコードを限定公開マネージド DNS ゾーンに同期します。

次の図は、Cloud DNS コントロール プレーンとデータプレーンがクラスタ名を解決する方法を示しています。

Pod が Cloud DNS を使用して Service の IP アドレスをリクエストする
Cloud DNS を使用してクラスタ名を解決する

この図では、Service バックエンドが実行中のバックエンド Pod を選択します。clouddns-controller は、Service バックエンドの DNS レコードを作成します。

Pod フロントエンドは、backend という名前の Service の IP アドレスを解決するために、169.254.169.254 にある Compute Engine ローカル メタデータ サーバーに DNS リクエストを送信します。このメタデータ サーバーはノードのローカルで実行され、キャッシュミスを Cloud DNS に送信します。

Cloud DNS は、Kubernetes Service のタイプに基づいて Service 名を異なる IP アドレスに解決します。ClusterIP Service の場合、Cloud DNS は Service 名を仮想 IP アドレスに解決します。ヘッドレス Service の場合、Service 名をエンドポイント IP アドレスのリストに解決します。

Pod フロントエンドが IP アドレスを解決したら、Pod は Service バックエンドと Service の内側のすべての Pod にトラフィックを送信できます。

DNS スコープ

Cloud DNS には次の DNS スコープがあります。複数のモードでクラスタを同時に動作させることはできません。

  • GKE クラスタ スコープ: DNS レコードはクラスタ内でのみ解決できます。これは kube-dns と同じ動作です。Service 名を解決できるのは、GKE クラスタで動作しているノードのみです。デフォルトでは、クラスタの DNS 名は *.cluster.local で終わります。これらの DNS 名はクラスタ内でのみ参照され、同じプロジェクト内の他の GKE クラスタの *.cluster.local DNS 名と重複または競合しません。このモードはデフォルト モードです
    • Cloud DNS の追加の VPC スコープ: Cloud DNS の追加の VPC スコープは、GKE クラスタ スコープを拡張して、ヘッドレス サービスを VPC 内の他のリソース(Cloud VPN または Cloud Interconnect を使用して接続された Compute Engine VM やオンプレミス クライアントなど)から解決できるようにするオプション機能です。このモードは、クラスタ スコープと並行して有効になる追加モードです。DNS の稼働時間やクラスタ スコープの機能に影響を与えることなく、クラスタでこのモードを有効または無効にできます。
  • VPC スコープ: DNS レコードは VPC 全体で解決可能です。Compute Engine VM とオンプレミス クライアントは、Cloud Interconnect または Cloud VPN を使用して接続し、GKE Service 名を直接解決できます。クラスタごとに一意のカスタム ドメインを設定する必要があります。これは、すべての Service と Pod の DNS レコードが VPC 内で一意であることを意味します。このモードにより、GKE リソースと非 GKE リソース間の通信の負担が軽減されます。

次の表に、DNS スコープの違いを示します。

機能 GKE クラスタ スコープ Cloud DNS の追加の VPC スコープ VPC スコープ
DNS の公開設定の範囲 GKE クラスタ内のみ クラスタのみ。ヘッドレス Service は VPC ネットワーク全体で解決可能 VPC ネットワーク全体
ヘッドレス サービスの解決策 クラスタ内で解決可能 「cluster.local」ドメインを使用してクラスタ内で、クラスタのサフィックスを使用して VPC 全体で解決可能 クラスタのサフィックスを使用して、クラスタ内と VPC 全体で解決可能
固有のドメインの要件 いいえ。デフォルトの「*.cluster.local」ドメインを使用します はい、一意のカスタム ドメインを設定する必要があります はい、一意のカスタム ドメインを設定する必要があります
設定の構成 デフォルト。追加の手順はありません クラスタ作成時には省略可
いつでも有効または無効にできます
クラスタの作成時に構成する必要があります

Cloud DNS リソース

GKE クラスタの DNS プロバイダとして Cloud DNS を使用すると、Cloud DNS コントローラによりプロジェクトの Cloud DNS にリソースが作成されます。GKE が作成するリソースは、Cloud DNS のスコープによって異なります。

範囲 前方参照ゾーン 逆引き参照ゾーン
クラスタのスコープ Compute Engine ゾーン(リージョン内)ごとにクラスタごとに 1 つの限定公開ゾーン Compute Engine ゾーン(リージョン内)ごとにクラスタごとに 1 つのレスポンス ポリシー ゾーン
Cloud DNS の追加の VPC スコープ クラスタ(グローバル ゾーン)ごとに Compute Engine ゾーン(リージョン内)ごとにクラスタごとに 1 つの限定公開ゾーン
クラスタ(グローバル ゾーン)ごとに 1 つの VPC スコープの限定公開ゾーン
クラスタ(グローバル ゾーン)ごとに(リージョン内の)Compute Engine ゾーンごとにクラスタごとにクラスタごとに 1 つのレスポンス ポリシー ゾーン
クラスタ(グローバル ゾーン)ごとに 1 つの VPC スコープのレスポンス ポリシー ゾーン
VPC スコープ クラスタごとに 1 つの限定公開ゾーン(グローバル ゾーン) クラスタごとに 1 つのレスポンス ポリシー ゾーン(グローバル ゾーン)

これらの Cloud DNS リソースに使用される命名規則は次のとおりです。

範囲 前方参照ゾーン 逆引き参照ゾーン
クラスタのスコープ gke-CLUSTER_NAME-CLUSTER_HASH-dns gke-CLUSTER_NAME-CLUSTER_HASH-rp
Cloud DNS の追加の VPC スコープ クラスタ スコープのゾーンの場合は gke-CLUSTER_NAME-CLUSTER_HASH-dns
VPC スコープのゾーンの場合は gke-CLUSTER_NAME-CLUSTER_HASH-dns-vpc
クラスタ スコープのゾーンの場合は gke-CLUSTER_NAME-CLUSTER_HASH-rp
VPC スコープのゾーンの場合は gke-NETWORK_NAME_HASH-rp
VPC スコープ gke-CLUSTER_NAME-CLUSTER_HASH-dns gke-NETWORK_NAME_HASH-rp

前の表にあるゾーンに加えて、Cloud DNS コントローラは構成に応じて次のゾーンをプロジェクト内に作成します。

カスタム DNS 構成 ゾーンのタイプ ゾーンの命名規則
スタブドメイン 転送(グローバル ゾーン) gke-CLUSTER_NAME-CLUSTER_HASH-DOMAIN_NAME_HASH
カスタム アップストリーム ネームサーバー 転送(グローバル ゾーン) gke-CLUSTER_NAME-CLUSTER_HASH-upstream

カスタム スタブドメインまたはカスタム アップストリーム ネームサーバーの作成方法については、スタブドメインのカスタム リゾルバの追加をご覧ください。

マネージド ゾーンと転送ゾーン

クラスタ スコープを使用して内部 DNS トラフィックを処理するクラスタの場合、Cloud DNS コントローラは、クラスタが属するリージョンの Compute Engine ゾーンごとにマネージド DNS ゾーンを作成します。

たとえば、クラスタを us-central1-c ゾーンにデプロイする場合、Cloud DNS コントローラが、us-central1-aus-central1-bus-central1-cus-central1-f にマネージド ゾーンを作成します。

Cloud DNS コントローラは、DNS stubDomain ごとに 1 つの転送ゾーンを作成します。

Cloud DNS は、. DNS 名を持つ 1 つのマネージド ゾーンを使用して、各 DNS アップストリームを処理します。

割り当て

Cloud DNS は、割り当てを使用して、GKE が DNS エントリ用に作成できるリソースの数を制限します。Cloud DNS の割り当てと上限は、プロジェクトの kube-dns の制限とは異なる場合があります。

GKE 向け Cloud DNS を使用する場合、次のデフォルトの割り当てがプロジェクトの各マネージド ゾーンに適用されます。

Kubernetes DNS リソース 対応する Cloud DNS リソース 割り当て
DNS レコードの数 マネージド ゾーンあたりの最大バイト数 2,000,000(マネージド ゾーンの場合は最大 50 MB)
ヘッドレス サービスあたりの Pod 数(IPv4 または IPv6) リソース レコードセットあたりのレコード数 GKE 1.24 ~ 1.25: 1,000(IPv4 または IPv6)
GKE 1.26 以降: IPv4 の場合は 3,500、IPv6 の場合は 2,000
プロジェクト内の GKE クラスタ数 プロジェクトあたりのレスポンス ポリシー数 100
クラスタあたりの PTR レコード数 レスポンス ポリシーごとのルール数 100,000

リソースの上限

次の表に示すように、クラスタごとに作成する Kubernetes リソースは Cloud DNS リソースの上限に影響します。

上限 上限への影響
マネージド ゾーンあたりのリソース レコードセット サービスの数と、有効なホスト名があるヘッドレス サービス エンドポイントの数(クラスタごと)
リソース レコードセットあたりのレコード ヘッドレス サービスごとのエンドポイントの数。他のサービスタイプには影響しません。
レスポンス ポリシーあたりのルール数 クラスタ スコープの場合、サービスの数と、クラスタごとに有効なホスト名があるヘッドレス サービス エンドポイントの数。VPC スコープの場合、VPC 内のすべてのクラスタの、サービスの数とホスト名があるヘッドレス エンドポイントの数。

Kubernetes に対する DNS レコードの作成方法については、Kubernetes の DNS ベースのサービス ディスカバリをご覧ください。

サービス プロジェクトごとに複数のクラスタ

GKE バージョン 1.22.3-gke.700 および 1.21.6-gke.1500 以降では、同じホスト プロジェクト内の VPC を参照する複数のサービス プロジェクトでクラスタを作成できます。

カスタム スタブドメインとアップストリーム ネームサーバーをサポートする

GKE 向け Cloud DNS は、kube-dns ConfigMap を使用して構成されたカスタム スタブドメインとアップストリーム ネームサーバーをサポートしています。このサポートは GKE Standard クラスタでのみ利用できます。

Cloud DNS は、stubDomainsupstreamNameservers の値を Cloud DNS 転送ゾーンに変換します。

仕様拡張

さまざまなクライアントやシステムとのサービス ディスカバリと互換性を改善するため、一般的な Kubernetes DNS 仕様に加えて追加の仕様を使用できます。

名前付きポート

このセクションでは、Cloud DNS によって Kubernetes クラスタ用に作成される DNS レコードに名前付きポートがどのように影響するかについて説明します。Kubernetes は、必要な DNS レコードの最小セットを定義します。一方、Cloud DNS は、独自のオペレーションとさまざまな Kubernetes 機能をサポートするために追加のレコードを作成する場合があります。次の表に、想定されるレコードセットの最小数を示します。ここで、「E」はエンドポイントの数、「P」はポートの数を表します。Cloud DNS によって追加のレコードが作成される場合があります。

IP スタックタイプ サービスタイプ レコードセット
シングル スタック ClusterIP
$$2+P$$
ヘッドレス
$$2+P+2E$$
デュアル スタック ClusterIP
$$3+P$$
ヘッドレス
$$3+P+3E$$
シングル スタック サービスとデュアル スタック サービスの詳細については、シングル スタック サービスとデュアル スタック サービスをご覧ください。

Cloud DNS によって作成される追加の DNS レコード

Cloud DNS は、レコードセットの最小数を超える DNS レコードを作成する場合があります。これらのレコードは、次のようなさまざまな目的に使用されます。

  • SRV レコード: Cloud DNS は、サービス ディスカバリのために SRV レコードを作成します。これらのレコードには、サービスのポートとプロトコルに関する情報が含まれています。
  • AAAA レコード(デュアル スタックの場合): IPv4 と IPv6 の両方を使用するデュアル スタック構成では、Cloud DNS は各エンドポイントに A レコード(IPv4 用)と AAAA レコード(IPv6 用)の両方を作成します。
  • 内部レコード: Cloud DNS は、独自の管理と最適化のために内部レコードを作成する場合があります。通常、これらのレコードはユーザーに直接関連するものではありません。
  • LoadBalancer Service: LoadBalancer タイプの Service に対して、Cloud DNS は外部ロードバランサの IP アドレスに関連付けられたレコードを作成します。
  • Headless Service: Headless Service には独自の DNS 構成があります。各 Pod は独自の DNS レコードを取得するため、クライアントは Pod に直接接続できます。このため、ヘッドレス Service レコードの計算でポート番号は乗算されません。

: backend Namespace にある my-http-server という Service について考えてみましょう。この Service は、3 つの Pod を含む Deployment に対して 80 と 8080 の 2 つのポートを公開します。したがって、E = 3、P = 2 です。

IP スタックタイプ サービスタイプ レコードセット
シングル スタック ClusterIP
$$2+2$$
ヘッドレス
$$2+2+2*3$$
デュアル スタック ClusterIP
$$3+2$$
ヘッドレス
$$3+2+3*3$$

これらの最小レコードに加えて、Cloud DNS は SRV レコードを作成します。デュアル スタック ネットワーキングの場合は AAAA レコードも作成します。my-http-server が LoadBalancer タイプの Service の場合、ロードバランサ IP 用に追加レコードが作成されます。注: Cloud DNS は、必要に応じて補足の DNS レコードを追加します。作成される具体的なレコードは、Service のタイプや構成などの要因によって異なります。

既知の問題

このセクションでは、GKE で Cloud DNS を使用する際に発生する可能性のある一般的な問題と、考えられる回避策について説明します。

Terraform は dns_config の変更により Autopilot クラスタの再作成を試みる

terraform-provider-google または terraform-provider-google-beta を使用すると、Terraform が Autopilot クラスタの再作成を試みるという問題が発生することがあります。このエラーは、バージョン 1.25.9-gke.400、1.26.4-gke.500、1.27.1-gke.400 以降を実行している新しく作成された Autopilot クラスタが、kube-dns の代わりに DNS プロバイダとして Cloud DNS を使用しているために発生します。

この問題は、 Google Cloudの Terraform プロバイダのバージョン 4.80.0 で解決されています。

terraform-provider-google または terraform-provider-google-beta のバージョンを更新できない場合は、lifecycle.ignore_changes 設定をリソースに追加して、google_container_clusterdns_config への変更を無視するようにできます。

  lifecycle {
    ignore_changes = [
      dns_config,
    ]
  }

NodeLocal DNSCache が有効な状態で kube-dns から Cloud DNS に移行した後に DNS 解決が失敗する

このセクションでは、Cloud DNS にあり、クラスタ スコープで NodeLocal DNSCache を有効にしている GKE クラスタの既知の問題について説明します。

クラスタで NodeLocal DNSCache が有効になっている状態で kube-dns から Cloud DNS に移行すると、クラスタで断続的に名前解決エラーが発生することがあります。

クラスタで NodeLocal DNSCache が有効になっている状態で kube-dns を使用する場合、NodeLocal DNSCache は NodeLocal DNSCache アドレスと kube-dns アドレスの両方でリッスンするように構成されます。

NodeLocal DNSCache のステータスを確認するには、次のコマンドを実行します。

kubectl get cm -n kube-system node-local-dns -o json | jq .data.Corefile -r | grep bind

出力は次のようになります。

    bind 169.254.20.10 x.x.x.10
    bind 169.254.20.10 x.x.x.10

クラスタで GKE Dataplane V2 が有効になっていて、クラスタが kube-dns を使用している場合、NodeLocal DNSCache は分離されたネットワークで実行され、すべての Pod IP アドレス(0.0.0.0)でリッスンするように構成されます。出力は次のようになります。

    bind 0.0.0.0
    bind 0.0.0.0

クラスタが Cloud DNS に更新されると、NodeLocal DNSCache 構成が変更されます。NodeLocal DNSCache 構成を確認するには、次のコマンドを実行します。

kubectl get cm -n kube-system node-local-dns -o json | jq .data.Corefile -r | grep bind

出力は次のようになります。

    bind 169.254.20.10
    bind 169.254.20.10

次のワークフローは、移行とノードの再作成の前後の resolv.conf ファイルのエントリを示しています。

移行前

  • Pod の resolv.conf ファイルが kube-dns IP アドレス(x.x.x.10 など)に構成されています。
  • NodeLocal DNSCache Pod は、Pod からの DNS リクエストをインターセプトし、次のアドレスでリッスンします。
    • (DPv1)両方のアドレス(169.254.20.10 x.x.x.10 をバインド)。
    • (DPv2)すべての Pod IP アドレス(0.0.0.0 をバインド)。
  • NodeLocal DNSCache はキャッシュとして機能し、kube-dns Pod にかかる負荷は最小限に抑えられます。

移行後

  • コントロール プレーンが Cloud DNS を使用するように更新された後も、Pod の resolv.conf ファイルは kube-dns IP アドレス(x.x.x.10 など)に構成されたままです。Pod は、ノードが再作成されるまでこの resolv.conf 構成を保持します。NodeLocal DNSCache で Cloud DNS が有効になっている場合、Pod はネームサーバーとして 169.254.20.10 を使用するように構成する必要があります。ただし、この変更は、Cloud DNS への移行後に作成または再作成されたノード上の Pod にのみ適用されます。
  • NodeLocal DNSCache Pod は、NodeLocal DNSCache アドレスでのみリッスンします(169.254.20.10 にバインド)。リクエストが NodeLocal DNSCache Pod に送信されません。
  • Pod からのすべてのリクエストは、kube-dns Pod に直接送信されます。この設定では、Pod で大量のトラフィックが発生します。

ノードの再作成後またはノードプールのアップグレード後

  • Pod の resolv.conf ファイルは、NodeLocal DNSCache IP アドレス(169.254.20.10)を使用するように構成されています。
  • NodeLocal DNSCache Pod は、NodeLocal DNSCache アドレス(169.254.20.10 にバインド)でのみリッスンし、この IP アドレスの Pod から DNS リクエストを受信します。

ノードプールの再作成前にノードプールが resolv.conf ファイルの kube-dns IP アドレスを使用すると、DNS クエリ トラフィックの増加に伴い kube-dns Pod のトラフィックが増加します。この増加により、DNS リクエストが断続的に失敗することがあります。エラーを最小限に抑えるため、この移行はダウンタイム中に行う必要があります。

次のステップ