Kubernetes 解体新書Part 5 パブリッククラウドとの関係

AWS の AZ と GCP の zone は同じものか

似た名前でも、同じ仕組みとは限りません。AWS と Google Cloud のネットワーク配置や、実行環境の分離を比べます。

  • L0 ブラウザだけ
  • 更新 2026年10月6日

AWS でも Google Cloud でも、「リージョン」「ゾーン」「サブネット」という言葉が出てきます。 名前が似ていても、どの範囲を指すかや、組み合わせ方が同じとは限りません。

この章では、ネットワークの配置と、利用者同士の実行環境の分離を例に、両社の説明を比べます。 同じ言葉から同じ構成を想像せず、どこで分かれているかを図で確かめます。

GOAL この章のゴール

  • AWS と Google Cloud のゾーンやサブネットの違いを説明できる
  • サービスごとに、利用者のコードをどう分離しているか分かる
  • 分離方式を比較するときに、共有する部分を確認できる

似ている用語の違い

AWS と GCP の用語を並べます。

AWS GCP
Region Region
AZ (Availability Zone) Zone
VPC VPC
Subnet Subnetwork

表の上では同じに見えますが、所属関係が違います。 AWS の VPC はリージョンに閉じていて、サブネットは AZ に属します。 GCP の VPC はグローバルで、サブネットワークはリージョンに属し、ゾーンには縛られません。

AWS の AZ と GCP の zone: 公開資料の定義とサブネットの所属左: AWS のリージョンは複数の AZ からなり、各 AZ は 1 つ以上の独立したデータセンターで、AZ 同士は数 km 以上 100 km 以内の距離で物理的に離れる。サブネットは AZ に属する。右: GCP のリージョンは 3 つ以上の zone からなり、zone はリージョン内の配置先で単一の障害ドメイン。zone と region は物理資源の論理的な抽象と定義される。サブネットはリージョンに属し、zone をまたぐ。VPC はグローバル。AWS リージョン (例: ap-northeast-1)VPC (リージョンに閉じる)AZ aデータセンター1 つ以上subnetAZ に属する電源、冷却が独立AZ cデータセンター1 つ以上subnetAZ に属する電源、冷却が独立AZ dデータセンター1 つ以上subnetAZ に属する電源、冷却が独立AZ 同士は数 km 以上離れ、100 km 以内。専用の光ファイバーで接続 (AWS の公開資料)。GCP リージョン (例: asia-northeast1)VPC (グローバル。リージョンをまたぐ)zone a配置先障害ドメイン1 つの障害単位zone b配置先障害ドメイン1 つの障害単位zone c配置先障害ドメイン1 つの障害単位zone は「物理資源の論理的な抽象」(Google の公開資料)subnet (リージョンに属し、zone をまたぐ)リージョンは 3 つ以上の zone からなり、3 つ以上の物理データセンターに置かれる。
図 1AWS の AZ は、物理的に離れた 1 つ以上のデータセンター。GCP の zone は、リージョン内の配置先であり、物理資源の論理的な抽象。サブネットの所属が違う。

AWS の AZ は、公開資料では「リージョン内にある、冗長な電源、ネットワーク、接続性を持つ 1 つ以上の独立したデータセンター」と定義されています。 AZ 同士は「数 km 以上の意味のある距離」で物理的に離れ、ただし互いに 100 km 以内にあり、電源、冷却、物理セキュリティが独立していて、専用の光ファイバーで繋がれています。 「AZ を分ける」は「別の建物に置く」とほぼ同じ意味です。

GCP の zone は、公開資料では「リージョン内の Google Cloud リソースの配置先」と定義され、「リージョン内の単一の障害ドメインと見なすべき」とされています。 同じ資料は、zone と region を「下にある物理資源の論理的な抽象」と呼び、リージョンは「3 つ以上の物理データセンターに置かれた 3 つ以上の zone」からなると説明しています。 つまり Google は、zone と建物の対応を定義に含めていません。 zone が約束するのは、別の zone と障害が相関しにくいことであって、別の建物にあることではありません。 どちらも障害ドメインとして使えますが、AWS は物理的な距離と独立性を定義に書き、Google は論理的な単位として定義している、というのが両社の違いです。

マルチテナントの分離という問題

パブリッククラウドの FaaS や CaaS は、互いに信頼しない顧客 (テナント) のコードを、同じ物理マシンに同居させます。 Firecracker の論文は、この問題を「強いセキュリティと高いオーバーヘッドの仮想化か、弱いセキュリティと小さいオーバーヘッドのコンテナか、という選択を迫られる」と要約し、公開クラウドの提供者にはその二者択一が受け入れられない、と述べています。 runc のような通常のコンテナはホストカーネルを共有するので、カーネルの脆弱性 (Part 3 で見た CVE-2019-5736 のような) が顧客間の壁を破る可能性があるからです。

