WSL2にKVM/QEMUを使った仮想環境構築

はじめに

WindowsVirtualboxを使って仮想環境を作成していたが、手間だったので、KVM/QEMUで簡易化ができるのではにないかと思い、実施する。

環境

  • Windows10(ホストOS)
  • WSL2
  • Ubuntu 22.04.3 LTS(WSL2上)
  • Ubuntu 22.04.3 LTS(KVM上)

構築

KVMのインストール

KVMをインストールする

$ sudo apt install -y libvirt-clients qemu-utils qemu-kvm libvirt-daemon libvirt-daemon-system

仮想環境が使用するイメージを作成

次に、cloud-initを使ってKVMで上で仮想環境を構築したいので、cloud-initで使用するcloudimgをダウンロードする。 https://cloud-images.ubuntu.com/releases/22.04/release/からcloudimgをダウンロードする。 保存先は/var/lib/libvirt/imagesとした。

#rootでログインして、ベースイメージのあるディレクトリへ移動
$ sudo -i
# cd /var/lib/libvirt/images

# curl -O https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img
# ls
ubuntu-22.04-server-cloudimg-amd64.img

次に仮想環境が使用するイメージを作成する。 ディスク容量は30Gとした。

# VMNAME=ubuntu22-vm1
## qemu-imgで扱えるように拡張子の変換
# qemu-img create -F qcow2 -b ubuntu-22.04-server-cloudimg-amd64.img -f qcow2 $VMNAME.qcow2 30G
Formatting 'id-vm1.qcow2', fmt=qcow2 size=53687091200 backing_file=ubuntu-20.04.1-server-cloudimg-amd64.img backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16

作成された .qcow2 は ubuntu-*.qcow2 をベースとし、ベースからの差分が書き込まれていく。 ベースイメージ .img は絶対に移動/削除しないこと。

イメージのメタデータを確認するには qemu-img info を使う。

# qemu-img info $VMNAME.qcow2
image: ubuntu22-vm1.qcow2
file format: qcow2
virtual size: 30 GiB (32212254720 bytes)
disk size: 196 KiB
cluster_size: 65536
backing file: ubuntu-22.04-server-cloudimg-amd64.img
backing file format: qcow2
Format specific information:
    compat: 1.1
    compression type: zlib
    lazy refcounts: false
    refcount bits: 16
    corrupt: false
    extended l2: false

作成したら root から抜けて一般ユーザ(ubuntu)に戻る。

# exit
logout
$ 

cloud-init用のuser-data/meta-dataの準備

cloud-init用のuser-data/meta-dataの準備する。 このイメージファイルにはcloud-initがインストールされており、外部から与えられたmeta-dataおよびuser-dataの設定に基いて、起動時にVMの各種初期化(ログインパスワードの設定、NICの設定、ファイルシステム設定、公開鍵の登録…など)を行うことができる。

# 作業用ディレクトリ作成
$ cd
$ mkdir -p cloud-init
$ cd cloud-init/

VMNAMEの変数をVM名に設定し、user-data/meta-dataを作成する下記コマンドを実行する。 VMNAMEの名前でディレクトリが作成され、cidata-(VM名).iso というISOイメージができる。 パスワードはubuntuとする。

#必要なライブラリをインストール
$ sudo apt install -y genisoimage

$ (
VMNAME=ubuntu22-vm1
mkdir -p $VMNAME
pushd $VMNAME
cat > user-data <<-EOS
#cloud-config
password: ubuntu
chpasswd: {expire: False}
ssh_pwauth: True
EOS
cat > meta-data <<-EOS
instance-id: $VMNAME
local-hostname: $VMNAME
EOS
genisoimage -output ../cidata-${VMNAME}.iso -volid cidata -joliet -rock user-data meta-data
popd
)

#出力
~/cloud-init/ubuntu22-vm1 ~/cloud-init
I: -input-charset not specified, using utf-8 (detected in locale settings)
Total translation table size: 0
Total rockridge attributes bytes: 331
Total directory bytes: 0
Path table size(bytes): 10
Max brk space used 0
183 extents written (0 MB)
~/cloud-init

