Skip to content
Published on

[オペレーティングシステム] 18. 仮想マシン:ハイパーバイザーからコンテナまで

Authors

仮想マシン:ハイパーバイザーからコンテナまで

仮想化技術は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 ESXiVMwareエンタープライズ市場リーダー
KVMLinuxカーネルLinuxカーネルモジュール、OSS
XenLinux Foundation準仮想化の先駆者、初期AWS使用
Hyper-VMicrosoftWindows 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 1Type 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 EntryGuest 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        │ ホスト名隔離              │  │
│  │ IPCIPCリソース隔離           │  │
│  │ USER       │ ユーザー/グループID隔離   │  │
│  │ CGROUP     │ cgroupビュー隔離          │  │
│  └────────────┴───────────────────────────┘  │
│                                              │
Control Groups(cgroups - リソース制限):│  ┌────────────┬───────────────────────────┐  │
│  │ CPUCPU使用量制限             │  │
│  │ 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を短時間停止して残りを転送し、宛先で再開します。これによりダウンタイムを数十ミリ秒レベルに削減できます。