はじめに
こんにちは、IT 基盤部ネットワークグループの守屋です。 ネットワーク全般 ( Cloud / DataCenter / オフィス ) の設計・構築・運用・保守を担当しています。 今回は、DeNA での GCP ネットワーク運用についてお話しさせて頂きます。 GCP のネットワークについては、 以前にも 記事を書いていますが、 今回は2年ほど運用してみてわかった Shared VPC を運用する上でのノウハウを中心に記載します。
Google Cloud Shared VPC について
Google Cloud Shared VPC を導入した背景
Shared VPC は Shared VPC 内に作成した Subnet の利用権限を別プロジェクトに付与することができるサービスです。 これにより Cloud VPN を含む VPC 関連のリソースは Shared VPC によって一元管理することができ、 利用者は管理された VPC 内で GCE や GKE を利用することができます。 つまり、GCP と他の DeNA リソース間の通信を一元的に管理できるサービスとなります。
GCP と他の DeNA リソース間の通信させる別の方法としては、通信が必要なプロジェクトごとに VPN や Interconnect などを設定するという方法もあります。 この方法は、小規模ネットワークであれば運用することは可能だと思いますが、 DeNA のように GCP 内に多くのプロジェクトが存在する場合は運用コストが膨大となるため、現実的ではありません。 そのため、DeNA では、ネットワークグループで管理するプロジェクトに VPN と Shared VPC を設定し、 各プロジェクトは、Shared VPC を経由して、GCP 以外の DeNA のリソースにアクセスできるネットワーク構成を採用しています。
Google Cloud Shared VPC の構成
Shared VPC の構成としては、下図のようになります。 各プロジェクトとサービスは Shared VPC または、サーバレス VPC アクセスコネクタと接続し、 GCP 以外の DeNA リソースにアクセスできるようになっています。
GCP の各サービスとは接続方法は以下となります。 接続方法の詳細については、後述します。
サービス | 接続方法 | 備考 |
---|---|---|
Google Compute Engine | Shared VPC | - |
Google Kubernetes Engine | Shared VPC | 共有するサブネットに制約あり |
サーバレスサービス | サーバレス VPC アクセスコネクタ | Shared VPC のサブネットを サーバレス VPC アクセスコネクタで使用する |
AWS Transit Gateway との比較
以前にも 記事にしましたが、 DeNA では、AWS のネットワーク管理に AWS Transit Gateway ( AWS TGW ) というサービスを利用しています。 TGW とは、AWS 上に構築するクラウドルータのようなサービスで VPC 、オンプレ、 他クラウドサービスとのネットワーク接続を一元的に管理することができます。 TGW を利用することによって、ネットワークが簡素化され、VPC 間の複雑なピア接続関係をなくすことができます。
AWS を運用している方も多いと思いますので、簡単にではありますが、 AWS TGW と GCP Shared VPC の運用で意識する主な違いを以下の表に記載します。
AWS TGW | GCP Shared VPC | |
---|---|---|
アクセス制限 | 各プロジェクトで定義 | ホストプロジェクトで定義 |
プロジェクト間の接続方法 | VPC を TGW に接続する | サービスによって異なる |
1つ目の大きな違いとしては、アクセス制限の方法となります。 AWS Transit Gateway では、各プロジェクトの VPC でセキュリティグループを定義してアクセス制限をすることができます。 一方、GCP Shared VPC の場合は、ホストプロジェクト ( VPC を共有する側のプロジェクト) 側で Firewall Rule を定義する必要があります。 DeNA で具体的にどのように管理をしているかは後述します。
2つ目の違いとしては、各プロジェクトの接続方法となります。 AWS TGW では、各プロジェクトの VPC を TGW に接続して対応します ( AWS TGW の設定方法についての詳細は、 AWS のドキュメント をご参照ください )。 前述しましたが、GCP Shared VPC の場合は、使用するサービスによって接続方法が異なり、 使用するサービスにあわせて適切なものを選択する必要があります。 各サービスごとの接続方法については後述します。
Google Compute Engine との接続
Google Compute Engine ( GCE ) を接続する場合、Shared VPC を設定することで他プロジェクトと VPC を共有することができます。 当初は、Google が提供しているドキュメントに従い、Shared VPC を設定していたのですが、 運用をしている中で以下の2点問題があることがわかりました。
- サービスプロジェクトで、VPC 内の全サブネットが使用可能になってしまう
- Firewall Rule をホストプロジェクト側で定義する必要がある
1 については、GCP の組織ポリシーの制約を利用することで解決できました。組織ポリシーの「共有 VPC サブネットワークの制限」を設定することで、 サービスプロジェクト ( VPC を共有される側のプロジェクト ) からアクセスできるサブネットを制限すること可能となりました。 「共有 VPC サブネットワークの制限」の詳細については こちら をご参照ください。
2 については、当初はネットワークチームで各事業部から依頼を受けて Firewall Rule を全て設定して対応していました。 しかし、GCP の Firewall Rule が増加した場合、運用が破綻することは予想できました。 そのため、Firewall Rule の管理を Terraform で行うようにし、 一部の Firewall Rule のコンフィグ管理を事業部に移管することで対応しました。
ただし、Firewall Rule の変更権限を各事業部に付与するのはセキュリィ的に問題があります。 各事業部に Firewall Rule の変更権限を付与した場合、 Shared VPC を利用するすべてのユーザが Firewall Rule を変更することができるようになります。 例えば、無関係プロジェクトへの全通信を拒否してサービスを停止させるということも可能になります。 したがって、GCP への Firewall Rule を変更、反映できるのはネットワークチームのみにしています。 具体的には、Firewall Rule の設定変更が必要になった場合、 ネットワークチーム宛に Github のプルリクエストを出して頂き、 ネットワークチームでレビュー、マージ、デプロイして Firewall Rule を変更するという運用にしています。
ホストプロジェクトとサービスプロジェクトの GCE の接続イメージは下図となります。 Shared VPC 内のサブネットをサービスプロジェクトにアサインします。
Google Kubernetes Engine との接続
Google Kubernetes Engine ( GKE ) との接続は、基本的に GCE と同じですが、 以下の2点に注意する必要があります。
- GKE 用のサブネットは、セカンダリIPを定義する必要がある
- Shared VPC 以外と通信させたい場合は VPC Peering で経路を広報する必要がある
1 については、GKE では、Pod、Service、Node 用にそれぞれセグメントを同一サブネットでアサインする必要があります。 Shared VPC 接続時に、Node 用のセグメントはプライマリ IP アドレス、Pod、 Service 用のセグメントはセカンダリ IP アドレスで定義したサブネットを サービスプロジェクトに共有することで、GKE で Shared VPC を利用できるようになります。 GKE クラスタでプライベートエンドポイントを使用する場合は、サブネットでPrivate Google Access を有効にし、 追加でエンドポイント用のセグメントをアサインする必要がありますが、 このセグメントは Shared VPC に定義されているサブネットと重複しない範囲から払い出す必要があります。 Pod、Service、Node で使用するセグメントには制約があるので、 詳しくは こちら をご参照ください。
2 については、GKE を Shared VPC 以外のネットワークと通信させたい場合に考慮する必要があります。 Shared VPC 上で GKE クラスタを作成した場合、自動で VPC Peering の設定が追加されますが、 デフォルトだと、Shared VPC のサブネットしか GKE クラスタへ広報されません。 GCP 以外のネットワーク ( e.g. オンプレ、AWS のネットワーク ) と通信させたい場合は、VPC Peering で「カスタムルートをエクスポート」するように設定し、 ホストプロジェクト内で設定したルートを Peering 先の GKE に広報する必要があります。 GKEクラスタのプライベートエンドポイントにアクセスする場合は、上記に加えて、GKE クラスタ設定でアクセス元のセグメントを 「承認済みネットワーク」へ追加する必要があります。
ホストプロジェクトとサービスプロジェクトの GKE の接続イメージは下図となります。 GKE クラスタの Pod、Service、Node を Shared VPC 内に作成し、 GKE クラスタとホストプロジェク間は VPC Peering で接続します。
サーバレスサービスとの接続
Google Cloud Functions などのサーバレスサービスを接続する場合、 ホストプロジェクトで Shared VPC のサブネットを使用してサーバレス VPC アクセスコネクタを作成し、 サービスプロジェクト内のサーバレスサービスで サーバレス VPC アクセスコネクタを指定して接続します。 サーバレス VPC アクセスコネクタを使用してサーバレスサービスを接続する場合は、以下の4点に注意する必要があります。
- サーバレス VPC アクセスコネクタ用の Firewall Rule を定義する必要がある
- Shared VPC の設定をする必要がある
- 各サービスごとに適切な IAM をアサインする必要がある
- 未対応のサービスがある
1 については、サーバレス VPC アクセスコネクタを使用する際の制約となります。 設定する Firewall Rule については、 こちら をご参照ください。
2 については、ホストプロジェクトで作成した サーバレス VPC アクセスコネクタをサービスプロジェクトで使用する際の制約となります。 ホストプロジェクトは Shared VPC のサブネットを指定して サーバレス VPC アクセスコネクタを作成する必要があります。 Shared VPC の設定がないと、サービスプロジェクトは Shared VPC のサブネットにあるサーバレス VPC アクセスコネクタにアクセスできません。 そのため、サービスプロジェクトで GCE や GKE を使用しない場合でも、ホストプロジェクトと Shared VPC を接続する必要があります。
3 については、サービス毎に適切な IAM をアサインします。 例えば、Google Cloud Function では、「Cloud Function サービスエージェント」をアサインする必要があります。 アサインする IAM については、各サービスの Google のドキュメントをご参照ください。
4 についてですが、2022 年 4月時点では、サーバレス VPC アクセスコネクタに未対応のサーバレスサービスがあります。 サーバレス VPC アクセスコネクタに対応しているサーバレスサービスについては、 こちら をご参照ください。
ホストプロジェクトとサービスプロジェクトのサーバレスサービスの接続イメージは下図となります。 ホストプロジェクトの Shared VPC 内のサブネットを指定して サーバレス VPC アクセスコネクタを作成し、 サービスプロジェクトのサーバレスサービスで作成した サーバレス VPC アクセスコネクタを指定して接続します。
おわりに
以上、DeNA での GCP ネットワーク運用のノウハウをご紹介させていただきました。 AWS や GCP などのクラウドネットワーク運用に関しては、 オンプレのネットワーク運用と比較するとまだまだ歴史が浅い分野であり、 技術のアップデートが早い分野でもあります。 運用当初は適切な構成であっても、時間が経過すると陳腐化してしまいます。 実際問題、レガシーになってしまった機能や機能のアップデートにより、 一部不適切になってしまったネットワーク構成の改善が課題としてあります。 そのため、日々の技術のキャッチアップが重要になります。 本ブログは 2022 年 5 月時点の GCP ネットワーク運用のノウハウとなりますが、 こちらの内容が少しでも皆様のお役に立てましたら幸いです。
最後まで読んでいただき、ありがとうございます!
この記事をシェアしていただける方はこちらからお願いします。