【Linux】KVM 入門

KVM を触る機会があったので備忘録を残しておきます。復習として Ubuntu 16.04 (Host OS) 上に KVM で CentOS7 (Guest OS) を立てます。

KVMと周辺技術

QEMU

QEMU は OSS のエミュレータで Type 2 hypervisors に分類される。アプリケーション型 VM で CPU エミュレーションの機能もあるが KVM と組み合わせる場合は主に Virtual I/O の機能を担う。Debian, Ubuntuの場合は qemu-kvm と呼ばれる Userspace tools を使う。語源は Quick Emulator という話がある。

KVM

KVM (Kernel-based Virtual Machine) は Linux Kernel に含まれる仮想化の機能で Kernel Module として提供される。Type 1 hypervisors に分類される。
KVM は QEMU の Virtual I/O 機能を使うが, CPUの仮想化支援機能 (virtualization specific CPU extensions) を使うことで高速化している。
kvm: the Linux Virtual Machine Monitor (Avi Kivity et al., 2007) によると KVM ではデバイスファイル /dev/kvm を通じて以下の操作が行われる。

  • 新しい VM の生成
  • VM へのメモリ割り当て
  • vcpu レジスタの read/write
  • vcpu への割り込みの挿入
  • vcpu の実行

Libvirt

Libvirt は仮想化のAPIを提供する管理用ツールキット。KVM, QEMU 以外にも Xen, Virtuozzo, VMWare ESX, LXC, BHyve などをサポートし, C, Python, Perl, Java といった言語でアクセスできる。

virsh

virsh は libvirt の API を利用しドメイン, ネットワーク, ストレージなどを管理できる interactive shell 環境を提供する。制御コマンドは約100種類ある。

KVMによる仮想環境の構築

今回は Ubuntu 16.04 (Host OS) 上に KVM で CentOS7 (Guest OS) を立てる。

ubuntu@ubuntu /home/ubuntu]$ cat /proc/version
Linux version 4.4.0-87-generic (buildd@lcy01-31) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4) ) #110-Ubuntu SMP Tue Jul 18 12:55:35 UTC 2017

qemu-kvm, libvirt, bridge-utils をインストールする。

ubuntu@ubuntu /home/ubuntu]$ sudo apt-get update
ubuntu@ubuntu /home/ubuntu]$ sudo apt install qemu-kvm libvirt0 libvirt-bin bridge-utils
ubuntu@ubuntu /home/ubuntu]$ libvirtd --version
libvirtd (libvirt) 1.3.1

サービスの自動起動を有効化。

ubuntu@ubuntu /home/ubuntu]$ sudo systemctl enable libvirt-bin
Synchronizing state of libvirt-bin.service with SysV init with /lib/systemd/systemd-sysv-install...
Executing /lib/systemd/systemd-sysv-install enable libvirt-bin

ubuntu@ubuntu /home/ubuntu]$ systemctl status libvirt-bin
● libvirt-bin.service - Virtualization daemon
   Loaded: loaded (/lib/systemd/system/libvirt-bin.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2018-10-23 23:28:53 JST; 24h ago
     Docs: man:libvirtd(8)
           http://libvirt.org
...

CentOS7 の ISO イメージを download しておく。

qemu-img コマンドでイメージファイルを作成する。今回はファイルフォーマットに qcow2 (QEMU Copy-On-Write 2)を指定した。

root@ubuntu:/# cd /var/lib/libvirt/images
root@ubuntu:/var/lib/libvirt/images# qemu-img create -f qcow2 centos7.qcow2 10G
Formatting 'centos7.qcow2', fmt=qcow2 size=10737418240 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16

virt-install コマンドで CentOS7 (Guest OS) をインストール。

ubuntu@ubuntu /home/ubuntu]$ sudo virt-install \
  --name centos7.qcow2 \
  --disk path=/var/lib/libvirt/images/centos7.qcow2,size=10 \
  --vcpus 2 \
  --ram 512 \
  --os-type linux \
  --graphics none \
  --console pty,target_type=serial \
  --network bridge:virbr0 \
  --location '/home/ubuntu/tmp/CentOS-7-x86_64-Minimal-1804.iso' \
  --extra-args 'console=ttyS0,115200n8 serial'

