このドキュメントでは、Google Kubernetes Engine(GKE)のサービス ディスカバリによってアプリケーション管理がどのように簡素化されるか、また、Cloud DNS スコープ、マルチクラスタ サービス(MCS)、Service Directory を使用して、サービス ディスカバリを単一クラスタを超えて拡張する方法について説明します。
このドキュメントは、GKE ユーザー、デベロッパー、管理者、アーキテクトを対象としています。 Google Cloud のコンテンツで参照する一般的なロールとタスク例の詳細については、一般的な GKE Enterprise ユーザーロールとタスクをご覧ください。
このドキュメントを読む前に、次のコンセプトを理解しておいてください。
概要
サービス ディスカバリは、IP アドレスやエンドポイント構成をハードコードせずに、サービスとアプリケーションが相互に動的に検索して通信できるようにするメカニズムです。サービス検出により、Pod が再スケジュールされたり、新しい Pod が追加されたりしても、アプリケーションは常に最新の Pod IP アドレスにアクセスできます。GKE には、kube-dns、カスタム kube-dns デプロイ、Cloud DNS など、サービス ディスカバリを実装する複数の方法が用意されています。NodeLocal
DNSCache を使用すると、DNS パフォーマンスをさらに最適化できます。
サービス ディスカバリのメリット
サービス検出には次のような利点があります。
- アプリケーション管理の簡素化: サービス ディスカバリにより、アプリケーション構成で IP アドレスをハードコードする必要がなくなります。アプリケーションは、論理 Service 名を使用して通信します。この名前は、正しい Pod IP アドレスに自動的に解決されます。このアプローチにより、構成が簡素化されます。特に、スケーリングや再スケジューリングによって Pod の IP アドレスが変更される可能性がある動的環境で有効です。
- スケーリングと復元力の簡素化: サービス検出により、サービス コンシューマーを頻繁に変更される Pod IP アドレスから切り離すことで、スケーリングが簡素化されます。アプリケーションのスケール中や、Pod で障害が発生して置き換えられた場合、Kubernetes は、特定の Service のトラフィックを受信できる Pod を自動的に更新します。サービス ディスカバリは、安定した Service 名へのリクエストが正常な Pod にのみ転送されるようにします。これにより、アプリケーションは手動操作やクライアントの再構成なしで、スケーリングや障害からの復旧を行うことができます。
- 高可用性: GKE は、ロード バランシングとサービス ディスカバリを組み合わせて使用し、負荷が高い場合でも高可用性を確保し、アプリケーションの応答性を向上させます。
サービス ディスカバリによるロード バランシング
GKE は、さまざまなレベルのロード バランシングとサービス ディスカバリを組み合わせて、アプリケーションの高可用性を確保します。
- 内部サービス: クラスタ内でのみアクセス可能なサービスの場合、GKE のデータプレーン(
kube-proxyまたはCilium)がロードバランサとして機能します。受信トラフィックを複数の正常な Pod に均等に分散し、過負荷を防ぎ、高可用性を確保します。 - 外部サービス: クラスタの外部からアクセスする必要があるサービスの場合、GKE は Google Cloud ロードバランサをプロビジョニングします。これらのロードバランサには、パブリック インターネット アクセス用の外部 Google Cloud ロードバランサと、Virtual Private Cloud ネットワーク内のアクセス用の内部 Google Cloud ロードバランサが含まれます。これらのロードバランサは、クラスタ内のノード間でトラフィックを分散します。各ノードのデータプレーンは、トラフィックを適切な Pod に転送します。
内部シナリオと外部シナリオの両方で、サービス検出は各 Service の使用可能な Pod のリストを継続的に更新します。この継続的な更新により、データプレーン(内部サービス用)とロードバランサ(外部サービス用)の両方が、トラフィックを正常なインスタンスにのみ転送するようになります。 Google Cloud
サービス ディスカバリのユースケース
サービス ディスカバリの一般的なユースケースは次のとおりです。
- マイクロサービス アーキテクチャ: マイクロサービス アーキテクチャでは、アプリケーションは多くの場合、相互にやり取りする必要がある小規模で独立した多数のサービスで構成されます。サービス ディスカバリにより、クラスタがスケーリングされても、これらのアプリケーションは互いに検出して情報を交換できます。
- ゼロ ダウンタイム デプロイを有効にして復元力を向上させる: サービス ディスカバリにより、制御されたロールアウトやカナリア デプロイなど、アプリケーションのゼロ ダウンタイム アップデートが容易になります。新しいサービス バージョンの検出を自動化し、トラフィックを新しいサービス バージョンに移行します。これにより、デプロイ中のダウンタイムを短縮し、ユーザーの移行をスムーズに行うことができます。サービス ディスカバリは復元力も強化します。GKE で Pod が失敗すると、新しい Pod がデプロイされ、サービス ディスカバリが新しい Pod を登録してトラフィックをリダイレクトします。これにより、アプリケーションのダウンタイムを最小限に抑えることができます。
サービス ディスカバリの仕組み
GKE では、アプリケーションは多くの場合、互いに検出して通信する必要がある複数の Pod で構成されます。サービス ディスカバリは、ドメイン ネーム システム(DNS)を使用してこの機能を提供します。インターネット上のウェブサイトを見つけるために DNS を使用するのと同様に、GKE クラスタ内の Pod は DNS を使用して、サービス名を使用してサービスを特定し、接続します。このアプローチにより、クラスタ内の実行場所に関係なく Pod が効果的に連携し、アプリケーションは不安定な IP アドレスではなく一貫したサービス名を使用して通信できます。
Pod が DNS 解決を行う方法
GKE クラスタ内の Pod は、自動的に生成された DNS レコードとローカル DNS 構成の組み合わせを使用して、Service と他の Pod の DNS 名を解決します。
Service の DNS 名
Kubernetes Service を作成すると、GKE は DNS 名を自動的に割り当てます。この名前は予測可能な形式に従っており、クラスタ内の任意の Pod がこの名前を使用して Service にアクセスできます。
<service-name>.<namespace>.svc.cluster.local
デフォルトのクラスタ ドメインは cluster.local ですが、クラスタの作成時にドメインをカスタマイズできます。たとえば、デフォルトの Namespace で my-web-app という名前の Service の DNS 名は my-web-app.default.svc.cluster.local になります。
/etc/resolv.conf の役割
これらの DNS 名を解決するために、Pod は /etc/resolv.conf ファイルに依存します。この構成ファイルは、DNS クエリを送信するネームサーバーを Pod に指示します。このファイルにリストされているネームサーバーの IP アドレスは、GKE クラスタで有効になっている特定の DNS 機能によって異なります。次の表は、構成に基づいて Pod が使用するネームサーバー IP の概要を示しています。
| GKE 向け Cloud DNS | NodeLocal DNSCache | `/etc/resolv.conf` ネームサーバーの値 |
|---|---|---|
| 有効 | 有効 | `169.254.20.10` |
| 有効 | 無効 | `169.254.169.254` |
| 無効 | 有効 | `kube-dns` Service の IP アドレス |
| 無効 | 無効 | `kube-dns` Service の IP アドレス |
この構成により、Pod からの DNS クエリが正しいコンポーネントに転送されます。
- NodeLocal DNSCache: ノードで高速なローカル ルックアップを提供します。
- メタデータ サーバー IP(
169.254.169.254): NodeLocal DNSCache を使用せずに Cloud DNS for GKE が有効になっている場合に使用されます。DNS クエリはこの IP アドレスに転送され、Cloud DNS はこの IP アドレスを使用して DNS リクエストをインターセプトして処理します。 kube-dnsService IP アドレス: Cloud DNS for GKE が無効になっている場合、標準のクラスタ内解決に使用されます。
GKE の DNS アーキテクチャ
GKE は、主に DNS を使用して、サービス ディスカバリ用の柔軟なアーキテクチャを提供します。次のコンポーネントは連携して、クラスタ内の DNS クエリを解決します。
kube-dns: GKE Standard クラスタのデフォルトのクラスタ内 DNS プロバイダ。kube-systemNamespace の Pod のマネージド デプロイとして実行され、Kubernetes API で新しい Service を監視して、必要な DNS レコードを作成します。- Cloud DNS: Google Cloudのフルマネージド DNS サービス。
kube-dnsに代わる信頼性の高いスケーラブルな代替手段であり、GKE Autopilot クラスタのデフォルトの DNS プロバイダです。 NodeLocal DNSCache: DNS ルックアップのパフォーマンスを向上させる GKE アドオン。クラスタ内の各ノードで DNS キャッシュを実行し、kube-dnsまたは Cloud DNS のいずれかと連携して DNS クエリをローカルで処理します。これにより、レイテンシとクラスタの中央 DNS プロバイダの負荷が軽減されます。GKE Autopilot クラスタの場合、NodeLocal DNSCacheはデフォルトで有効になっており、オーバーライドできません。- カスタム
kube-dnsDeployment: 独自のkube-dnsインスタンスをデプロイして管理できる Deployment。kube-dnsの構成とリソースをより詳細に制御できます。
DNS プロバイダを選択する
次の表に、GKE で使用可能な DNS プロバイダと、その機能、各プロバイダを選択するタイミングの概要を示します。
| プロバイダ | 機能 | 選択するタイミング |
|---|---|---|
| `kube-dns` | Service と Pod のクラスタ内 DNS 解決。 | 標準のネットワーキングが必要なすべてのクラスタ。新しいバージョンの `kube-dns` は、小規模クラスタと大規模クラスタの両方に適しています。 |
| Cloud DNS | 高度な DNS 機能(プライベート ゾーン、トラフィック ステアリング、グローバル ロード バランシング)と、他の Google Cloud サービスとの統合。 | Service を外部に公開する場合、マルチクラスタ環境の場合、または DNS クエリ率(QPS)が高いクラスタの場合。 |
| カスタム `kube-dns` Deployment | 構成、リソース割り当て、代替 DNS プロバイダを使用する可能性をさらに制御できます。 | 大規模なクラスタ、またはより積極的なスケーリングやリソース割り当てのきめ細かい制御が必要な特定の DNS ニーズ。 |
単一クラスタの外部にあるサービス ディスカバリ
次の方法を使用すると、単一の GKE クラスタを超えてサービス ディスカバリを拡張できます。
Cloud DNS スコープ
クラスタ DNS に Cloud DNS を使用するクラスタは、次の 3 つのスコープのいずれかで動作できます。
- クラスタ スコープ: これは Cloud DNS のデフォルトの動作です。このモードでは、Cloud DNS は
kube-dnsと同等の機能を提供し、クラスタ内のリソース専用に DNS 解決を提供します。DNS レコードはクラスタ内からのみ解決でき、標準の Kubernetes Service スキーマ<svc>.<ns>.svc.cluster.localに準拠しています。 - 追加の VPC スコープ: このオプション機能は、Cloud VPN または Cloud Interconnect を使用して接続する Compute Engine VM やオンプレミス クライアントなど、同じ VPC ネットワーク内の他のリソースからヘッドレス サービスを解決できるようにすることで、クラスタ スコープを拡張します。
- VPC スコープ: この構成では、クラスタ Service の DNS レコードが VPC ネットワーク全体で解決されます。このアプローチでは、同じ VPC 内のクライアント、または(Cloud VPN または Cloud Interconnect 経由で)VPC に接続しているクライアントは、Service 名を直接解決できます。
VPC スコープの DNS の詳細については、GKE 向け Cloud DNS の使用をご覧ください。
マルチクラスタ サービス
マルチクラスタ サービス(MCS)を使用すると、複数の GKE クラスタ間でサービス ディスカバリとトラフィック管理が可能になります。MCS を使用すると、統合されたサービス エクスペリエンスを維持しながら、クラスタにまたがるアプリケーションを構築できます。
MCS は、DNS ベースのサービス ディスカバリを利用して、クラスタ間で Service を接続します。MCS インスタンスを作成すると、<svc>.<ns>.svc.clusterset.local 形式の DNS レコードが生成されます。これらのレコードは、参加している各クラスタの Service のエンドポイントの IP アドレスに解決されます。
1 つのクラスタ内のクライアントが MCS にアクセスすると、リクエストは参加しているクラスタの最も近い使用可能なエンドポイントにルーティングされます。このトラフィック分散は、各ノードの kube-proxy(GKE Dataplane V2 では Cilium)によって管理されます。これにより、クラスタ間の効率的な通信とロード バランシングが保証されます。
GKE 用 Service Directory
GKE 用 Service Directory は、Kubernetes と非 Kubernetes のデプロイ全体でサービス検出を行うための統合レジストリを提供します。Service Directory は、GKE と非 GKE の両方のサービスを 1 つのレジストリに登録できます。
Service Directory は、次のような場合に特に役立ちます。
- Kubernetes アプリケーションと Kubernetes 以外のアプリケーションを相互に検出可能にするための単一レジストリ。
- マネージド サービス ディスカバリ ツール。
- 他のクライアントからアクセス可能なサービスのメタデータを保存する機能。
- サービスレベルごとにアクセス権限を設定する機能。Service Directory サービスは、DNS、HTTP、gRPC を使用して解決できます。Service Directory は Cloud DNS と統合され、Service Directory 内のサービスに一致する Cloud DNS レコードを作成できます。
詳細については、GKE 用 Service Directory の構成をご覧ください。
DNS のパフォーマンスを最適化する
特に大規模なクラスタやトラフィックの多いクラスタで、信頼性が高く効率的なサービス検出を確保するには、次のベスト プラクティスと最適化戦略を検討してください。
NodeLocal DNSCache でパフォーマンスを最適化する
Pod の密度が高いクラスタや、大量の DNS クエリを生成するアプリケーションの場合は、NodeLocal DNSCache を有効にすることで DNS ルックアップの速度を向上させることができます。NodeLocal DNSCache は、クラスタ内の各ノードで DNS キャッシュを実行する GKE アドオンです。Pod が DNS リクエストを行うと、そのリクエストは同じノードにあるキャッシュに送信されます。このアプローチにより、レイテンシとネットワーク トラフィックが削減されます。
この機能を有効にして構成する方法については、NodeLocal DNSCache の設定をご覧ください。
DNS プロバイダをスケーリングする
kube-dns を使用していて、特にトラフィックが多い期間に断続的なタイムアウトが発生する場合は、kube-dns レプリカの数をスケーリングする必要があるかもしれません。kube-dns-autoscaler は、クラスタ内のノード数とコアの数に基づいてレプリカの数を調整します。パラメータを調整して、より多くのレプリカをより早くデプロイできます。
詳細な手順については、kube-dns のスケールアップをご覧ください。
一般的なベスト プラクティス
- 適切な DNS プロバイダを選択する: クラスタのニーズに基づいて DNS プロバイダを選択します。Cloud DNS は、高 QPS ワークロード、マルチクラスタ環境、より広範な VPC ネットワークとの統合が必要な場合におすすめします。新しいバージョンの
kube-dnsは、標準のクラスタ内サービス ディスカバリのニーズがある小規模から大規模までの幅広いクラスタに適しています。 kube-dnsに Spot VM またはプリエンプティブル VM を使用しない: Spot VM またはプリエンプティブル VM でkube-dnsなどの重要なシステム コンポーネントを実行しないことで、クラスタの DNS サービスの安定性を確保します。予期しないノードの終了は、DNS 解決の問題につながる可能性があります。- 明確でわかりやすいサービス名を使用する: サービスに一貫性のある意味のある命名規則を採用して、アプリケーション構成の読み取りと保守を容易にします。
- Namespace で整理する: Kubernetes Namespace を使用して、関連するサービスをグループ化します。このアプローチは、名前の競合を防ぎ、クラスタ リソースの整理を改善するのに役立ちます。
- DNS のモニタリングと検証: DNS の指標とログを定期的にモニタリングして、アプリケーションに影響が及ぶ前に潜在的な問題を特定します。Pod 内から DNS 解決を定期的にテストして、サービス ディスカバリが想定どおりに機能していることを確認します。
次のステップ
- GKE のクラスタ DNS の概要を読む。
- Kubernetes クラスタで DNS が使用される方法の概要について、Service と Pod の DNS で確認する。
- NodeLocal DNSCache を設定する方法を確認する。
- カスタム
kube-dnsDeployment を設定する方法を学習する。