GKE Sandbox

このページでは、Pod 内のコンテナで、不明なコードや信頼できないコードが実行されたときに、GKE Sandbox を使用してノードのホストカーネルを保護する方法について説明します。たとえば、SaaS プロバイダなどのマルチテナント クラスタでは、ユーザーから送信された不明なコードが実行されることが少なくありません。

GKE Sandbox は、オープンソース プロジェクトの gVisor を使用します。このトピックでは gVisor の概要について説明します。詳細については、gVisor の公式ドキュメントをご覧ください。

GKE Sandbox を有効にする方法の詳細については、GKE Sandbox を構成するをご覧ください。

概要

GKE Sandbox は、セキュリティに新たなレイヤを追加し、信頼できないコードからクラスタノードのホストカーネルを保護します。GKE Sandbox の仕組みについて説明する前に、潜在的なリスクの特徴について理解しておきましょう。これは、リスクを回避する際に役立ちます。

dockercontainerd などのコンテナ ランタイムは、コンテナのプロセスとノードのカーネルをある程度分離しています。ただし、コンテナ ランタイムはノードの特権ユーザーとして実行されることが多く、その場合、ホストカーネルに対するほとんどのシステムコールにアクセスできます。

潜在的な脅威

マルチテナント クラスタや、コンテナで信頼できないワークロードが実行されるクラスタは、他のクラスタよりも脆弱性が悪用されるリスクが高くなります。たとえば、SaaS プロバイダ、ウェブ ホスティング プロバイダ、ユーザーにコードのアップロードと実行を許可している組織では、攻撃を受ける可能性が高くなります。コンテナ ランタイムやホストカーネルの欠陥が悪用されると、コンテナ内で実行されるプロセスがコンテナをエスケープして、ノードのカーネルに影響を及ぼし、ノードが停止する可能性があります。

また、悪意のあるテナントが、このような欠陥を利用して他のテナントのメモリやディスクに侵入し、データを盗み出す可能性もあります。

信頼できないワークロードが、他の Google Cloud サービスやクラスタ メタデータにアクセスする可能性もあります。

GKE Sandbox が脅威を軽減する仕組み

gVisor は、高レベルの権限を必要としない Linux カーネル API のユーザー空間を再実装したものです。containerd などのコンテナ ランタイムとともに、このユーザー空間カーネルはシステムコールの大半を再実装し、ホストカーネルに代わってサービスを提供します。これにより、ホストカーネルへの直接アクセスが制限されています。この仕組みの詳細については、gVisor アーキテクチャ ガイドをご覧ください。コンテナの観点から見ると、gVisor はほぼ透過的で、コンテナ化されたアプリケーションに変更を加える必要はありません。

ノードプールで GKE Sandbox を有効にすると、そのノードプール内のノードで実行中の Pod ごとにサンドボックスが作成されます。さらに、サンドボックス化された Pod を実行するノードは、他の Google Cloud サービスやクラスタ メタデータにアクセスすることはできません。

各サンドボックスは、独自のユーザー空間カーネルを使用します。このため、必要な分離レベルとアプリケーションの特性に基づいて、コンテナを Pod にグループ化できます。

GKE Sandbox は、次のタイプのアプリケーションに特に適しています。サンドボックス化するアプリケーションについては、制限事項をご覧ください。

  • Rust、Java、Python、PHP、Node.js、Golang など、ランタイムを使用するサードパーティまたは信頼できないアプリケーション
  • ウェブサーバーのフロントエンド、キャッシュ、またはプロキシ
  • CPU を使用して外部メディアまたはデータを処理するアプリケーション
  • CPU を使用した機械学習ワークロード
  • CPU 使用量の多いアプリケーションやメモリを大量に消費するアプリケーション

その他のセキュリティに関する推奨事項

GKE Sandbox を使用する場合は、次の推奨事項も考慮してください。

  • サンドボックス内で実行されるすべてのコンテナに対してリソースの上限を指定することをおすすめします。これにより、不正なアプリケーションによるノードリソースの占有を回避し、ノード上で実行中の他のアプリケーションやシステム プロセスへの悪影響を防ぐことができます。

  • Workload Identity を使用している場合、IP 169.254.169.254 へのアクセスをブロックするためにネットワーク ポリシーを使用してクラスタ メタデータへのアクセスをブロックすることをおすすめします。これにより、悪意のあるアプリケーションがプロジェクト ID、ノード名、ゾーンなどのプライベート データにアクセスする可能性があるリスクを防ぎます。

制限事項

GKE Sandbox は多くのアプリケーションで動作していますが、すべてのアプリケーションに対応しているわけではありません。このセクションでは、GKE Sandbox の現在の制限事項について詳しく説明します。

ノードプールの構成

  • デフォルトのノードプールで GKE Sandbox を有効にすることはできません。
  • GKE Sandbox を使用する場合、クラスタに 2 つ以上のノードプールが必要です。 GKE Sandbox が無効になっているノードプールが少なくとも 1 つは必要です。 すべてのワークロードがサンドボックス化されていても、このノードプールには 1 つ以上のノードが必要です。
  • ノードプールでは、e2-micro、e2-small、e2-medium マシンタイプは使用できません。

