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 は、公開資料では「リージョン内にある、冗長な電源、ネットワーク、接続性を持つ 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 の 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 は顧客ごとに VM を起動して隔て、gVisor は VM を作らずにホスト上で動きます。 この 2 つを「どちらが強いか」で比べる前に、それぞれが何と何の間に置かれているかを、公開資料で数えられる範囲で数えます。
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 の仮想化です。
参考
- Regions and Availability Zones (AWS Global Infrastructure)
- Regions and Zones (Amazon EC2 User Guide)
- Geography and regions (Google Cloud)
- Regions and zones (Compute Engine)
- Borg: The Predecessor to Kubernetes (Kubernetes Blog, 2015)
- Overview (Kubernetes Documentation, Concepts)
- Firecracker: Lightweight Virtualization for Serverless Applications (NSDI 2020)
- What is gVisor? (gVisor documentation)
- gVisor Platforms (gVisor documentation)
- gVisor Users
- About GKE Sandbox (Google Kubernetes Engine)
- Select an execution environment for services (Cloud Run)
- Simplify compute management with AWS Fargate (Amazon EKS User Guide)