このドキュメントは、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 コントロール プレーンとデータプレーンがクラスタ名を解決する方法を示しています。
この図では、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.localDNS 名と重複または競合しません。このモードはデフォルト モードです。- 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-dnsVPC スコープのゾーンの場合は gke-CLUSTER_NAME-CLUSTER_HASH-dns-vpc |
クラスタ スコープのゾーンの場合は gke-CLUSTER_NAME-CLUSTER_HASH-rpVPC スコープのゾーンの場合は 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-a、us-central1-b、us-central1-c、us-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 は、stubDomains と upstreamNameservers の値を 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_cluster が dns_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-dnsIP アドレス(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-dnsPod にかかる負荷は最小限に抑えられます。
移行後
- コントロール プレーンが Cloud DNS を使用するように更新された後も、Pod の
resolv.confファイルはkube-dnsIP アドレス(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-dnsPod に直接送信されます。この設定では、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 リクエストが断続的に失敗することがあります。エラーを最小限に抑えるため、この移行はダウンタイム中に行う必要があります。