クラスタ メタデータへのアクセス

  • サンドボックス化された Pod を実行するノードでは、ノードのオペレーティング システムのレベルでクラスタ メタデータにアクセスできません。
  • GKE Sandbox が有効になっているノードでは、通常の Pod を実行できます。ただし、デフォルトでは、これらの通常の Pod は Google Cloud サービスやクラスタ メタデータにアクセスできません。
  • Workload Identity を使用して、Google Cloud サービスへのアクセス権を Pod に付与します。

ハイパー スレッディングの無効化

gVisor ノードでは、ハイパースレッド間で共有されるコア状態を利用するサイドチャネルの脆弱性を軽減するため、すべてのアーキテクチャでハイパー スレッディングがデフォルトで無効になっています。たとえば、マイクロアーキテクチャ データ サンプリング(MDS)の脆弱性です。ノードプールに対してハイパー スレッディングを有効にするには:

  1. ノードラベル 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
    
  2. ノードプールに 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
    
  3. ノードの再起動後に、DaemonSet Pod が実行状態であることを確認します。

    kubectl get pods --selector=name=enable-smt -n kube-system
    
  4. 次のようなレスポンスが返されます。

    NAME               READY     STATUS    RESTARTS   AGE
    enable-smt-2xnnc   1/1       Running   0          6m
    
  5. Pod のログに SMT has been enabled があることを確認します。

    kubectl logs enable-smt-2xnnc enable-smt -n kube-system
    

機能

デフォルトでは、コンテナは未処理のソケットを開けないため、悪質な攻撃を防ぐことができます。pingtcpdump など、特定のネットワーク関連ツールは、そのコアの機能の一部として未処理のソケットを作成します。未処理のソケットを有効にするには、NET_RAW の機能をコンテナのセキュリティ コンテキストに明示的に追加する必要があります。

spec:
  containers:
  - name: my-container
    securityContext:
      capabilities:
        add: ["NET_RAW"]

外部依存関係

サンドボックス内で実行される信頼できないコードに、データベース サーバー、API、その他のコンテナ、CSI ドライバなどの外部サービスとの接続が許可されている場合があります。これらのサービスはサンドボックス境界の外部で実行されているため、個別に保護する必要があります。これらのサービスの脆弱性が悪用されると、サンドボックスが回避される可能性があります。サンドボックス内で実行されるコードがこれらのサービスに接続するリスクと影響を考慮し、必要な保護手段を講じる必要があります。

たとえば、ext4 や CSI ドライバなど、コンテナ ボリュームのファイル システム実装などを検討する必要があります。CSI ドライバはサンドボックス分離の外部で実行され、ホストとサービスに対して特権アクセスが許可されている場合があります。これらのドライバが悪用されると、ホストのカーネルに侵入され、ノード全体が乗っ取られる可能性があります。攻撃による影響を抑えるため、コンテナ内の CSI ドライバは必要最小限の権限で実行することをおすすめします。Compute Engine Persistent Disk CSI ドライバは GKE Sandbox でサポートされています。

互換性のない機能

現在、次の Kubernetes 機能と GKE Sandbox を併用することはできません。

  • GPU や TPU などのアクセラレータ
  • Pod またはコンテナのレベルでの統計情報のモニタリング
  • hostpath ストレージ
  • CPU とメモリの制限は、保証された Pod とバースト可能 Pod にのみ適用されますが、適用されるのは、Pod で実行中のすべてのコンテナに CPU とメモリの制限が指定されている場合だけです。
  • hostNetworkhostPIDhostIPC など、ホストの Namespace を指定する PodSecurityPolicies を使用する Pod
  • 特権モードなどの PodSecurityPolicy 設定を使用する Pod
  • VolumeDevices
  • ポート転送
  • Seccomp、Apparmo または Selinux SysctlNoNewPrivileges双方向の MountPropagationFSGroupProcMount などの Linux カーネル セキュリティ モジュール。
  • Traffic Director
  • Istio は 1.18.6-gke.4801 より前のクラスタ バージョンではサポートされていません。Istio は 1.18.6-gke.4801 以降でサポートされています。

ワークロードの特性

ノードのカーネルにアクセスするために中間層を追加すると、パフォーマンスとのトレードオフが発生します。GKE Sandbox は、分離を必要とする大規模なマルチテナント クラスタで最大の効果を発揮します。GKE Sandbox でワークロードのテストを行う場合は、次のガイドラインに従ってください。

システムコール

オーバーヘッドの少ないシステムコールを大量に生成するワークロード(小規模の入出力オペレーションを頻繁に実行するワークロードなど)をサンドボックス内で実行すると、システム リソースの消費が増える可能性があります。その場合、より強力なノードを使用するか、クラスタにノードを追加する必要があります。

ハードウェアまたは仮想化への直接アクセス

ワークロードで次のいずれかが必要な場合、GKE Sandbox が適切ではないことがあります。このサンドボックスでは、ノードのホストカーネルに直接アクセスできないためです。

  • ノードのハードウェアへの直接アクセス
  • カーネルレベルの仮想化機能
  • 特権コンテナ

次のステップ