AWS と Google は、この問題にそれぞれ別の OSS で答えました。

どのサービスが、どの分離技術の上で動いているかAWS Lambda と Fargate (ECS / EKS) は Firecracker の microVM。GKE Sandbox、Cloud Run の第 1 世代、App Engine は gVisor。Cloud Run 第 2 世代と GKE Sandbox の microVM 版は microVM (フル Linux 互換)。Firecracker と gVisor はどちらも OSS として公開されている。AWSAWS LambdaFargate (ECS / EKS)FirecrackermicroVM / Rust / KVMgithub.com/firecracker-microvmKata Containers や Flintlock も採用Google CloudGKE SandboxCloud Run (第 1 世代)gVisorrunsc / Sentry / GoApp Engine も gVisor (利用者一覧)Cloud Run (第 2 世代)microVM、フル Linux 互換GKE Sandbox (microVM 版)入れ子の仮想化が要るGoogle も用途により microVM を選ぶ。「どちらか一方」ではない。
図 2AWS Lambda / Fargate は Firecracker の microVM。GKE Sandbox / Cloud Run 第 1 世代 / App Engine は gVisor。どちらも OSS として読める。

AWS の Firecracker は前の章で見た通り、KVM ベースの microVM です。 顧客の関数や task ごとに VM を立て、別のゲストカーネルで隔てます。

Google の gVisorジーバイザーコンテナの syscall をユーザー空間で動く Go 製のカーネル (Sentry) が受け取って処理する、サンドボックス化されたコンテナランタイム。用語集で見る は、gVisor 自身の説明では「Linux に似たインターフェースを実装した、Go で書かれてユーザー空間で動くアプリケーションカーネル」です。 runsc という OCI ランタイムがコンテナを起動し、Sentry というユーザー空間の「カーネル」がコンテナのシステムコールを受け取って自分で処理します。 コンテナが open() や read() を呼ぶと、それを受け取るのは Sentry で、ホストの Linux には届きません。 Sentry は必要なときだけ、種類を絞ったシステムコールでホストに頼みます。 ホストのカーネルに届くシステムコールが減るので、コンテナがホストを攻撃する面が狭くなります。

gVisor のドキュメントによると、Sentry はファイルの操作を自分では行わず、Gofer という別のホストプロセスに 9P プロトコルで頼みます。 Sentry 自身も seccomp で絞られた中で動くので、Sentry が破られても、ホストのファイルを直接開くことはできません。 gVisor は自らを、VM でも seccomp のような規則ベースの絞り込みでもない「第 3 の方式」と位置づけています。 gVisor の利用者一覧には、Google Cloud の GKE Sandbox、Cloud Run、App Engine が載っています。

Firecracker の microVM スタックと gVisor のサンドボックス左: ホストの Linux + KVM の上に Firecracker (Rust の VMM) が microVM を作り、その中にゲストカーネル、containerd、runc、コンテナが載る。右: ホスト Linux の上で runsc が Sentry (ユーザー空間のカーネル) を起動し、コンテナのシステムコールを Sentry が受け、ファイルアクセスは Gofer を通す。Firecracker (AWS Lambda / Fargate)ホストマシン (Lambda では EC2 ベアメタル)ホスト Linux + KVMFirecracker VMM (Rust、ユーザー空間)jailer + seccomp で囲うゲストカーネル (microVM 専用、デバイスは 5 種)containerd + runc (firecracker-containerd)コンテナ (task / 関数)分離の仕組み = VM ごとに専用のカーネル。起動 125 ms 未満、1 VM あたり 5 MiB 未満のオーバーヘッド。gVisor (GKE Sandbox / Cloud Run 第 1 世代)ホスト (GKE ならノードの VM。任意の Linux でも)ホスト Linux カーネルrunsc (OCI runtime)platform: systrap (既定) / KVMSentry (Go で書かれたユーザー空間カーネル)syscall を受けて自分で処理Gofer (ファイルアクセスを仲介)コンテナ分離の仕組み = Sentry が syscall を処理する。ホストに届くsyscall を大幅に減らす。VM は作らない。
図 3Firecracker は VM ごとに別のカーネルを動かし、gVisor はコンテナの syscall をユーザー空間の Sentry が処理する。分離の仕組みが違う。

分離の層を数える

Firecracker は顧客ごとに VM を起動して隔て、gVisor は VM を作らずにホスト上で動きます。 この 2 つを「どちらが強いか」で比べる前に、それぞれが何と何の間に置かれているかを、公開資料で数えられる範囲で数えます。

