このページでは、Pod 内のコンテナで、不明なコードや信頼できないコードが実行されたときに、GKE Sandbox を使用してノードのホストカーネルを保護する方法について説明します。たとえば、Software as a Service(SaaS)プロバイダなどのマルチテナント クラスタでは、ユーザーから送信された不明なコードが実行されることが少なくありません。GKE Sandbox は、価値の高いコンテナを実行する場合にも、多層防御の有効な手段となります。
GKE Sandbox は、オープンソース プロジェクトの gVisor を使用します。このトピックでは gVisor の概要について説明します。詳細については、gVisor の公式ドキュメントをご覧ください。
GKE Sandbox を有効にして使用する方法については、GKE Sandbox の構成に関する記事をご覧ください。
概要
GKE Sandbox は、セキュリティに新たなレイヤを追加し、信頼できないコードからクラスタノードのホストカーネルを保護します。GKE Sandbox の仕組みについて説明する前に、潜在的なリスクの特徴について理解しておきましょう。これは、リスクを回避する際に役立ちます。
containerd
などのコンテナ ランタイムは、コンテナのプロセスとノードのカーネルをある程度分離しています。ただし、コンテナ ランタイムはノードの特権ユーザーとして実行されることが多く、その場合、ホストカーネルに対するほとんどのシステムコールにアクセスできます。
潜在的な脅威
マルチテナント クラスタや、コンテナで信頼できないワークロードが実行されるクラスタは、他のクラスタよりも脆弱性が悪用されるリスクが高くなります。たとえば、SaaS プロバイダ、ウェブ ホスティング プロバイダ、ユーザーにコードのアップロードと実行を許可している組織では、攻撃を受ける可能性が高くなります。コンテナ ランタイムやホストカーネルの欠陥が悪用されると、コンテナ内で実行されるプロセスがコンテナをエスケープして、ノードのカーネルに影響を及ぼし、ノードが停止する可能性があります。
また、悪意のあるテナントが、このような欠陥を利用して他のテナントのメモリやディスクに侵入し、データを盗み出す可能性もあります。
信頼できないワークロードが、他の Google Cloud サービスやクラスタ メタデータにアクセスする可能性もあります。
GKE Sandbox が脅威を軽減する仕組み
gVisor は、高レベルの権限を必要としない Linux カーネル API のユーザー空間を再実装したものです。containerd
などのコンテナ ランタイムとともに、このユーザー空間カーネルはシステムコールの大半を再実装し、ホストカーネルに代わってサービスを提供します。これにより、ホストカーネルへの直接アクセスが制限されています。この仕組みの詳細については、gVisor アーキテクチャ ガイドをご覧ください。コンテナの観点から見ると、gVisor はほぼ透過的で、コンテナ化されたアプリケーションに変更を加える必要はありません。
Autopilot クラスタの Pod で GKE Sandbox をリクエストすると、GKE はその Pod をサンドボックスで実行します。GKE Standard では、ノードで GKE Sandbox を有効にすると、それらのノードで実行されるすべての Pod がサンドボックスで実行されます。
各サンドボックスは、独自のユーザー空間カーネルを使用します。このため、必要な分離レベルとアプリケーションの特性に基づいて、コンテナを Pod にグループ化できます。
GKE Sandbox は、次のタイプのアプリケーションに特に適しています。サンドボックス化するアプリケーションについては、制限事項をご覧ください。
- Rust、Java、Python、PHP、Node.js、Golang など、ランタイムを使用するサードパーティまたは信頼できないアプリケーション
- ウェブサーバーのフロントエンド、キャッシュ、またはプロキシ
- CPU を使用して外部メディアまたはデータを処理するアプリケーション
- CPU を使用した機械学習ワークロード
- CPU 負荷の高いアプリケーションやメモリを大量に消費するアプリケーション
- GPU 負荷の高いワークロード
その他のセキュリティに関する推奨事項
GKE Sandbox を使用する場合は、次の推奨事項も考慮してください。
サンドボックス内で実行されるすべてのコンテナに対してリソースの上限を指定します。これにより、不正なアプリケーションによるノードリソースの占有を回避し、ノード上で実行中の他のアプリケーションやシステム プロセスへの悪影響を防ぐことができます。
GKE 用 Workload Identity 連携を使用している場合は、ネットワーク ポリシーを使用してクラスタ メタデータへのアクセスをブロックし、
169.254.169.254
へのアクセスをブロックします。これにより、悪意のあるアプリケーションがプロジェクト ID、ノード名、ゾーンのプライベート データにアクセスする可能性があるリスクを防ぎます。GKE 用 Workload Identity 連携は、GKE Autopilot クラスタで常に有効になっています。
制限事項
GKE Sandbox は多くのアプリケーションで動作していますが、すべてのアプリケーションに対応しているわけではありません。このセクションでは、GKE Sandbox の現在の制限事項について詳しく説明します。
GKE Sandbox の GPU
GKE バージョン 1.29.2-gke.1108000 以降では、GKE Sandbox は NVIDIA GPU の使用をサポートしています。
GKE Sandbox ですべての NVIDIA ドライバの脆弱性が軽減されるわけではありませんが、Linux カーネルの脆弱性からは引き続き保護されます。gVisor プロジェクトで GPU ワークロードを保護する方法については、GPU サポートガイドをご覧ください。
GKE Sandbox 内の GPU ワークロードには、次の制限が適用されます。
- 特定の GKE バージョンの
latest
NVIDIA ドライバ バージョンのみがサポートされます。Autopilot クラスタに、GKE Sandbox をサポートする NVIDIA ドライバ バージョンが自動的にインストールされます。 - CUDA ワークロードのみがサポートされます。
- サポートされる GPU モデルは、nvidia-tesla-t4、nvidia-tesla-a100、nvidia-a100-80gb、nvidia-l4、nvidia-h100-80gb です。
GKE Sandbox は、GPU ワークロードで追加料金なしで使用できます。
ノードプールの構成
Standard クラスタに適用
- GKE Sandbox は、Windows Server ノードプールで使用できません。
- デフォルトのノードプールで GKE Sandbox を有効にして、デフォルトのノードプールで実行しているシステム サービスを GKE Sandbox を使用する信頼できないワークロードから分離することはできません。
- GKE Sandbox を使用する場合、クラスタに 2 つ以上のノードプールが必要です。GKE Sandbox が無効になっているノードプールが少なくとも 1 つは必要です。 すべてのワークロードがサンドボックス化されていても、このノードプールには 1 つ以上のノードが必要です。
- 1.24.2-gke.300 より前のバージョンの GKE では、e2-micro、e2-small、e2-medium マシンタイプはサポートされていません。GKE バージョン 1.24.2-gke.300 以降では、これらのマシンタイプがサポートされています。
- ノードでは、containerd(
cos_containerd
)を含む Container-Optimized OS のノードイメージを使用する必要があります。
クラスタ メタデータへのアクセス
Autopilot クラスタと Standard クラスタに適用
- サンドボックス化された Pod を実行するノードでは、ノードのオペレーティング システムのレベルでクラスタ メタデータにアクセスできません。
- GKE Standard では、GKE Sandbox が有効になっているノードで通常の Pod を実行できます。ただし、デフォルトでは、これらの通常の Pod は Google Cloud サービスやクラスタ メタデータにアクセスできません。
- GKE 用 Workload Identity 連携を使用して、Google Cloud サービスへのアクセス権を Pod に付与します。
SMT が無効になっている可能性がある
Autopilot クラスタと Standard クラスタに適用
同時マルチスレッディング(SMT)設定は、マイクロアーキテクチャ データ サンプリング(MDS)の脆弱性など、コア状態を共有するスレッドを利用するサイドチャネルの脆弱性を軽減するために使用されます。
GKE バージョン 1.25.5-gke.2500 以降と 1.26.0-gke.2500 以降では、gVisor は Linux Core Scheduling を使用してサイドチャネル攻撃を軽減するように構成されています。SMT のデフォルト設定は変更されません。Core Scheduling は、gVisor で実行さていれるワークロードにのみ使用されます。
GKE バージョン 1.24.2-gke.300 以降では、SMT はマシンの MDS に対する脆弱性に基づいて、次のようにマシンタイプ別に構成されます。
Scale-Out
コンピューティング クラスで実行されている Autopilot Pod: SMT は無効になります。Intel プロセッサを搭載したマシンタイプ: SMT はデフォルトで無効になります。
Intel プロセッサを搭載していないマシンタイプ: SMT はデフォルトで有効になります。
コアごとに 1 つのスレッドのみのマシンタイプ : SMT はサポートされません。リクエストされたすべての vCPU が表示されます。
バージョン 1.24.2-gke.300 より前では、すべてのマシンタイプで SMT が無効になります。
SMT を有効にする
Standard クラスタに適用
GKE Standard クラスタでは、選択したマシンタイプで SMT が無効になっている場合は SMT を有効にできます。SMT が有効か無効かに関係なく、vCPU ごとに課金されます。料金については、Compute Engine の料金をご覧ください。
GKE バージョン 1.24.2-gke.300 以降
GKE Sandbox ノードプールを作成するときに、--threads-per-core
フラグを設定します。
gcloud container node-pools create smt-enabled \
--cluster=CLUSTER_NAME \
--machine-type=MACHINE_TYPE \
--threads-per-core=2 \
--sandbox type=gvisor
CLUSTER_NAME
: 既存のクラスタの名前。MACHINE_TYPE
: マシンタイプ。
--threads-per-core
の詳細については、コアあたりのスレッド数を設定するをご覧ください。
バージョン 1.24.2-gke.300 より前の GKE
ノードラベル
cloud.google.com/gke-smt-disabled=false
を使用して、クラスタに新しいノードプールを作成します。gcloud container node-pools create smt-enabled \ --cluster=CLUSTER_NAME \ --machine-type=MACHINE_TYPE \ --node-labels=cloud.google.com/gke-smt-disabled=false \ --image-type=cos_containerd \ --sandbox type=gvisor
ノードプールに DaemonSet をデプロイします。DaemonSet は、
cloud.google.com/gke-smt-disabled=false
ラベルのあるノードでのみ実行されます。kubectl create -f \ https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-node-tools/master/disable-smt/gke/enable-smt.yaml
DaemonSet Pod のステータスが Running であることを確認します。
kubectl get pods --selector=name=enable-smt -n kube-system
出力は次のようになります。
NAME READY STATUS RESTARTS AGE enable-smt-2xnnc 1/1 Running 0 6m
Pod のログに
SMT has been enabled
があることを確認します。kubectl logs enable-smt-2xnnc enable-smt -n kube-system
機能
Standard クラスタに適用
デフォルトでは、コンテナは未処理のソケットを開けないため、悪質な攻撃を防ぐことができます。ping
や tcpdump
など、特定のネットワーク関連ツールは、そのコアの機能の一部として未処理のソケットを作成します。未処理のソケットを有効にするには、NET_RAW
の機能をコンテナのセキュリティ コンテキストに明示的に追加する必要があります。
spec:
containers:
- name: my-container
securityContext:
capabilities:
add: ["NET_RAW"]
GKE Autopilot を使用する場合、この機能にはセキュリティ上の影響があるため、Google Cloud では NET_RAW
権限をコンテナに追加できません。
外部依存関係
Autopilot クラスタと Standard クラスタに適用
サンドボックス内で実行される信頼できないコードに、データベース サーバー、API、その他のコンテナ、CSI ドライバなどの外部サービスとの接続が許可されている場合があります。これらのサービスはサンドボックス境界の外部で実行されているため、個別に保護する必要があります。これらのサービスの脆弱性が悪用されると、サンドボックスが回避される可能性があります。サンドボックス内で実行されるコードがこれらのサービスに接続するリスクと影響を考慮し、必要な保護手段を講じる必要があります。
たとえば、ext4 や CSI ドライバなど、コンテナ ボリュームのファイル システム実装などを検討する必要があります。CSI ドライバはサンドボックス分離の外部で実行され、ホストとサービスに対して特権アクセスが許可されている場合があります。これらのドライバが悪用されると、ホストのカーネルに侵入され、ノード全体が乗っ取られる可能性があります。攻撃による影響を抑えるため、コンテナ内の CSI ドライバは必要最小限の権限で実行することをおすすめします。GKE Sandbox では、Compute Engine 永続ディスクの CSI ドライバの使用がサポートされています。
互換性のない機能
次の Kubernetes 機能では GKE Sandbox を使用できません。
- コンテナレベルのメモリ使用量の指標。ただし、Pod のメモリ使用量はサポートされています。
- hostPath ストレージ
- CPU とメモリの制限は、Guaranteed Pod と Burstable Pod にのみ適用されますが、適用されるのは、Pod で実行中のすべてのコンテナに CPU とメモリの制限が指定されている場合だけです。
- 特権モードで実行されるコンテナ
- VolumeDevices
- ポート転送
- Seccomp、Apparmor、Selinux、Sysctl、
NoNewPrivileges
、双方向の MountPropagation、ProcMount などの Linux カーネル セキュリティ モジュール。 - Traffic Director
Istio CNI を含む ASM
FSGroup は GKE バージョン 1.22 以降でサポートされています。
Cloud Service Mesh は、Autopilot クラスタの GKE Sandbox Pod ではサポートされていません。
ワークロードの特性
Autopilot クラスタと Standard クラスタに適用
ノードのカーネルにアクセスするために中間層を追加すると、パフォーマンスとのトレードオフが発生します。GKE Sandbox は、分離を必要とする大規模なマルチテナント クラスタで最大の効果を発揮します。GKE Sandbox でワークロードのテストを行う場合は、次のガイドラインに従ってください。
システムコール
Autopilot クラスタと Standard クラスタに適用
オーバーヘッドの少ないシステムコールを大量に生成するワークロード(小規模の I/O オペレーションを頻繁に実行するワークロードなど)をサンドボックス内で実行すると、システム リソースの消費が増える可能性があります。その場合、より強力なノードを使用するか、クラスタにノードを追加する必要があります。
ハードウェアまたは仮想化への直接アクセス
Autopilot クラスタと Standard クラスタに適用
ワークロードで次のいずれかが必要な場合、GKE Sandbox が適切ではないことがあります。このサンドボックスでは、ノードのホストカーネルに直接アクセスできないためです。
- ノードのハードウェアへの直接アクセス
- カーネルレベルの仮想化機能
- 特権コンテナ