GKE Sandbox

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

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

概要

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

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

潜在的な脅威

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

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

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

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

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

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

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

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

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

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

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

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

制限事項

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

ノードプールの構成

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

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

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

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

gVisor ノードでは、デフォルトでハイパー スレッディングが無効化され、Intel が発表した Microarchitectural Data Sampling(MDS)の脆弱性が軽減されています。ノードプールに対してハイパー スレッディングを有効にするには:

  1. ノードラベル cloud.google.com/gke-smt-disabled=false を使用して、クラスタに新しいノードプールを作成します。

    gcloud container node-pools create smt-enabled --cluster=[CLUSTER_NAME] \
      --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 ポッドが実行状態であることを確認します。

    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. ポッドのログに 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"]

互換性のない機能

現在、GKE Sandbox は次の Kubernetes の機能と一緒には使用できません。

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

ワークロードの特性

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

システムコール

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

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

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

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

次のステップ