分離の層を数える: EKS on Fargate と GKE Sandbox左: EKS on Fargate では、AWS のホストの上に Pod ごとの VM (Firecracker の microVM) が並び、Pod とホストの間の境界はその VM。右: GKE Sandbox では、Google のホストの上に顧客のノードである Compute Engine の VM があり、その中で gVisor (runsc + Sentry) が Pod とノードカーネルの間にもう 1 枚の境界を置く。EKS on Fargate: Pod ごとに VMAWS のホスト (ホスト OS は AWS のもの)VM ×多数 (Pod ごとに 1 つ、専用カーネル)顧客 A の Pod | 顧客 B の Pod | …kubelet + コンテナ (Pod)Pod とホストの間の境界 = VM が 1 枚。「各 Pod は VM の中に隔てられる」(EKS の公開資料)。Lambda も同じ作りで、ワーカーは EC2 ベアメタル (論文)。GKE Sandbox: ノードの VM の中に gVisorGoogle のホスト (物理マシン)Compute Engine の VM = あなたのノード顧客ごとに別の VM。ここが顧客間の境界gVisor (runsc + Sentry)Pod とノードカーネルの間の境界コンテナ (Pod)境界は 2 枚。gVisor が守るのは、あなたのノードのカーネル。「信頼できないコードからホストのカーネルを守る」(GKE の公開資料)。Cloud Run の下でどう顧客を分けているかは公開されていない。
図 4EKS on Fargate は Pod ごとに VM を 1 つ。GKE Sandbox は、顧客のノード (Compute Engine の VM) の中で gVisor が Pod とノードのカーネルを隔てる。

EKS on Fargate では、ドキュメントの通り「各 Pod が VM の中に隔てられ」、ホスト OS は AWS のものです。 顧客の Pod とホストの間にある境界は、その VM の 1 枚です。 Lambda も同じで、論文によるとワーカーは EC2 のベアメタルで、microVM 1 つに顧客 1 つの関数 1 つが入ります。

GKE Sandbox では、ノードは顧客のプロジェクトにある Compute Engine の VM で、その VM の中で gVisor が動きます。 GKE のドキュメントは、GKE Sandbox の目的を「信頼できないワークロードのコードをカーネルから隔てて、ホストのカーネルを守る」ことだと説明しています。 ここで守られる「ホスト」はノードの VM、つまり顧客自身のノードです。 顧客同士を隔てているのは、その下で Compute Engine の VM を分けている Google の仮想化の層で、gVisor はその内側で、同じノードの Pod 同士と、Pod とノードカーネルの間に 2 枚目の境界を足しています。

Cloud Run のように複数の顧客のコンテナを Google 側のマシンで動かすサービスでは、第 1 世代が gVisor、第 2 世代が microVM だと公開されています。 その下で顧客ごとにマシンや VM をどう分けているかは公開されていません。 したがって、「Google はなぜ gVisor で足りると判断したのか」を公式の説明として確かめる手段はありません。 確かめられるのは、両社とも境界を 1 枚で済ませていない (Fargate は VM と task の分離、GKE Sandbox は VM と gVisor) ことと、どの層に何枚の境界を置くかが、各社のサービスごとに違うことです。 「顧客や Pod を隔てる仕組みを、何段、どの層に置くか」という問いの立て方は、自分の基盤を設計するときにそのまま使えます。

自分の基盤に持ち帰る

この章の問いを、手元のクラスタに向けてみます。 「このクラスタの Pod 同士は、何で分離されているか」。 答えは普通「同じカーネルを共有し、namespace と cgroup で分かれているだけ」です。 それで十分かどうかは、誰のコードが動くかで決まります。

全部自分のチームのコードなら、runc で十分です。 CI のジョブや、外部から受け取ったプラグインを動かすなら、RuntimeClass で gVisor や Kata Containers (Firecracker を VMM に使える) を指定し、その Pod だけ隔離を強める選択肢があります。 GKE なら、RuntimeClass に gvisor か microvm を書くだけで GKE Sandbox が使えます。 この教材の Web ターミナル も gVisor で動いていて、Part 3 で「Web ターミナルでは unshare や runc が動かないことがある」と注意したのはそのためです。

ふりかえり

QAWS の AZ と GCP の zone の、公開資料上の定義の違いは?

AWS は AZ を「数 km 以上離れ、電源や冷却が独立した 1 つ以上のデータセンター」と定義しています。Google は zone を「リージョン内の配置先で、単一の障害ドメイン」とし、zone と region は「物理資源の論理的な抽象」だと説明しています。

QFirecracker と gVisor の分離の仕組みの違いは?

Firecracker は KVM ベースの microVM で、ゲストカーネルが別に動きます。gVisor は VM を作らず、Sentry (Go 製のユーザー空間プログラム) がシステムコールを処理します。gVisor にも KVM platform はありますが、既定は systrap です。

QGKE Sandbox の gVisor は、何と何の間に境界を置く?

GKE のノードは顧客のプロジェクトの Compute Engine VM で、GKE Sandbox はその VM の中で動きます。守るのはノードのカーネルで、顧客同士を分けているのはその下の Compute Engine の仮想化です。

参考