- Authors

- Name
- Youngju Kim
- @fjvbn20031
仮想マシン:ハイパーバイザーからコンテナまで
仮想化技術は1台の物理マシン上に複数の独立した実行環境を作成し、リソース活用度を高めて隔離を提供します。この記事では、従来のハイパーバイザーベースVMから現代的なコンテナまで解説します。
1. 仮想マシンの利点
┌──────────────────────────────────────────┐
│ VMの主要利点 │
│ │
│ 隔離(Isolation): │
│ - VM間の完全な隔離 │
│ - 1つのVM障害が他のVMに影響しない │
│ │
│ 統合(Consolidation): │
│ - 複数サーバーを1台の物理マシンに統合 │
│ - ハードウェア活用率向上(15% → 70%+) │
│ │
│ 移植性(Portability): │
│ - VMイメージを他のホストに移動可能 │
│ - ハードウェア独立 │
│ │
│ 開発/テスト: │
│ - 多様なOS環境を同時運用 │
│ - スナップショットで高速復元 │
│ │
│ セキュリティ: │
│ - 疑わしいソフトウェアをVMで実行 │
│ - 侵害時にVMのみ廃棄 │
└──────────────────────────────────────────┘
2. Type 1ハイパーバイザー(Bare-Metal)
物理ハードウェア上で直接実行されるハイパーバイザーです。
┌────────────┐ ┌────────────┐ ┌────────────┐
│ Guest OS 1 │ │ Guest OS 2 │ │ Guest OS 3 │
│ (Linux) │ │ (Windows) │ │ (FreeBSD) │
├────────────┤ ├────────────┤ ├────────────┤
│ 仮想 HW │ │ 仮想 HW │ │ 仮想 HW │
└──────┬─────┘ └──────┬─────┘ └──────┬─────┘
│ │ │
┌──────┴──────────────┴──────────────┴──────┐
│ Type 1 ハイパーバイザー │
│ (VMware ESXi, Xen, Hyper-V, KVM) │
├───────────────────────────────────────────┤
│ 物理ハードウェア │
└───────────────────────────────────────────┘
| 名前 | 開発元 | 特徴 |
|---|---|---|
| VMware ESXi | VMware | エンタープライズ市場リーダー |
| KVM | Linuxカーネル | Linuxカーネルモジュール、OSS |
| Xen | Linux Foundation | 準仮想化の先駆者、初期AWS使用 |
| Hyper-V | Microsoft | Windows Server統合 |
3. Type 2ハイパーバイザー(Hosted)
既存のオペレーティングシステム上で実行されるハイパーバイザーです。
┌────────────┐ ┌────────────┐
│ Guest OS 1 │ │ Guest OS 2 │
├────────────┤ ├────────────┤
│ 仮想 HW │ │ 仮想 HW │
└──────┬─────┘ └──────┬─────┘
│ │
┌──────┴──────────────┴───────────┐
│ Type 2 ハイパーバイザー │
│ (VirtualBox, VMware Workstation)│
├─────────────────────────────────┤
│ ホストOS (macOS等) │
├─────────────────────────────────┤
│ 物理ハードウェア │
└─────────────────────────────────┘
Type 1 vs Type 2 比較
| 特性 | Type 1 | Type 2 |
|---|---|---|
| 実行場所 | ハードウェア直接 | ホストOS上 |
| 性能 | 高い(低オーバーヘッド) | 普通(ホストOS経由) |
| 用途 | サーバー、クラウド | 開発/テスト、デスクトップ |
| 隔離レベル | 高い | 普通 |
4. ハードウェア支援仮想化
VT-x(Intel Virtualization Technology)
ハードウェアレベルで仮想化をサポートし効率性を高めます。
ソフトウェア仮想化(バイナリ変換):
┌─────────────────────────────────┐
│ Guest OSが特権命令を実行 │
│ ↓ │
│ ハイパーバイザーがトラップ │
│ ↓ │
│ バイナリ変換でエミュレーション │
│ → オーバーヘッド大 │
└─────────────────────────────────┘
ハードウェア支援仮想化(VT-x):
┌─────────────────────────────────┐
│ VMX rootモード(ハイパーバイザー)│
│ VMX non-rootモード(Guest OS) │
│ │
│ Guest OSが特権命令を実行 │
│ ↓ │
│ VM Exit → ハイパーバイザーへ │
│ ↓ │
│ ハイパーバイザー処理 │
│ ↓ │
│ VM Entry → Guest OSに復帰 │
│ → ハードウェアが切替処理、高速 │
└─────────────────────────────────┘
メモリ仮想化 - EPT(Extended Page Tables)
ソフトウェア方式(Shadow Page Table):
ゲスト仮想 → ゲスト物理(ゲストページテーブル)
ゲスト物理 → ホスト物理(ハイパーバイザー管理)
→ 2回の変換が必要
ハードウェア方式(EPT / AMD NPT):
ゲスト仮想 → ゲスト物理 → ホスト物理
↑ CPUが自動変換
→ ハイパーバイザー介入なしにハードウェアが直接処理
5. 準仮想化(Paravirtualization)
Guest OSのカーネルを修正してハイパーバイザーと直接通信する方式です。
完全仮想化: 準仮想化:
Guest OS(修正なし) Guest OS(修正済み)
│ │
├→ 特権命令実行 ├→ ハイパーコール(Hypercall)
├→ Trap(ハードウェア) ├→ 直接ハイパーバイザー呼出
└→ ハイパーバイザーエミュレーション └→ ハイパーバイザー処理
準仮想化の利点: より高速(Trapオーバーヘッドなし)
準仮想化の欠点: Guest OSカーネルの修正が必要
// Xen 반가상화 하이퍼콜 예시 (의사 코드)
// 반가상화: 하이퍼콜 사용
void disable_interrupts_paravirt() {
HYPERVISOR_event_channel_op(EVTCHNOP_mask, &mask_params);
}
void update_page_table_paravirt(pte_t *pte, pte_t new_val) {
HYPERVISOR_mmu_update(&mmu_update, 1, NULL, DOMID_SELF);
}
6. コンテナ(Containers)
コンテナはOSレベルの仮想化で、カーネルを共有しながらプロセスを隔離します。
VM vs コンテナ
VM: コンテナ:
┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐
│App A │ │App B │ │App C │ │App A │ │App B │ │App C │
├──────┤ ├──────┤ ├──────┤ ├──────┤ ├──────┤ ├──────┤
│Bins/ │ │Bins/ │ │Bins/ │ │Bins/ │ │Bins/ │ │Bins/ │
│Libs │ │Libs │ │Libs │ │Libs │ │Libs │ │Libs │
├──────┤ ├──────┤ ├──────┤ └──┬───┘ └──┬───┘ └──┬───┘
│GuestOS│ │GuestOS│ │GuestOS│ │ │ │
└──┬───┘ └──┬───┘ └──┬───┘ ┌──────┴───────┴───────┴──────┐
┌──┴────────┴────────┴──┐ │ コンテナランタイム │
│ ハイパーバイザー │ │ (Docker Engine) │
├───────────────────────┤ ├──────────────────────────────┤
│ ホストOS │ │ ホストOS │
├───────────────────────┤ │ (カーネル共有) │
│ 物理ハードウェア │ ├──────────────────────────────┤
└───────────────────────┘ │ 物理ハードウェア │
└──────────────────────────────┘
VM: OS全体含む(GB単位) コンテナ: アプリ+ライブラリのみ(MB単位)
起動: 分単位 開始: 秒単位
Docker基本使用法
# Docker 이미지 빌드
# Dockerfile 예시
# FROM ubuntu:22.04
# RUN apt-get update && apt-get install -y nginx
# COPY index.html /var/www/html/
# EXPOSE 80
# CMD ["nginx", "-g", "daemon off;"]
docker build -t my-nginx .
docker run -d -p 8080:80 --name web my-nginx
docker ps
docker logs web
docker stop web
docker rm web
コンテナの隔離技術(Linux)
┌──────────────────────────────────────────────┐
│ Linuxコンテナ隔離技術 │
│ │
│ Namespaces(隔離): │
│ ┌────────────┬───────────────────────────┐ │
│ │ PID │ プロセスID隔離 │ │
│ │ NET │ ネットワークスタック隔離 │ │
│ │ MNT │ ファイルシステムマウント隔離│ │
│ │ UTS │ ホスト名隔離 │ │
│ │ IPC │ IPCリソース隔離 │ │
│ │ USER │ ユーザー/グループID隔離 │ │
│ │ CGROUP │ cgroupビュー隔離 │ │
│ └────────────┴───────────────────────────┘ │
│ │
│ Control Groups(cgroups - リソース制限): │
│ ┌────────────┬───────────────────────────┐ │
│ │ CPU │ CPU使用量制限 │ │
│ │ Memory │ メモリ使用量制限 │ │
│ │ I/O │ ディスクI/O帯域幅制限 │ │
│ │ Network │ ネットワーク帯域幅制限 │ │
│ └────────────┴───────────────────────────┘ │
└──────────────────────────────────────────────┘
// 네임스페이스를 이용한 프로세스 격리 (의사 코드)
#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define STACK_SIZE (1024 * 1024)
int child_func(void *arg) {
printf("Child PID (in namespace): %d\n", getpid());
sethostname("container", 9);
execl("/bin/bash", "bash", NULL);
return 0;
}
int main() {
char *stack = malloc(STACK_SIZE);
int flags = CLONE_NEWPID | CLONE_NEWUTS | CLONE_NEWNS;
pid_t pid = clone(child_func, stack + STACK_SIZE, flags, NULL);
printf("Child PID (in parent): %d\n", pid);
waitpid(pid, NULL, 0);
free(stack);
return 0;
}
Kubernetes概要
コンテナオーケストレーションプラットフォームで、大規模コンテナのデプロイと管理を自動化します。
┌──────────────────────────────────────────────────┐
│ Kubernetes クラスター │
│ │
│ Control Plane(マスター): │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ API │ │ Scheduler│ │ Controller│ │
│ │ Server │ │ │ │ Manager │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ ┌──────────┐ │
│ │ etcd │ ← クラスター状態ストア │
│ └──────────┘ │
│ │
│ Worker Nodes: │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Node 1 │ │ Node 2 │ │
│ │ ┌─────┐ ┌─────┐│ │ ┌─────┐ ┌─────┐│ │
│ │ │Pod A│ │Pod B││ │ │Pod C│ │Pod D││ │
│ │ └─────┘ └─────┘│ │ └─────┘ └─────┘│ │
│ └─────────────────┘ └─────────────────┘ │
└──────────────────────────────────────────────────┘
7. アプリケーション隔離
セキュリティ強化のための多層隔離
┌─────────────────────────────────────┐
│ 隔離レベルの比較 │
│ │
│ VM: 強い隔離 │
│ │ (ハイパーバイザー境界)│
│ gVisor: 中間隔離 │
│ │ (ユーザー空間カーネル)│
│ コンテナ: 基本隔離 │
│ │ (名前空間/cgroups) │
│ プロセス: 最小隔離 │
│ (同一カーネル共有) │
└─────────────────────────────────────┘
8. VMマイグレーション
実行中のVMを別の物理ホストに移動する技術です。
ライブマイグレーション過程
ソースホスト 宛先ホスト
┌──────────────┐ ┌──────────────┐
│ VM(実行中) │ │ │
│ 1. メモリ │ │ │
│ ページ転送│───────────────→│ 受信 │
│ 2. ダーティ │ │ │
│ ページ │───────────────→│ 受信 │
│ 反復転送 │ │ │
│ 3. VM一時停止│ │ │
│ 残り転送 │───────────────→│ 受信 │
│ 4. VM停止 │ │ 5. VM再開 │
└──────────────┘ └──────────────┘
ダウンタイム: 数十〜数百ms(ほぼ無中断)
9. ユニカーネル(Unikernels)
アプリケーションと必要なOS機能のみを1つの単一アドレス空間イメージにコンパイルする軽量VMです。
通常のVM: ユニカーネル:
┌───────────┐ ┌───────────┐
│ App │ │ App │
├───────────┤ │ + 必要な │
│ ライブラリ│ │ OS機能 │
├───────────┤ │(単一バイ │
│ 完全OS │ │ ナリ) │
└─────┬─────┘ └─────┬─────┘
ハイパーバイザー ハイパーバイザー
サイズ: GB単位 サイズ: MB単位
起動: 秒単位 起動: ミリ秒単位
攻撃サーフェス: 広い 攻撃サーフェス: 非常に狭い
10. まとめ
- Type 1ハイパーバイザー: ハードウェア直接実行、サーバー/クラウド環境に最適
- Type 2ハイパーバイザー: ホストOS上で実行、開発/テスト環境に最適
- ハードウェア仮想化: VT-x、EPT等でオーバーヘッドを最小化
- 準仮想化: Guest OS修正でハイパーバイザーとの効率的な通信
- コンテナ: 軽量隔離、高速起動、Docker/Kubernetesエコシステム
- VMマイグレーション: ライブマイグレーションでほぼ無中断移動
- ユニカーネル: 極度に軽量化された特殊目的VM
クイズ:仮想マシン
Q1. Type 1とType 2ハイパーバイザーの違いは何ですか?
A1. Type 1は物理ハードウェア上で直接実行され(bare-metal)、オーバーヘッドが少なく性能に優れます。Type 2は既存のOSの上でアプリケーションとして実行されインストールが簡単ですが、ホストOSを経由するため追加のオーバーヘッドがあります。
Q2. コンテナがVMより軽い理由は何ですか?
A2. VMはそれぞれ完全なGuest OSを含みますが、コンテナはホストカーネルを共有しアプリケーションとライブラリのみパッケージングします。そのためコンテナイメージはMB単位で軽く、起動時間も秒単位で高速です。
Q3. ライブマイグレーションでダウンタイムを最小化する方法は?
A3. プレコピー(Pre-copy)方式では、VMが実行中にメモリページを転送し、変更された(dirty)ページを反復転送します。変更量が十分に減ると、VMを短時間停止して残りを転送し、宛先で再開します。これによりダウンタイムを数十ミリ秒レベルに削減できます。