[!] この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
クラウドのマネージドKubernetesサービスであるAmazon EKSでプライベートクラスターを構築し、社内で使用しているシステムを移行したことを以前の記事で紹介しました。クラウドベンダーごとにマネージドKubernetesサービスは存在し、GCPではGoogle Kubernetes Engine(GKE)が提供されています。コンテナの操作はどのサービスを利用しても同じですが、ネットワークやセキュリティなどの部分はクラウドが提供するサービスを利用することになるため、ベンダーごとに違ってきます。そこで、すでに利用中のAmazon EKSと比較するために、GKEについても検証してみることにしました。
GCPに構築した仮想ネットワークには、AWSと同じように以下の特徴があります。
- VPN接続しているオンプレミスネットワークからのみアクセス可能
- インターネットへのアクセスはプロキシ経由
このネットワークにGKEクラスターを構築するためには、やはり注意すべき事項が何点かありました。そこで、この記事ではインターネットから隔離された、プライベートなGKEクラスターを構築する方法を紹介します。なお、GCPやKubernetesの基礎知識はすでにあるものとします。
クラスターネットワークの選択
GKEクラスターは、あるPodから別のPodにトラフィックをルーティングする方法で大別できます。エイリアスIP範囲を使用するクラスターは、「VPCネイティブクラスター」と呼ばれ、Google Cloudのルートを使用するクラスターは、「ルートベースクラスター」と呼ばれています。「VPCネイティブクラスター」にはさまざまなメリット ⧉があるため、今回は、「VPCネイティブクラスター」を作成します。
VPCネイティブクラスターを作成する場合、VPC内のサブネットを指定します。クラスターでは3つの固有のサブネットIP範囲を使用します。
- ワーカーノードのIPアドレスに、サブネットのプライマリIP範囲を使用
- PodのIPアドレスに、セカンダリIP範囲を使用
- ServiceのCluster IPアドレスに、別のセカンダリIP範囲を使用
限定公開のGoogleアクセスの設定
限定公開のGoogleアクセスによって、ワーカーノードは、Googleのプライベートネットワークを経由してGoogleのAPIやサービスにアクセスできます。これによりインターネットへのアクセスができなくても、Google Container Registry(GCR)からコンテナイメージを取得したり、Cloud Loggingにログを送信したりできるようになります。限定公開のGoogleアクセスを有効化するために以下の作業を行います。
DNSレコードの作成
限定公開のGoogleアクセスが有効になっても、GoogleのAPIやサービスを利用する際のドメイン名がインターネットからルーティングされるIPアドレス範囲に名前解決されるのは変わりません。そこで、ドメインの名前解決がGoogle Cloud内からのみルーティング可能なアドレス範囲に行われるように変更します。
Google APIとサービスにアクセスできるドメインは、デフォルトドメインの他に以下の2つがあります。
- restricted.googleapis.com
- 仮想IPアドレスの範囲:199.36.153.4/30
- VPC Service ControlsをサポートするCloud APIとDeveloper APIにのみアクセスできる
- Google WorkspaceウェブアプリケーションやGoogle Workspace APIはサポートしていない
- private.googleapis.com
- 仮想IPアドレスの範囲:199.36.153.8/30
- ほとんどのGoogle APIやサービス(VPC Service ControlsをサポートしていないCloud APIとDeveloper APIを含む)にアクセスできる
- マップ、Google広告、GCP、末尾が「googleapis.com」のドメイン名であるGoogle APIへのアクセスが含まれる
- Google Workspaceウェブアプリケーションはサポートしていない
VPC Service ControlsでサポートされていないGoogle APIおよびサービスにアクセスする必要がない限り、「*.googleapis.com」のDNSリクエストを「restricted.googleapis.com」に送信することが推奨されているので、今回はアドレス範囲「199.36.153.4/30」に転送します。これは、Cloud DNSを使用することで実現できます。また、GCRからコンテナイメージを取得するためには、「gcr.io」へのDNSリクエストも同じアドレス範囲に転送できるように設定する必要があります。
その後、「restricted.googleapis.com」へのルートを作成し、ファイアウォールで外向き(下り)トラフィックを許可します。ルートを作成する際、各ルートのネクストホップに「default Internet gateway」を設定する必要があることに注意してください。
最終的なネットワーク構成図は、以下のようになりました。
限定公開のGoogleアクセスの有効化
限定公開のGoogleアクセスは、サブネット単位で有効化します。使用するサブネットの編集画面に移動し、限定公開のGoogleアクセスを有効化します。
限定公開クラスターの作成
GKEクラスターを作成すると、デフォルトでは「一般公開クラスター」が構成されます。この場合、ワーカーノードは外部IPアドレスを持ってしまい、今回の目的に適していません。そこで、「一般公開クラスター」ではなく「限定公開クラスター」として構成します。これにより、作成されたワーカーノードは内部IPアドレスしか持たなくなります。そして、「限定公開クラスター」の有効化と合わせて、「外部IPアドレスを使用したマスターへのアクセス」を無効化することで、インターネットからのアクセスを遮断できます。
GKEクラスターを作成すると、以下のリソースが自動的に作成されます。
- VPCネットワークピアリング
- 名前が「gke-」から始まり「-peer」で終わるVPCネットワークピアリング
- ワーカーノードが存在するVPCとマスターが存在するVPCを接続する
- ファイアウォールのルール
- ヘルスチェックを実行するGoogleのIPアドレス範囲(プローブIP範囲)からのトラフィックを許可する
- ワーカーノードの起動処理が正常に完了したことを確認するために利用
- LoadBalancer Service(L4ロードバランサー)、Ingress(L7ロードバランサー)のために、あらかじめ接続を許可する必要がある
オンプレミスネットワークからKubernetes APIへのアクセス
ワーカーノードからマスターへの通信は作成されたVPCネットワークピアリングを経由して行います。また、kubectl
コマンドでKubernetes APIサーバーにアクセスする際も、このVPCネットワークピアリングを経由する必要があるため、現状の構成ではワーカーノードがホストされたVPC内からkubectl
コマンドを実行しなければなりません。VPN接続されたオンプレミスネットワークから実行できるようにするためには、以下を実施します。
VPCネットワークピアリングの修正
- GKEクラスターと同時に作成されたVPCネットワークピアリングを編集する
- 「カスタムルートをエクスポートする」を有効化
クラウドルーターの修正
- オンプレミスとのVPN接続に使用しているクラウドルーターを編集する
- 「カスタムルートの作成」を選択し、マスターに付与したIPアドレス範囲を追加する
GKEクラスターの修正
- GKEクラスターの設定を編集する
- マスター承認済みのネットワークにオンプレミスネットワークのIPアドレス範囲を追加する
これで、オンプレミスネットワークに対してマスターが存在するVPCのIPアドレス範囲のルートが伝播されます。オンプレミスとマスターの間に経路が確立し、オンプレミスネットワークからKubernetes APIサーバーにアクセスすることが可能になります。
クラスター設定ファイルの取得
kubeconfigファイルはgcloud container clusters get-credentials
コマンドを使用して入手できます。限定公開クラスターには、内部IPアドレスと外部IPアドレスの2つのエンドポイントが存在し、--internal-ip
オプションを付けることで、外部IPアドレスではなく、内部IPアドレスのエンドポイントへ接続するように設定されます。今回は外部IPアドレスを使用したマスターへの接続を無効化しているので、このオプションが付いていないと正常にkubeconfigファイルを取得できないので注意してください。
C:>gcloud container clusters get-credentials <cluster_name> --zone <zone_name> --project <gcp_project_id> --internal-ipp
Fetching cluster endpoint and auth data.
kubeconfig entry generated for kikaku.
これにより、kubectlコマンドでGKEクラスターへ接続できるようになりました。動作確認としてkubectl get node
を実行してみると、以下のような結果が出力されたので、正常にアクセスできていることがわかります。
C:\>kubectl get node
NAME STATUS ROLES AGE VERSION
gke-alpha-cluster-default-pool-0f94de4e-q34p Ready <none> 6m2s v1.16.11-gke.5
gke-alpha-cluster-default-pool-86ae4b0f-l0tz Ready <none> 6m4s v1.16.11-gke.5
まとめ
今回もインターネットへのアクセスが存在しない、完全にプライベートなKuberntesサービスを構築する方法を紹介しました。Amazon EKSとGKEの両方を利用してみた感想ですが、Kubernetesクラスターを速く構築できたり、コンソール画面からKubernetesリソース状態を管理できたりするので、GKEの方が使いやすいと感じました。なお、その後のアップデートで、Amazon EKSでもコンソール画面からリソース状態の確認まではできるようになりました。
また、私たちはAmazon EKSとGKEを利用してみましたが、Azure Kubernetes Service(AKS)やOracle Container Engine for Kubernetes(OKE)など、他にもクラウドベンダーによるマネージドKubernetesサービスは存在します。Kubernetesに興味のある方は、さまざまなマネージドKubernetesサービスをぜひ試してみてください。