VMの作成と起動

以下のVMを作成するためのシェルスクリプトを作成する。

$ cat > create-ubuntu22-vm1.sh << "EOF"
#!/bin/bash

# VM name
VMNAME=ubuntu22-vm1
# # of vCPUs assigned to the VM
VCPUS=2
# RAM size assigned to the VM
RAMSIZE=4  # Unit: GB
# VM image file name
IMAGE_FILE=/var/lib/libvirt/images/${VMNAME}.qcow2
CIDATA_FILE=$PWD/cidata-${VMNAME}.iso

if [ ! -r $CIDATA_FILE ]; then
    echo "error: $CIDATA_FILE not found"
    exit 1
fi
if [ ! -r $IMAGE_FILE ]; then
    echo "error: $IMAGE_FILE not found"
    exit 2
fi
sudo virt-install \
    --name $VMNAME \
    --ram $(($RAMSIZE * 1024)) \
    --vcpus $VCPUS \
    --arch x86_64 \
    --os-type linux \
    --os-variant ubuntu22.04 \
    --virt-type qemu\
    --file $IMAGE_FILE \
    --cdrom $CIDATA_FILE \
    --boot hd \
    --network network:default \
    --graphics none \
    --serial pty \
    --console pty \
    --autostart --noreboot
EOF

vCPUとメモリの設定は必要に応じて変える。

libvirt-qemuユーザーが/home/ubuntuディレクトリにアクセスできるようにするためには、以下のコマンドを実行する。

$ sudo setfacl -m u:libvirt-qemu:x /home/ubuntu

次に、シェルスクリプトの実行する。このシェルスクリプトではvirt-installコマンドを使用しているのでそれをインストールしてから、シェルスクリプトを実行する。

#ライブラリをインストール
$ sudo apt install -y virt-manager

#シェルスクリプト実行
$ bash ./create-ubuntu22-vm1.sh

(数十分後)
ubuntu22-vm1 login: ubuntu ←作成したIDを入力
Password: ←user-dataで指定したpasswordを入力

ubuntu@ubuntu22-vm1:~$ ←WSL2上の仮想環境にログインできた。

念のために、WSL2上から仮想環境を確認する。

$ virsh list
 Id   Name           State
------------------------------
 6    ubuntu22-vm1   running

無事に動作していそうである。

参考

hiro20180901.hatenablog.com

トラブルシューティングメモ

#シェルスクリプト実行
$ bash ./create-ubuntu22-vm1.sh

WARNING  --os-type is deprecated and does nothing. Please stop using it.
ERROR    Host does not support domain type kvm for virtualization type 'hvm' with architecture 'x86_64'

シェルスクリプト時、上記のエラーを確認した。 hiro20180901.hatenablog.com

上記 を参考に、WSL2 で Nested VM が有効かどうか確認する。

$ ls -l /dev/kvm*
crw-rw-r-- 1 root kvm 10, 232 Feb 26 07:33 /dev/kvm
$ egrep -c '(vmx|svm)' /proc/cpuinfo
0
$ kvm-ok
INFO: Your CPU does not support KVM extensions
INFO: For more detailed results, you should run this as root
HINT:   sudo /usr/sbin/kvm-ok

CPUがKVMをサポートしていないようだ。

現在のPCで使用しているCPUが 11th Gen Intel(R) Core(TM) i5-1145G7 @ 2.60GHz 2.61 GHz である。Intel CPUの場合、Intel® Virtualization Technology (VT-x)の機能があると、そのCPUが仮想化技術をサポートしているようである。

https://www.intel.co.jp/content/www/jp/ja/support/articles/000005486/processors.html を参考に、自分のCPUにIntel® Virtualization Technology (VT-x)があるかどうかをhttps://ark.intel.com/content/www/jp/ja/ark/products/208081/intel-core-i5-1145g7e-processor-8m-cache-up-to-4-10-ghz.html から確認したがサポートしているようだ。 そのことから、WSL2上ではkvm-okコマンドが正常に動作していないようである。

参考

hiro20180901.hatenablog.com