画像

仮想マシンとコンテナという2つの仮想化の形

Linuxは、物理的なハードウェア上で直接動作するだけでなく、さまざまな形の「仮想化されたゲスト」としても動作します。代表的な形態は次の2つです。

種類仕組み特徴
仮想マシン(VM)ハイパーバイザーが仮想的なハードウェアまたは実行環境を提供し、その上で完全に独立したOS(カーネルを含む)を動かすホストと異なるOS・カーネルを動かせる。分離レベルが高い分、オーバーヘッドも大きい
コンテナホストのカーネルを共有しつつ、プロセスやファイルシステムの名前空間を分離し、あたかも独立した環境であるかのように見せるホストと同じカーネルを使うため軽量・高速だが、ホストと異なるカーネルは使えない

コンテナには、OS全体に近い環境を提供する用途で使われるLinuxコンテナ(LXC等)と、単一のアプリケーションとその依存関係をパッケージ化する用途で使われるアプリケーションコンテナ(Docker等)があります。これは厳密な技術上の二分ではなく、主な用途・運用形態による区別です。

ハイパーバイザーの種類

仮想マシンを動かす基盤となるソフトウェアをハイパーバイザーと呼び、大きく2種類に分類されます。

種類動作する場所代表例
Type 1(ベアメタル型)ハードウェア上に直接インストールされ、通常のホストOSを必要としないXen、VMware ESXi、Hyper-V
Type 2(ホスト型)既存のOS(ホストOS)の上にアプリケーションとして動作するVirtualBox、QEMU(単体)、VMware Workstation

KVMはLinuxカーネルの機能として動作するためLinuxホストを必要とします。KVMをType 1として扱う資料もありますが、Type 1/Type 2の分類は定義によって異なるため、KVMについては分類だけでなくLinuxカーネル上で動作する点を押さえます。

Type 1はデータセンター・クラウド基盤など性能・分離性が重視される用途で、Type 2はデスクトップでの開発・検証用途でよく使われます。

Dockerの基本操作

Dockerは、アプリケーションと実行環境をコンテナとして分離・実行するための仕組みです。
Dockerイメージはコンテナのひな型で、Docker Hubなどのレジストリから取得できます。

基本用語

用語説明
イメージコンテナ作成に使用する読み取り専用のテンプレート
コンテナイメージから作成された実行環境
ボリュームコンテナ削除後もデータを保持する領域
レジストリDockerイメージを保存・配布するサービス

基本的な操作例

systemctl status docker                  # Dockerサービスの状態確認
sudo systemctl start docker              # Dockerサービスの起動
docker pull nginx:latest                 # nginxイメージの取得
docker image ls                          # イメージ一覧の表示
docker run -d --name web -p 8080:80 nginx    # nginxコンテナをオプション付きで起動
docker container ls                      # 実行中のコンテナ一覧
docker container ls -a                   # 停止中を含む一覧
docker logs -f web                       # ログをリアルタイム表示
docker exec -it web /bin/sh              # コンテナ内でシェルを実行
docker stop web && docker rm web         # 停止して削除
docker image rm nginx:latest             # イメージの削除

ブラウザで http://localhost:8080 を開くと、nginxの画面を確認できます。

docker runでよく使うオプション

オプション使用例・意味
-dバックグラウンドで実行
--name webコンテナ名を指定
-p 8080:80ホストの8080番をコンテナの80番へ転送
-v data:/var/lib/appボリュームをマウント
-e KEY=value環境変数を設定
--rmコンテナ終了時に自動削除
--restart unless-stoppedDocker再起動後も自動起動

IaaSクラウドの一般的な構成要素

