ハードウェア基礎 #7 仮想化とコンテナ — 物理サーバー 1 台が複数台になる仕組み

読了 6分

#6 まで、1 台のサーバーを構成する 4 つのリソースをすべて見ました。ところがクラウドは物理サーバー 1 台を数十台のように分けて売ります。EC2 インスタンス 1 つがまるごと物理サーバーであるはずはありません。この分割を可能にするのが仮想化で、その上でさらに軽く分ける方式がコンテナです。今回はその仕組みを整理します。

ハードウェア基礎 シリーズでの今回の位置です。

なぜ 1 台を分けるのか #

1 台の物理サーバーは、たいてい普段はリソースが余っています。1 つのサービスが CPU とメモリを常に使い切ることはまれです。サービスごとにサーバーを 1 台ずつ買えば、余るリソースの分だけお金が遊びます。

仮想化はこの余るリソースを集めて、1 台を複数の独立した環境に分けます。各環境は自分だけのサーバーのように見え、互いに隔離されます。稼働率が上がり、環境を分単位で作って消せるようになります。クラウドの「必要なだけ借りて使う」を可能にした土台がまさにこれです。

仮想化 — ハイパーバイザーがハードウェアを分ける #

物理サーバーの上に ハイパーバイザー (Hypervisor) という層を置き、その上に複数の 仮想マシン (VM) を乗せます。ハイパーバイザーは物理リソースを切って各 VM に分け与え、VM 同士が互いに侵せないように隔離します。

各 VM は 自分だけのオペレーティングシステムをまるごと持ちます。 VM から見れば本物のハードウェアの上で動いているように見え、その中に Linux なり Windows なりを別途インストールします。EC2 インスタンス 1 つがまさにこの VM 1 つに相当します。

仮想化 — VM は OS を各自持つ
┌──────────┐ ┌──────────┐ ┌──────────┐
│  アプリ A │ │  アプリ B │ │  アプリ C │
│  OS      │ │  OS      │ │  OS      │   ← VM ごとに OS 1 つ
└──────────┘ └──────────┘ └──────────┘
        ハイパーバイザー
        物理サーバー (CPU・メモリ・ストレージ・ネットワーク)

VM は隔離が強いです。1 つの VM の中で何が起きても、他の VM と物理サーバーへの影響はほぼありません。代わりに OS をまるごと乗せるのでメモリとディスクを多く使い、起動に時間がかかります。

コンテナ — OS カーネルを共有する #

コンテナは別の道を選びます。OS を VM ごとに別々に持たず、ホストの OS カーネルを複数のコンテナが共有 します。コンテナはその上でプロセス単位に隔離されるだけで、自分の OS をまるごと持ちません。

コンテナ — カーネルを共有する
┌──────┐ ┌──────┐ ┌──────┐
│アプリA│ │アプリB│ │アプリC│   ← OS なしでアプリと依存だけ
└──────┘ └──────┘ └──────┘
   コンテナランタイム
   共有 OS カーネル
   物理サーバーまたは VM

OS 1 つを共有するのでコンテナは軽いです。メモリを少なく使い、起動が数十秒ではなく一瞬です。同じサーバーに VM よりはるかに多く乗せられます。この軽さが DockerKubernetes が定着した理由です。代わりにカーネルを共有するので隔離は VM より弱いです。

項目仮想マシン (VM)コンテナ
OSVM ごとに 1 つホストカーネルを共有
重さ重い (GB 単位)軽い (MB 単位)
起動時間数十秒数秒以内
隔離強い相対的に弱い
1 サーバーに乗せる数数個~数十個数十~数百個

実務では 2 つを重ねて使います。クラウドが物理サーバーを VM (インスタンス) に分けて貸し、ユーザーはそのインスタンスの中でさらにコンテナを複数動かします。

リソースはどう分けられ上限が掛かるか #

分けた環境がリソースを取り合わないためには、各自の取り分に上限が必要です。Linux は cgroups という機能でプロセスグループごとに CPU・メモリ・入出力の上限を掛けます。コンテナのリソース制限がこの上で動作します。

  • CPU#2 の vCPU がここで分かれます。インスタンスに割り当てられた vCPU を、その中のコンテナたちが上限の範囲で分けて使います。
  • メモリ#3 で押さえたとおり、コンテナにメモリ上限を掛けなければ 1 つがホストのメモリを飲み込んで他のコンテナまで脅かします。上限を超えるとそのコンテナのプロセスが終了します。

オーバーコミットとノイジーネイバー #

仮想化の稼働率には影があります。クラウド事業者は物理リソースより多い量を各 VM に約束することもあります。すべての VM が同時にリソースを使い切ることはないという前提の上でです。これを オーバーコミット (overcommit) と言います。

普段は問題ありませんが、同じ物理サーバーに乗った別の VM が急にリソースを使い込むと、自分の VM の性能が揺れます。この現象を ノイジーネイバー (noisy neighbor) と言います。「昨日は問題なかったインスタンスが今日は遅い」の 1 つの原因です。

性能が揺れてはいけないワークロードは、リソースを独占するインスタンスの種類を選ぶか、1 つの物理サーバーをまるごと借りる専用オプションを使います。こうした選択は #9 のインスタンス種類の決定とつながります。

よく出会う落とし穴 #

「コンテナは軽い VM だ」 #

似て見えますが違います。VM は OS をまるごと持って隔離が強く、コンテナはカーネルを共有して軽いものの隔離が弱いです。隔離の水準が重要なワークロードはこの違いを見極める必要があります。

「コンテナに上限を掛けなかった」 #

上限がなければ 1 つのコンテナがホストのリソースを独占して他のコンテナを飢えさせます。運用では CPU とメモリの上限を明示するのが安全です。

「インスタンスの性能がばらつくが原因がわからない」 #

オーバーコミット環境のノイジーネイバーかもしれません。一貫した性能が必要なら、リソースを独占する種類や専用インスタンスを検討します。

「VM の上にコンテナは無駄だ」 #

むしろ標準です。クラウドインスタンス (VM) の強い隔離の上に、その中でコンテナの軽いデプロイを一緒に得る構成です。

まとめ #

今回つかんだ絵です。

  • 仮想化は余るリソースを集めて、1 台の物理サーバーを複数の独立した環境に分けます。
  • ハイパーバイザー がハードウェアを分け、各 VM は自分の OS をまるごと持ちます。EC2 インスタンスがその VM です。
  • コンテナ はホストカーネルを共有して軽いものの、隔離は VM より弱いです。DockerKubernetes の土台です。
  • リソースは cgroups で上限が掛かります。コンテナのメモリ上限は明示するのが安全です。
  • オーバーコミットノイジーネイバー はクラウドの性能が揺れる 1 つの原因です。

次回 — クラウド #

仮想化はクラウドがリソースを分けて売る土台でした。これからその上の絵、クラウド自体を整理します。#8 クラウド — 所有から賃借へ、オンプレミスから IaaS / PaaS / SaaS まで では、ハードウェアを所有から賃借へ変えた変化、オンプレミスとコロケーションとクラウドの違い、そして IaaS・PaaS・SaaS がハードウェアをどこまで見えなくするかを整理します。

X