Google Kubernetes Engine(GKE)では、さまざまな方法でワークロードを保護できます。GKE でワークロードを保護するには、コンテナ イメージのコンテンツ、コンテナのランタイム、クラスタ ネットワーク、クラスタ API サーバーへのアクセスなど、何層ものスタックを考慮する必要があります。
クラスタとワークロードの保護には、階層的なアプローチをおすすめします。ユーザーとアプリケーションのアクセスレベルは、最小権限の原則に従って決定します。ワークロードのデプロイとメンテナンスを安全に行うためには柔軟性とセキュリティのバランスを適切に取る必要がありますが、このバランスは階層によって異なります。たとえば、一部のセキュリティ設定は特定の種類のアプリケーションにとって制限が多すぎたり、大幅にリファクタリングしないと使用目的に適合しなかったりする場合があります。
このドキュメントでは、インフラストラクチャの各レイヤの概要と、ニーズに合わせて最適なセキュリティ機能を構成する方法について説明します。
認証と認可
Kubernetes は次の 2 種類の認証をサポートしています。
- ユーザー アカウントは、Kubernetes で認識はされますが、Kubernetes では管理されないアカウントです。このため、たとえば、
kubectl
を使用した作成や削除はできません。 - サービス アカウントは、Kubernetes によって作成と管理は行われますが、Kubernetes によって作成されたエンティティ(Pod など)でしか使用できないアカウントです。
GKE クラスタでは、Kubernetes ユーザー アカウントは Google Cloud で管理され、次の 2 種類のいずれかになります。
認証後、それらの 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 RBAC のドキュメントを読む。
- Kubernetes API サーバーの認証で、Kubernetes API サーバーとの接続でサポートされる認証方法を確認する。
コントロール プレーンのセキュリティ
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 ログインの無効化
GKE Autopilot ノードは、常に Container-Optimized OS をオペレーティング システムとして使用します。
ノードのアップグレード
OS には定期的にパッチを適用することをおすすめします。コンテナのランタイム、Kubernetes 自体、ノードのオペレーティング システムのセキュリティに問題が発生すると、ノードの緊急アップグレードが必要となる場合があります。ノードをアップグレードすると、ノードのソフトウェアは最新バージョンになります。
GKE クラスタは自動アップグレードをサポートしています。Autopilot クラスタでは、自動アップグレードが常に有効になります。Standard クラスタのノードは手動でアップグレードできます。
信頼できないワークロードからのノードの保護
不明または信頼できないワークロードを実行するクラスタでは、ポッド内で実行される信頼できないワークロードからノードのオペレーティング システムを保護することをおすすめします。
たとえば、Software-as-a-Service(SaaS)プロバイダなどのマルチテナント クラスタは、ユーザーから送信された不明なコードを実行することも珍しくありません。セキュリティ調査も、ワークロードに対してノードのデフォルトよりも強力な隔離が必要になる可能性があるアプリケーションの 1 つです。
GKE Sandbox をクラスタで有効にすると、信頼できないワークロードをノード上のサンドボックス内に隔離できます。GKE Sandbox は、オープンソースのプロジェクトである gVisor を使用して構築されています。
インスタンス メタデータの保護
GKE は、基盤となる Compute Engine インスタンスのインスタンス メタデータを使用して、ノードのブートストラップやコントロール プレーンの接続で使用される認証情報と構成をノードに提供します。このメタデータには、ノードのサービス アカウント キーなど、ノードの Pod がアクセスする必要のない機密情報が含まれています。
GKE 用 Workload Identity 連携を使用すると、インスタンスの機密性の高いメタデータのパスを遮断できます。GKE 用 Workload Identity 連携により、クラスタで GKE メタデータ サーバーが有効になり、kube-env
などの機密性の高いフィールドへのリクエストが除外されます。
GKE 用 Workload Identity 連携は、Autopilot クラスタで常に有効になっています。Standard クラスタでは、GKE 用 Workload Identity 連携を手動で有効にしない限り、Pod はインスタンス メタデータにアクセスできます。
ネットワーク セキュリティ
GKE で実行されているワークロードの大部分は、クラスタの内部または外部で実行されている他のサービスと通信する必要があります。クラスタやその Pod を流れるトラフィックを制御する方法は、複数あります。
ポッド間の通信を制限する
デフォルトでは、クラスタ内のすべての Pod は Pod の IP アドレスを使用してネットワークにアクセスできます。同様に、デフォルトでは、クラスタがデプロイされている VPC 内の任意のアクセス可能なアドレスへの送信接続が下り(外向き)トラフィックにより許可されます。
クラスタ管理者とユーザーは、ネットワーク ポリシーを使用すると、Namespace 内の Pod への上り(内向き)接続やその Pod からの下り(外向き)接続を遮断できます。デフォルトでは、ネットワーク ポリシーが定義されていない場合、ポッドへのすべての入力トラフィックとポッドからのすべての出力トラフィックが許可されます。ネットワーク ポリシーを使用すると、タグを使用して Pod を流れるトラフィックを定義できます。
名前空間でネットワーク ポリシーが適用されると、ポッドからのトラフィックとポッドへのトラフィックのうち、構成されたラベルと一致しないものはすべてドロップされます。クラスタや Namespace を作成するときに、すべての 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 コンテナのプロセス権限を制限する
コンテナ化されたプロセスの権限を制限することは、クラスタの全体的なセキュリティにとって重要なことです。Autopilot のセキュリティ機能で説明されているように、GKE Autopilot クラスタは常に特定の権限を制限しています。
また、Pod とコンテナの両方でセキュリティ コンテキストを使用してセキュリティ関連のオプションを設定できます。この設定では、次のようにプロセスのセキュリティ設定を変更できます。
- 実行するユーザーとグループ
- 利用可能な Linux 機能
- 権限を昇格させる能力
これらの制限を Pod レベルやコンテナレベルではなくクラスタレベルで適用するには、PodSecurityAdmission コントローラを使用します。クラスタ管理者は、PodSecurityAdmission を使用することで、クラスタまたは Namespace 内のすべての Pod に Pod セキュリティ標準の事前定義ポリシーを遵守させることができます。また、Gatekeeper を使用して、クラスタレベルでカスタム Pod セキュリティ ポリシーを設定することもできます。
GKE ノードでは、Container-Optimized OS と Ubuntu のどちらのオペレーティング システムが使用されている場合でも、Kubernetes で起動されたすべてのコンテナにデフォルトの Docker AppArmor セキュリティ ポリシーが適用されます。プロファイルのテンプレートは GitHub で確認できます。特に、次のプロファイルではコンテナに対する以下の機能が拒否されます。
/proc/
内のファイルに直接書き込む- プロセス ID ディレクトリ(
/proc/<number>
)内に存在しないファイルに書き込む /proc/sys
内に存在する/proc/sys/kernel/shm*
以外のファイルに書き込む- ファイルシステムをマウントする
詳細情報:
- Pod のセキュリティ コンテキストのドキュメントを読む。
- Container-Optimized OS AppArmor のドキュメントで既存の保護機能を確認する。
Pod に Google Cloud リソースへのアクセス権限を付与する
コンテナと Pod は、Google Cloud 内の他のリソースへのアクセスを必要とする場合があります。このための方法が 3 つあります。
GKE 用 Workload Identity 連携(推奨)
Pod に Google Cloud リソースへのアクセスを許可する最も安全な方法は、GKE 用 Workload Identity 連携を使用することです。GKE 用 Workload Identity 連携を使用すると、Kubernetes サービス アカウントを IAM サービス アカウントとして実行できます。Kubernetes サービス アカウントとして実行する Pod には、IAM サービス アカウントの権限が与えられます。
GKE 用 Workload Identity 連携は、GKE Sandbox で使用できます。
ノードのサービス アカウント
Standard クラスタの場合、Pod は、ノードの Compute Engine 仮想マシン(VM)によって使用されるサービス アカウントの認証情報を使用して Google Cloud に対する認証を行うことができます。
GKE Sandbox では Compute Engine メタデータ サーバーへのアクセスがブロックされるため、この方法を GKE Sandbox に対して行うことはできません。
JSON 形式のサービス アカウント キー(非推奨)
サービス アカウント キーを使用すると、Google Cloud リソースの認証情報をアプリケーションに付与できます。アカウントキーを安全に管理することが難しいため、この方法はおすすめしません。
この方法を選択した場合は、アプリケーションごとにカスタム IAM サービス アカウントを使用し、アプリケーションに付与する権限が最小限になるようにします。ペアに設定されたアプリケーションが正常に動作するために必要な最小限の IAM ロールを、各サービス アカウントに付与します。サービス アカウントをアプリケーション専用にしておくと、不正に利用されたときにアクセス権を簡単に取り消し、他のアプリケーションへの影響を防ぐことができます。サービス アカウントに適切な IAM ロールを割り当てると、Kubernetes Secret を使用して JSON サービス アカウント キーを作成し、Pod にそのキーをマウントできます。
Binary Authorization の使用
Binary Authorization は Google Cloud 上のサービスであり、クラウド内で実行されるアプリケーションにソフトウェア サプライ チェーン セキュリティを提供します。また、Artifact Registry または他のコンテナ イメージ レジストリから GKE にデプロイするイメージに対して機能します。
Binary Authorization を使用すると、アプリケーションを本番環境にデプロイする前に、ソフトウェアの品質と整合性を保護するための内部プロセスを正常かつ確実に完了できます。Binary Authorization を有効にしたクラスタを作成する方法については、Binary Authorization ドキュメントのクラスタの作成をご覧ください。
Binary Authorization 継続的検証(CV)により、Pod に関連付けられたコンテナ イメージを定期的にモニタリングし、進化する内部プロセスに準拠しているかどうか確認できます。
監査ロギング
監査ロギングを使用すると、管理者が GKE 環境で発生したイベントの保持、クエリ、処理、アラート生成を行うことができます。管理者はログに記録された情報を使用して、フォレンジック分析、リアルタイム アラート、GKE クラスタの使用状況とユーザーのカタログを作成できます。
デフォルトでは、GKE では管理アクティビティ ログが記録されます。また、検査対象のオペレーションの種類によってはデータアクセス イベントを記録することもできます。
詳細については、以下をご覧ください。
- GKE 監査ロギングのチュートリアルを読む。
- Cloud Audit Logs を読む。
組み込みのセキュリティ対策
GKE では、クラスタ内のシステム オブジェクトに対して特定の制限が適用されています。ワークロードのパッチ適用などのオペレーションを実行すると、GKE Warden という Admission Webhook が一連の制限付きオペレーションに対するリクエストを検証し、リクエストを許可するかどうかを決定します。
Autopilot クラスタのセキュリティ対策
Autopilot クラスタには、専門知識と業界のベスト プラクティスに基づいてさまざまなセキュリティ設定が適用されています。詳細については、Autopilot のセキュリティ対策をご覧ください。
Standard クラスタのセキュリティ対策
Standard クラスタは、デフォルトでは Autopilot クラスタよりも制約が緩やかです。GKE Standard クラスタには、次のセキュリティ設定があります。
kube-system
Namespace のワークロードなど、GKE マネージド システム ワークロードで使用される ServiceAccount は更新できません。cluster-admin
のデフォルトの ClusterRole はsystem:anonymous
、system:unauthenticated
、またはsystem:authenticated
グループにはバインドできません。