Edited at

インターネット接続なしの完全にプライベートなGKEクラスター


こちらの記事は、2019年5月に公開された『 Completely Private GKE Clusters with No Internet Connectivity 』の和訳になります。



はじめに

Google Kubernetes Engine(GKE)クラスターをインターネットアクセスから分離する理由はいくつかありますが、主な理由はセキュリティです。多くの金融機関、政府機関、および同様の機関が、Google Cloud Platform(GCP)でワークロードを実行しています。

この投稿では、インターネットへのアクセスをブロックする、隔離されたネットワークでGKEクラスターを立ち上げるために必要な手順を説明します。


TL;DR


  1. プライベートGoogleアクセスを有効にしてGKEクラスターのVPCとサブネットを作成します。

  2. 送信時に0.0.0.0/0(全指定)でブロックするファイアウォールのルールでVPCをロックダウンし、Googleヘルスチェックからの受信を許可し、Googleヘルスチェック、制限されたAPI、およびGKEプライベートマスター範囲への送信を許可します。

  3. VPCで自動的に作成されたデフォルトルートを削除します(ネクストホップとしてデフォルトインターネットゲートウェイを指定しているルール)。デフォルトのインターネットゲートウェイを介してGoogle Restricted API(199.36.153.4/30)に到達するためのルートを作成します。

  4. 次のCloud DNSの変更を行い、ゾーンをVPCにアタッチします。


    • * .googleapis.comからrestrict.googleapis.comを引くためのCNAMEレコード、restricted.googleapis.comから199.36.153.4/30を引くためのAレコードをもつ、プライベートDNSゾーンgoogleapis.comを作成します。

    • * .gcr.ioからgcr.ioを引くためのCNAMEレコード、gcr.ioから199.36.153.4/30を引くためのAレコードをもつプライベートDNSゾーンgcr.ioを作成します。



  5. プライベートノードとプライベートマスターでGKEクラスターを作成します。


環境

image.png


段階的な展開

以降で利用可能なTerraformコード


VPCとサブネットを作成する

クラスターを作成する前に、クラスターに使用する環境にVPCとサブネットが必要です。それぞれのクラスターに3つのサブネットがあります。


  • ノードレンジ:GKEワーカーノードはこのサブネットに存在します。

  • クラスターレンジ:GKEはこの範囲を取得し、ノード間で分割します。デフォルトでは、各ノードはこの範囲から/ 24を取得しますが、 フレックスポッドCIDRを使用してカスタマイズできます。

  • サービスレンジ:クラスター内で実行されるクラスターIPサービスに使用されます。

クラスタとサービスのレンジは、ノードのプライマリレンジに対するセカンダリレンジとして構成されます。セカンダリレンジは、クラスターでエイリアスIPを構成するために使用されます。これにより、より良いSDNインテグレーションを実現します。これらの理由により、他の方法を使用せずに、別名IPサブネットを使用することをお勧めします。

gcloud compute networks create gke-no-internet-network \

--subnet-mode custom \
--bgp-routing-mode global

gcloud compute networks subnets create priv-cluster-01 \
--network gke-no-internet-network \
--range 10.10.10.0/24 \
--region us-central1 --enable-flow-logs \
--enable-private-ip-google-access \
--secondary-range services=10.10.11.0/24,pods=10.1.0.0/16


ファイアウォールのルールを作成する

VPCが作成されたら、それをロックダウンして、インターネットへのあらゆるタイプのアクセスを防止しましょう。デフォルトではすべての出力トラフィックが許可されているため、このトラフィックをブロックするルールを作成する必要があります。

gcloud compute firewall-rules create deny-egress \

--action DENY \
--rules all \
--destination-ranges 0.0.0.0/0 \
--direction EGRESS \
--priority 1100 \
--network gke-no-internet-network

次に、ヘルスチェックを実行するGoogleのIPアドレスへの入力/出力を許可しましょう。これらはGCPがノードが正常にスピンアップしたことを認識し、将来のロードバランサーまたはイングレスサービスのために許可される必要があります。

gcloud compute firewall-rules create allow-healthcheck-ingress \

--action ALLOW \
--rules tcp:80,tcp:443 \
--source-ranges 130.211.0.0/22,35.191.0.0/16 \
--direction INGRESS \
--network gke-no-internet-network

gcloud compute firewall-rules create allow-healthcheck-egress \
--action ALLOW \
--rules tcp:80,tcp:443 \
--destination-ranges 130.211.0.0/22,35.191.0.0/16 \
--direction EGRESS \
--network gke-no-internet-network

また、制限されたGoogle APIのVIPへトラフィックを許可する必要があります。これは、Googleサービスとの通信に使用され、GKE APIと通信するために必要です。

gcloud compute firewall-rules create allow-google-apis-egress \

--action ALLOW \
--rules all \
--destination-ranges 199.36.153.4/30 \
--direction EGRESS \
--network gke-no-internet-network

この次の出力ルールは、GKEワーカーノードから、ステップ#5で作成されるマスターノードへのトラフィックを許可します。クラスターを作成する前にこのルールを作成する必要があります。そうしないと、ワーカーノードがマスターノードに到達できなくなります。ここでは出力ルールのみが必要です。入力ルールは、クラスターの作成中にGCPによって自動的に作成されます。

gcloud compute firewall-rules create allow-master-node-egress \

--action ALLOW \
--rules tcp:443,tcp:10250 \
--destination-ranges 172.16.0.0/28 \
--direction EGRESS \
--network gke-no-internet-network

注:このVPCは現在、0.0.0.0/0へのすべての出力をブロックしています。内部IP空間(10.0.0.0/8、172.16.0.0/20、192.168.0.0/16)に向かうトラフィックには、クラスターがそれらのIPに到達できるようにするための追加の出力ルールが必要になります。


