セキュリティの概要

Google Kubernetes Engine(GKE)では、さまざまな方法でワークロードを保護できます。GKE でワークロードを保護するには、コンテナ イメージのコンテンツ、コンテナのランタイム、クラスタ ネットワーク、クラスタ API サーバーへのアクセスなど、何層ものスタックを考慮する必要があります。

クラスタとワークロードの保護には、階層的なアプローチをおすすめします。ユーザーとアプリケーションのアクセスレベルは、最小権限の原則に従って決定します。ワークロードのデプロイとメンテナンスを安全に行うためには柔軟性とセキュリティのバランスを適切に取る必要がありますが、このバランスは階層によって異なります。たとえば、一部のセキュリティ設定は特定の種類のアプリケーションにとって制限が多すぎたり、大幅にリファクタリングしないと使用目的に適合しなかったりする場合があります。

このドキュメントでは、インフラストラクチャの各レイヤの概要と、ニーズに合わせて最適なセキュリティ機能を構成する方法について説明します。

認証と承認

Kubernetes は次の 2 種類の認証をサポートしています。

  1. ユーザー アカウントは、Kubernetes で認識はされますが、Kubernetes では管理されないアカウントです。このため、たとえば、kubectl を使用した作成や削除はできません。
  2. サービス アカウントは、Kubernetes によって作成と管理は行われますが、Kubernetes によって作成されたエンティティ(Pod など)でしか使用できないアカウントです。

GKE クラスタでは、Kubernetes ユーザー アカウントは Google Cloud で管理され、次の 2 種類のいずれかになります。

  1. Google アカウント
  2. Google Cloud サービス アカウント

認証後、それらの ID に Kubernetes リソースの作成、読み取り、更新、削除を許可する必要があります。

Kubernetes サービス アカウントと Google Cloud サービス アカウントは、名前は同じでも異なるエンティティです。Kubernetes サービス アカウントは、クラスタの一部として定義され、通常はそのクラスタ内で使用されます。それに対し、Google Cloud サービス アカウントは Google Cloud プロジェクトの一部であり、クラスタ内における権限だけでなく、Google Cloud プロジェクトのクラスタ自体に対する権限も簡単に付与できます。また、Identity and Access Management(IAM)を使用して、すべての Google Cloud リソースに対しても権限も付与できます。このため、Google Cloud サービス アカウントは Kubernetes サービス アカウントよりも強力です。セキュリティの最小権限の原則に従うために、Google Cloud サービス アカウントの使用はその機能が必要な場合のみにする必要があります。

クラスタレベルや Kubernetes Namespace 内で Kubernetes リソースへのアクセス権限を詳細に構成するには、ロールベースのアクセス制御(RBAC)を使用します。RBAC では、詳細なポリシーを作成して、ユーザーとサービス アカウントがアクセス可能なオペレーションとリソースを定義できます。RBAC を使用すると、Google アカウント、Google Cloud サービス アカウント、Kubernetes サービス アカウントへのアクセスを制御できます。GKE の認証と認可の戦略をさらに簡略化、合理化するには、以前の属性ベースのアクセス制御を無効にすることで、Kubernetes RBAC と IAM を信頼できる情報源とします。

詳細については、以下をご覧ください。

コントロール プレーンのセキュリティ

GKE では、Kubernetes のコントロール プレーン コンポーネントは Google によって管理と保守が行われます。コントロール プレーン コンポーネントは、API サーバー、スケジューラ、コントローラ マネージャー、Kubernetes 構成が保持されている etcd データベースなどの Kubernetes コントロール プレーンを実行するソフトウェアをホストします。

デフォルトでは、コントロール プレーン コンポーネントはパブリック IP アドレスを使用します。承認済みのネットワーク限定公開クラスタを使用することで Kubernetes API サーバーを保護できます。限定公開のクラスタでは、コントロール プレーンにプライベート IP アドレスを割り当て、パブリック IP アドレスからのアクセスを遮断できます。

IAM を ID プロバイダとして使用すると、Google Kubernetes Engine でクラスタ認証を処理できます。認証については、Kubernetes API サーバーの認証をご覧ください。

定期的に認証情報をローテーションすると、コントロール プレーンの保護を強化できます。認証情報のローテーションを開始すると、SSL 証明書とクラスタ認証局がローテーションされます。これは GKE によって自動的に行われ、コントロール プレーンの IP アドレスが確実にローテーションされます。

詳細については、以下をご覧ください。

ノードのセキュリティ

GKE は、Google Cloud プロジェクトで実行されている Compute Engine インスタンスにワークロードをデプロイします。これらのインスタンスは、ノードとして GKE クラスタに接続されています。次のセクションでは、Google Cloud で使用可能なノードレベルのセキュリティ機能の使用方法を説明します。

Container-Optimized OS