OSの初期設定後, ログインしインターネット接続できることを確認。

...
[  OK  ] Started NTP client/server.
[   22.508599] ip6_tables: (C) 2000-2006 Netfilter Core Team
[   22.755743] Ebtables v2.0 registered
[   22.859845] IPv6: ADDRCONF(NETDEV_UP): ens2: link is not ready
[   22.886116] 8139cp 0000:00:02.0 ens2: link up, 100Mbps, full-duplex, lpa 0x05E1
[   23.009772] nf_conntrack version 0.5.0 (3900 buckets, 15600 max)
[   23.252506] bridge: filtering via arp/ip/ip6tables is no longer available by default. Update your scripts to load br_netfilter if you need this.
[   23.342535] Netfilter messages via NETLINK v0.30.
[   23.368565] ip_set: protocol 6

CentOS Linux 7 (Core)
Kernel 3.10.0-862.el7.x86_64 on an x86_64

localhost login: root
Password:

[root@localhost ~]# curl -LI www.google.com -o /dev/null -w '%{http_code}\n' -s
200

Ubuntu 16.04 (Host OS) に戻り virsh コマンドで interactive shell に接続する。

ubuntu@ubuntu /home/ubuntu]$ virsh uri
qemu:///system

ubuntu@ubuntu /home/ubuntu]$ virsh --connect qemu:///system
Welcome to virsh, the virtualization interactive terminal.

Type:  'help' for help with commands
       'quit' to quit

virsh #

interactive shell でも後述の操作は可能だが, 今回は一度抜ける。

virsh list コマンドで VM 一覧を確認。

ubuntu@ubuntu /home/ubuntu]$ virsh list
 Id    Name                           State
----------------------------------------------------
 4     centos7.qcow2                  running

起動は virsh start, 終了は virsh shutdown, 強制終了は virsh destroy コマンドで行う。

ubuntu@ubuntu /home/ubuntu]$ virsh shutdown centos7.qcow2
Domain centos7.qcow2 is being shutdown

ubuntu@ubuntu /home/ubuntu]$ virsh list
 Id    Name                           State
----------------------------------------------------

ubuntu@ubuntu /home/ubuntu]$ virsh start centos7.qcow2
Domain centos7.qcow2 started

virsh console コマンドで Guest OS のコンソールに接続できる。

ubuntu@ubuntu /home/ubuntu]$ virsh console centos7.qcow2

コンソールからは ctrl + shift + [ で抜けれる。

ログイン中の Linux が物理か VM か確認する

How To Check If A Linux System Is Physical Or Virtual Machine を参考に VPS 上で dmidecode コマンドで確認する。

$ sudo dmidecode | egrep -i 'manufacturer|product'
        Manufacturer: QEMU
        Product Name: Standard PC (i440FX + PIIX, 1996)
        Manufacturer: Bochs
        Manufacturer: Bochs
        Manufacturer: Bochs

他の VPS では以下となった。

$ sudo dmidecode | egrep -i 'manufacturer|product'
        Manufacturer: Fedora Project
        Product Name: OpenStack Nova
        Manufacturer: QEMU
        Manufacturer: QEMU
        Manufacturer: QEMU
        Manufacturer: QEMU
        Manufacturer: QEMU

余裕があれば bridge-utils で仮想ブリッジを作成する方法を追記する。

[1] QEMU, a Fast and Portable Dynamic Translator (Fabrice Bellard, 2005)
[2] KVMとは
[3] QEMUで作成可能な仮想ディスクファイルフォーマットを比べてみた
[4] What’s the difference between Type 1 and Type 2 hypervisors?
[5] understanding relationship between Qemu and KVM
[6] How to detect virtualization