デフォルトルートを削除し、Google APIへのルートを作成する

VPCを作成すると、ネクストホップがdefault-internet-gatewayとしてインターネットへのデフォルトルート(0.0.0.0/0)が自動的に作成されます。インターネットへのパスを削除するために、このルートを削除する必要があります。GUIを使用して削除するのが最も簡単です。

次に、VPCでルートを作成して、制限されたGoogle APIサブネットにトラフィックを送信します。プライベートGoogle APIにアクセスするための要件に従って、ネクストホップをdefault-internet-gatewayとして設定する必要があります 。

「インターネットゲートウェイ」と言っても、実際にはトラフィックをインターネットに送信しません。サブネットで有効にしたプライベートGoogleアクセス機能のおかげで、トラフィックはGoogle APIへのプライベート内部パスを辿るようにルーティングされます。

gcloud compute routes create google-apis \

--destination-range 199.36.153.4/30 \
--next-hop-gateway default-internet-gateway \
--network gke-no-internet-network

image.png


Google APIおよびGCR.ioのDNSゾーンを作成します

次のステップとして、googleapis.comのVPCでDNSをカスタマイズします。googleapis.comはパブリックIPにて解決されるため、restricted.googleapis.comを使用する必要があります。

このURLは、GCPネットワーク内でアクセス可能な特定の範囲199.36.153.4/30に解決されます(前の手順でルートを作成した範囲と同じです)。GKEワーカーノードを正常に起動するためには、googleapis.comの代わりにrestricted.googleapis.comを使用する必要があります。

これは、GCP内のプライベートクラウドDNS機能を使用して実施できます。まず、Cloud DNSでgoogleapis.comのプライベートゾーンを作成します。

ゾーンが作成されたら、restricted.googleapis.comを指す* .googleapis.comのCNAMEレコードを追加します。この作業を行うためにはもう1つのレコード、restricted.googleapis.comの制限付きVIP IPを指すAレコードが必要です。

gcloud dns managed-zones create google-apis \

--description "private zone for Google APIs" \
--dns-name googleapis.com \
--visibility private \
--networks gke-no-internet-network

gcloud dns record-sets transaction start --zone google-apis

gcloud dns record-sets transaction add restricted.googleapis.com. \
--name *.googleapis.com \
--ttl 300 \
--type CNAME \
--zone google-apis

gcloud dns record-sets transaction add "199.36.153.4" \
"199.36.153.5" "199.36.153.6" "199.36.153.7" \
--name restricted.googleapis.com \
--ttl 300 \
--type A \
--zone google-apis

gcloud dns record-sets transaction execute --zone google-apis

GCR.ioドメインに対して同様の設定を行い、コンテナレジストリに到達するためにトラフィックを制限されたGoogle APIサブネットに送信する必要があります。これらの変更がないと、GKEクラスターは、必要なすべてのコンテナをプルダウンできないため、正常に起動しません。

gcloud dns managed-zones create gcr-io \

--description "private zone for GCR.io" \
--dns-name gcr.io \
--visibility private \
--networks gke-no-internet-network

gcloud dns record-sets transaction start --zone gcr-io

gcloud dns record-sets transaction add gcr.io. \
--name *.gcr.io \
--ttl 300 \
--type CNAME \
--zone gcr-io

gcloud dns record-sets transaction add "199.36.153.4" "199.36.153.5" "199.36.153.6" "199.36.153.7" \
--name gcr.io \
--ttl 300 \
--type A \
--zone gcr-io

gcloud dns record-sets transaction execute --zone gcr-io


GKEクラスターを作成する

ネットワークといくつかのサブネットができたので、プライベートGKEクラスターを作成しましょう。クラスターを作成するときに調整する箇所は多数ありますが、プライベートIPのみを使用してワーカーノードとマスターノードを作成するために必要なものはわずかです。次の設定を確認します。


  • VPCネイティブの有効化

  • プライベートクラスタノードの有効化

  • 外部IPアドレスを使用したマスターへのアクセスを無効化

gcloud beta container clusters create private-gke-cluster \

--zone "us-central1-a" \
--enable-private-nodes \
--enable-private-endpoint \
--master-ipv4-cidr "172.16.0.0/28" \
--enable-ip-alias \
--network "projects/<project_id>/global/networks/gke-no-internet-network" \
--subnetwork "projects/<project_id>/regions/us-central1/subnetworks/priv-cluster-01" \
--cluster-secondary-range-name "pods" \
--services-secondary-range-name "services" \
--enable-master-authorized-networks


プライベートクラスタがデプロイされました!

すべてがプランどおりに進んだ場合、クラスターはすべてのワークロードとサービスが正常な状態で起動するはずです。この記事の設定で問題が発生した場合は、Twitterでご連絡ください。お手伝いさせていただきます。


Terraform

本記事の手順をスキップしてすぐに起動したい場合は、次のGithubリポジトリで利用可能なterraform構成ファイルがあります。

https://github.com/andreyk-code/no-inet-gke-cluster.git


翻訳協力

Author: Andrey Kumanov

Thank you for letting us share your knowledge!

記事選定: @takitakis

翻訳/技術監査: @aoharu / @azumana

Markdown化: @aoharu


ご意見・ご感想をお待ちしております

今回の記事は、いかがだったでしょうか?

・こうしたら良かった、もっとこうして欲しい、こうした方が良いのではないか

・こういったところが良かった

などなど、率直なご意見を募集しております。

いただいたお声は、今後の記事の質向上に役立たせていただきますので、お気軽にコメント欄にてご投稿ください。Twitterでもご意見を受け付けております。

みなさまのメッセージをお待ちしております。