GKE ノードのデフォルトでは、Kubernetes とそのコンポーネントを実行するオペレーティング システムとして Google のコンテナ用に最適化された OS が使用されています。Container-Optimized OS には GKE クラスタのセキュリティを強化する高度な機能が複数実装されています。その例を次に示します。

  • ファイアウォールの遮断
  • 読み取り専用ファイルシステム(可能な場合)
  • 制限付きユーザー アカウントと root ログインの無効化

ノードのアップグレード

OS には定期的にパッチを適用することをおすすめします。コンテナのランタイム、Kubernetes 自体、ノードのオペレーティング システムのセキュリティに問題が発生すると、ノードの緊急アップグレードが必要となる場合があります。ノードをアップグレードすると、ノードのソフトウェアは最新バージョンになります。

クラスタ内のノードは手動でアップグレードできますが、GKE では自動アップグレードを有効にすることもできます。

ノードを信頼できないワークロードから保護する

不明または信頼できないワークロードを実行するクラスタでは、ポッド内で実行される信頼できないワークロードからノードのオペレーティング システムを保護することをおすすめします。

たとえば、Software-as-a-Service(SaaS)プロバイダなどのマルチテナント クラスタは、ユーザーから送信された不明なコードを実行することも珍しくありません。セキュリティ調査も、ワークロードに対してノードのデフォルトよりも強力な隔離が必要になる可能性があるアプリケーションの 1 つです。

GKE Sandbox をクラスタで有効にすると、信頼できないワークロードをノード上のサンドボックス内に隔離できます。GKE Sandbox は、オープンソースのプロジェクトである gVisor を使用して構築されています。

インスタンス メタデータの保護

GKE ノードは Compute Engine インスタンスとして実行されるため、デフォルトでインスタンス メタデータへのアクセス権限を持ちます。インスタンス メタデータからは、ブートストラップやコントロール プレーン ノードへの接続に使用される認証情報と構成がノードに提供されます。ただし、ノード上で実行されている Pod では、ノードのサービス アカウント キーなどの機密データが含まれるこの情報は必ずしも必要ではありません。従来の API を無効化しメタデータ隠蔽を使用すると、インスタンスの機密メタデータへのパスを遮断できます。メタデータ隠蔽により kube-env などのフィールドに対するリクエストがフィルタリングされ、クラスタ内で実行されているポッドは機密データにアクセスできなくなります。

ネットワーク セキュリティ

GKE で実行されているワークロードの大部分は、クラスタの内部または外部で実行されている他のサービスと通信する必要があります。クラスタやその Pod を流れるトラフィックを制御する方法は、複数あります。

ポッド間の通信を制限する

デフォルトでは、クラスタ内のすべてのポッドはポッドの IP アドレスを使用してネットワークにアクセスできます。同様に、デフォルトでは、クラスタがデプロイされている VPC 内の任意のアクセス可能なアドレスへの送信接続が下り(外向き)トラフィックにより許可されます。

クラスタ管理者とユーザーは、ネットワーク ポリシーを使用すると、Namespace 内の Pod への上り(内向き)接続やその Pod からの下り(外向き)接続を遮断できます。デフォルトでは、ネットワーク ポリシーが定義されていない場合、ポッドへのすべての入力トラフィックとポッドからのすべての出力トラフィックが許可されます。ネットワーク ポリシーを使用すると、タグを使用して Pod を流れるトラフィックを定義できます。

名前空間でネットワーク ポリシーが適用されると、ポッドからのトラフィックとポッドへのトラフィックのうち、構成されたラベルと一致しないものはすべてドロップされます。クラスタや名前空間を作成するときにすべてのポッドで受信トラフィックと送信トラフィックをデフォルトで拒否するように設定すると、クラスタに新しいワークロードを追加した場合に明示的にトラフィックを承認することが必要になります。

詳細については、以下をご覧ください。

負荷分散されたトラフィックのフィルタリング

Kubernetes Pod でネットワーク ロードバランサを使用して負荷分散を行うには、タイプ LoadBalancer が Pod のラベルと一致する Service を作成する必要があります。サービスを作成すると外部接続用 IP が取得され、Kubernetes ポッドのポートにマッピングされます。承認済みのトラフィックのフィルタリングは、IP アドレスに基づいて kube-proxy がノードレベルで行います。

このフィルタリングは、Service オブジェクトの loadBalancerSourceRanges 構成で指定します。この構成パラメータでは、Service へのアクセスを許可する CIDR 範囲のリストを指定できます。loadBalancerSourceRanges を構成しない場合は、すべてのアドレスが外部 IP 経由で Service にアクセスできます。

Service への外部アクセスが不要な場合は、内部ロードバランサの使用を検討してください。VPC 内部からのトラフィックをフィルタリングする必要がある場合は、loadBalancerSourceRanges も内部ロードバランサに適用されます。

詳細については、内部負荷分散のチュートリアルをご覧ください。

ワークロードの保護