パブリッククラウドの多くは、IaaS(Infrastructure as a Service)として、次のような構成要素を組み合わせて仮想的なインフラを提供しています。

  • コンピューティングインスタンス:仮想マシンそのもの。CPU・メモリのサイズ(インスタンスタイプ)を選んで起動する。
  • ブロックストレージ:インスタンスに接続する仮想ディスク。インスタンス本体とは独立してアタッチ・デタッチできることが多い。
  • ネットワーキング:仮想ネットワーク、サブネット、ファイアウォール(セキュリティグループ)等、インスタンス間・外部との通信を制御する仕組み。

クローン・テンプレート化の際に変更が必要な項目

仮想マシンのイメージをそのまま複製(クローン)して複数台を起動すると、本来は各ホストで一意であるべき値が重複してしまう問題が起こります。テンプレートから新しいインスタンスを作成する際は、次のような項目を変更(再生成)する必要があります。

項目重複するとどうなるか
SSHホスト鍵同じ鍵を持つ複数のホストが存在すると、ホストの識別ができなくなり、SSHの信頼モデルが損なわれる。接続先のホスト名またはIPアドレスに対してknown_hostsに記録済みの鍵と異なる鍵が提示された場合は、「中間者攻撃の可能性」の警告が出る
マシンID(/etc/machine-id)システムを一意に識別するIDが重複し、一部のsystemd関連の仕組み(ログの管理等)で問題が生じる可能性がある
ホスト名・固有のネットワーク設定同じ名前が名前解決や管理上の識別に使われる環境では混乱し、IPアドレスが重複すると通信が競合する

クラウド向けに作成されたイメージでは、cloud-init(後述)やクラウド基盤側の仕組みにより、初回起動時にこれらの値の一部を設定・再生成することがあります。対象となる項目はイメージ、cloud-initの設定、クラウド基盤によって異なるため、独自に作成したテンプレートでは必要な値を事前に確認して初期化します。

cloud-init:クラウドインスタンスの起動時の自動設定

cloud-initは、クラウドインスタンスの初期設定を自動的に行う業界標準の仕組みです。主要なパブリッククラウド・プライベートクラウド基盤の多くで共通して使われています。

cloud-initが自動的に行う代表的な設定には、次のようなものがあります。

  • ホスト名の設定
  • SSH公開鍵の登録(クラウド基盤側で指定した鍵を、インスタンス内の該当ユーザーの~/.ssh/authorized_keysに反映する)
  • 初期ユーザーアカウントの作成
  • ネットワーク設定の適用
  • 起動時に実行する「user-data」(利用者が指定したスクリプトや設定)の実行

各設定やuser-dataの実行タイミングは、cloud-initのモジュール、イメージの設定、クラウド基盤のデータソースに依存します。初回のみ実行される処理もあれば、起動ごとに実行される処理もあります。

これにより、利用者はイメージを起動するだけで、個別のログイン・手動設定を行うことなく、すぐに利用可能な状態のインスタンスを得られます。

仮想化製品との統合:ゲストドライバー

仮想マシンのゲストOSとして動作するLinuxは、ハイパーバイザーが提供する準仮想化デバイス(ディスク・ネットワーク等を、エミュレーションより高速に扱うための仕組み)を利用します。たとえばvirtioドライバー群はLinuxカーネルに含まれていることが多いドライバーです。また、VMware ToolsやQEMU Guest Agentは、ゲストOSとハイパーバイザーの連携を強化するためのゲスト統合ツール/エージェントです。利用できる機能は製品や構成により異なり、正常なシャットダウンの通知、ゲスト情報の取得、クリップボード共有、時刻同期などが提供されることがあります。

仮想化環境の検出:systemd-detect-virt

systemd-detect-virtは、systemdを使用する環境で、現在実行している環境が仮想化されているかどうかを検出するコマンドです。対応している仮想化技術であれば、KVM、Xen、Docker、LXC等を検出できます。

オプション効果
(オプション無し)検出した仮想化技術の名前を表示する(例:kvm、docker)
-vハードウェア仮想化(VM)のみを検出対象にする
-cコンテナ仮想化(カーネル共有型)のみを検出対象にする
systemd-detect-virt
# kvm