Kubernetes では、コンテナベースのワークロードのプロビジョニング、スケーリング、更新を迅速に行うことができます。このセクションでは、管理者やユーザーが実行中のコンテナを制御し、同じクラスタ内の他のコンテナ、コンテナが実行されるノード、ユーザーのプロジェクトで有効になっている Google Cloud サービスに対するそのコンテナの影響範囲を制限する方法について説明します。

Pod コンテナのプロセス権限を制限する

コンテナ化されたプロセスの権限を制限することは、クラスタの全体的なセキュリティにとって重要です。GKE では、Pod とコンテナの両方でセキュリティ コンテキストを使用してセキュリティ関連のオプションを設定できます。この設定では、次のようにプロセスのセキュリティ設定を変更できます。

  • 実行するユーザーとグループ
  • 利用可能な Linux 機能
  • 権限を昇格させる能力

これらの設定を Pod やコンテナではなくクラスタレベルで変更するには、PodSecurityPolicy を実装する必要があります。クラスタ管理者が PodSecurityPolicy を使用すると、クラスタ内のすべての Pod に、ここで定義された最小限のベースライン ポリシーを遵守させることができます。

GKE ノードでは、Container-Optimized OS と Ubuntu のどちらのオペレーティング システムが使用されている場合でも、Kubernetes で起動されたすべてのコンテナにデフォルトの Docker AppArmor セキュリティ ポリシーが適用されます。プロファイルのテンプレートは GitHub で確認できます。特に、次のプロファイルではコンテナに対する以下の機能が拒否されます。

  • /proc/ 内のファイルに直接書き込む
  • プロセス ID ディレクトリ(/proc/<number>)内に存在しないファイルに書き込む
  • /proc/sys 内に存在する /proc/sys/kernel/shm* 以外のファイルに書き込む
  • ファイルシステムをマウントする

詳細については、以下をご覧ください。

Pod に Google Cloud リソースへのアクセス権限を付与する

コンテナとポッドは、Google Cloud 内の他のリソースへのアクセスを必要とする場合があります。このための方法が 3 つあります。

Pod に Google Cloud リソースへのアクセス権限を付与する最も簡単で安全な方法は、Workload Identity です。Workload Identity を使用すると、Kubernetes サービス アカウントを Google Cloud サービス アカウントとして実行できます。Kubernetes サービス アカウントとして実行する Pod には、Google Cloud サービス アカウントの権限が与えられます。

Workload Identity は GKE Sandbox で使用できます。

ノードサービス アカウント

Pod は、メタデータにある Kubernetes クラスタのサービス アカウントの認証情報を使用して Google Cloud に対する認証を行うこともできます。ただし、Workload Identity が有効になっていない場合、これらの認証情報はクラスタで実行されている任意の Pod からアクセスできます。クラスタ内で実行中のすべての Pod が必要とする最小限の IAM ロールを持つカスタム サービス アカウントを作成して構成します。

GKE Sandbox ではメタデータ サーバーへのアクセスがブロックされるため、この方法には GKE Sandbox との互換性はありません。

サービス アカウント JSON キー

Google Cloud リソースに対する認証情報をアプリケーションに付与する 3 番目の方法では、サービス アカウント キーを手動で使用します。この方法は、アカウントキーを安全に管理するのが難しいため、強く非推奨とされます。

アプリケーション専用の Google Cloud サービス アカウントを使用して認証情報を付与して、アプリケーションに付与する権限を必要最小限に抑えてください。各サービス アカウントには、ペアに設定されたアプリケーションが正常に動作するために必要な IAM ロールだけが割り当てられます。サービス アカウントをアプリケーション専用にしておくと、不正使用が発生した場合に、アクセス権限を簡単に取り消して他のアプリケーションへの影響を防止できます。サービス アカウントに適切な IAM ロールを割り当てると、Kubernetes Secret を使用して JSON サービス アカウント キーを作成し、Pod にマウントできます。

Binary Authorization の使用

Binary Authorization は Google Cloud 上のサービスであり、クラウド内で実行されるアプリケーションにソフトウェア サプライ チェーン セキュリティを提供します。Binary Authorization は、Artifact Registry または他のコンテナ イメージ レジストリから GKE にデプロイするイメージに対して機能します。Binary Authorization を使用すると、アプリケーションを本番環境にデプロイする前に、ソフトウェアの品質と整合性を保護するための内部プロセスを正常かつ確実に完了できます。

Binary Authorization を有効にしたクラスタを作成する方法については、Binary Authorization ドキュメントクラスタの作成をご覧ください。

監査ロギング

監査ロギングを使用すると、管理者が GKE 環境で発生したイベントの保持、クエリ、処理、アラート生成を行うことができます。管理者はログに記録された情報を使用して、フォレンジック分析、リアルタイム アラート、GKE クラスタの使用状況とユーザーのカタログを作成できます。

デフォルトでは、GKE では管理アクティビティ ログが記録されます。また、検査対象のオペレーションの種類によってはデータアクセス イベントを記録することもできます。

詳細については、以下をご覧ください。