Webコンソールで操作可能なKVM環境を構築する

こんにちは。
株式会社クラスアクト インフラストラクチャ事業部の大塚です。

今回はubuntu22.04上にKVMを構築していきたいと思います。

# HWスペック
以下の環境で構築しました。ProxmoxVE上に立ち上げます。
Processorsにhostが表示されていることはKVMを立ち上げる際にはマストです。
メモリに関しては画像より高めのほうがいいかもしれません。
![image41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/a558e012-c031-f576-5b9e-454b7e5877bc.png)
KVM上にVMを立ち上げたらとんでもないことになっていました汗
![image42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/cadc1ea7-4e9a-6bee-973d-a3adc8651767.png)

# 用語
## KVM
Kernel-based Virtual Machineを略してKVMと呼びます。
ハードウェア仮想化のハイパーバイザ。
KVMをインストールすることによって、ホストのカーネルがハードウェア仮想化（≒ホストコンピュータの物理ハードウェアとゲスト仮想マシンとの間で仮想化レイヤーを提供し、仮想マシンがハードウェアリソースにアクセスできるようにすること）をサポートし、仮想マシンの実行を可能にします。また、仮想マシンはホストの物理HWに直接アクセスできるようになったり、ホストのリソース管理及びスケジューリングを担当します。
- ※ハイパーバイザ
物理的なハードウェアを複数の仮想マシンに仮想的に分割して、それら仮想マシンが独立して稼働できるようにするためのソフトウェア

## QEMU
Quick EMUlatorを略してQEMUと呼びます。
ホストマシン上で様々なアーキテクチャやプラットフォームの仮想マシンのデバイス（HDDやNIC等）をエミュレートまたはゲストOSの実行するためのツールとして使用されるようです。
- ※エミュレータ
特定のハードウェア、ソフトウェア、または環境を模倣して、別のハードウェアやソフトウェアで同じ動作や機能を再現するもの

# 構築
まずいつも通りapt update,upgradeを行います。
そのあと、egrep -c '(vmx|svm)' /proc/cpuinfoを実行します。この出力結果が0とかになっているとKVM環境を作れないのでVM立ち上げから見直してください。
最後にKVM関連で必要になるものをインストールしていますが、それぞれ以下の役割があります。
- qemu-kvm - ハードウェアエミュレーションを提供するオープンソースのエミュレータ・仮想化パッケージ。
- virt-manager - libvirt デーモンで仮想マシンを管理する Qt ベースのグラフィカルインターフェース。
- libvirt-daemon-system - libvirt デーモンの実行に必要な設定ファイルを提供するパッケージ。
- virtinst - 仮想マシンのプロビジョニングと変更のためのコマンドラインユーティリティ一式。
- libvirt-clients - コマンドラインから仮想マシンとハイパーバイザーを管理・制御するためのクライアントサイドライブラリと API 一式。
- bridge-utils - ブリッジデバイスを作成・管理するためのツールセット。
```
root@kvm01:~# apt update
root@kvm01:~# apt upgrade -y
root@kvm01:~# egrep -c '(vmx|svm)' /proc/cpuinfo
32 ←0以上がマスト
root@kvm01:~# apt install -y cpu-checker
root@kvm01:~# kvm01-ok
INFO: /dev/kvm01 exists
kvm01 acceleration can be used
root@kvm01:~# apt install -y qemu-kvm01 virt-manager libvirt-daemon-system virtinst libvirt-clients bridge-utils
```
libvirtdを起動します。
```
root@kvm01:~# systemctl enable --now libvirtd
root@kvm01:~# systemctl start libvirtd
root@kvm01:~# systemctl status libvirtd
● libvirtd.service - Virtualization daemon
     Loaded: loaded (/lib/systemd/system/libvirtd.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2023-06-28 14:35:06 UTC; 1min 2s ago
TriggeredBy: ● libvirtd-ro.socket
             ● libvirtd-admin.socket
             ● libvirtd.socket
       Docs: man:libvirtd(8)
             https://libvirt.org
   Main PID: 20414 (libvirtd)
      Tasks: 21 (limit: 32768)
     Memory: 10.2M
        CPU: 492ms
     CGroup: /system.slice/libvirtd.service
             tq20414 /usr/sbin/libvirtd
             tq20557 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/lib/libvirt/libvirt_leaseshelper
             mq20558 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/lib/libvirt/libvirt_leaseshelper
Jun 28 14:35:06 kvm systemd[1]: Started Virtualization daemon.
Jun 28 14:35:07 kvm dnsmasq[20557]: started, version 2.86 cachesize 150
Jun 28 14:35:07 kvm dnsmasq[20557]: compile time options: IPv6 GNU-getopt DBus no-UBus i18n IDN2 DHCP DHCPv6 no-Lua TFTP conntrack ipset auth cryptohash DNSSEC loop-detect inotify dump>
Jun 28 14:35:07 kvm dnsmasq-dhcp[20557]: DHCP, IP range 192.168.122.2 -- 192.168.122.254, lease time 1h
Jun 28 14:35:07 kvm dnsmasq-dhcp[20557]: DHCP, sockets bound exclusively to interface virbr0
Jun 28 14:35:07 kvm dnsmasq[20557]: reading /etc/resolv.conf
Jun 28 14:35:07 kvm dnsmasq[20557]: using nameserver 127.0.0.53#53
Jun 28 14:35:07 kvm dnsmasq[20557]: read /etc/hosts - 7 addresses
Jun 28 14:35:07 kvm dnsmasq[20557]: read /var/lib/libvirt/dnsmasq/default.addnhosts - 0 addresses
Jun 28 14:35:07 kvm dnsmasq-dhcp[20557]: read /var/lib/libvirt/dnsmasq/default.hostsfile
root@kvm:~# usermod -aG kvm $USER
root@kvm:~# usermod -aG libvirt $USER
```
/etc/netplan/00-installer-config.yamlを以下のように修正します。
```00-installer-config.yaml
network:
  ethernets:
    ens18:
      dhcp4: false
      dhcp6: false
  # add configuration for bridge interface
  bridges:
    br0:
      interfaces: [ens18] 
      dhcp4: false
      addresses: [192.168.2.100/24] ★VM起動時に割り当たっているIPアドレスを記載します。
      routes:
        - to: default
          via: 192.168.2.254 ★VM起動時に割り当たっているIPアドレスを記載します。
          metric: 100
      nameservers:
        addresses: [8.8.8.8] ★VM起動時に割り当たっているIPアドレスを記載します。
      parameters:
        stp: false
      dhcp6: false
  version: 2
```
参考までに、修正前の00-installer-config.yamlも記載しておきます。
```00-installer-config.yaml
# This is the network config written by 'subiquity'
network:
  ethernets:
    ens18:
      addresses:
      - 192.168.2.100/24
      gateway4: 192.168.2.254
      nameservers:
        addresses:
        - 8.8.8.8
        search: []
  version: 2
```
netplan applyを実行して上記の変更を反映させます。
warning的なのが出力されるかもしれませんが、気にしないで大丈夫です。
```
root@kvm01:/etc/netplan# netplan apply
root@kvm01:/etc/netplan# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP group default qlen 1000
    link/ether a2:46:98:94:ea:d5 brd ff:ff:ff:ff:ff:ff
    altname enp0s18
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 52:54:00:2b:18:60 brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever
4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 26:ee:ab:43:33:bd brd ff:ff:ff:ff:ff:ff
    inet 192.168.2.100/24 brd 192.168.2.255 scope global br0
       valid_lft forever preferred_lft forever
    inet6 fe80::24ee:abff:fe43:33bd/64 scope link
       valid_lft forever preferred_lft forever
```
KVMをWebコンソールで操作するためにcockpitをインストールしていきます。
```
root@kvm01:~# apt install cockpit cockpit-machines -y
root@kvm01:~# systemctl start cockpit
root@kvm01:~# systemctl status cockpit 
● cockpit.service - Cockpit Web Service 
     Loaded: loaded (/lib/systemd/system/cockpit.service; static) 
     Active: active (running) since Thu 2023-06-29 10:27:00 UTC; 21s ago 
TriggeredBy: ● cockpit.socket 
       Docs: man:cockpit-ws(8) 
   Main PID: 6437 (cockpit-tls) 
      Tasks: 1 (limit: 23280) 
     Memory: 1.7M 
        CPU: 386ms 
     CGroup: /system.slice/cockpit.service 
             mq6437 /usr/lib/cockpit/cockpit-tls 
Jun 29 10:27:00 kvm01 systemd[1]: Starting Cockpit Web Service... 
Jun 29 10:27:00 kvm01 cockpit-certificate-ensure[6429]: /usr/lib/cockpit/cockpit-certificate-helper: line 32: sscg: co> 
Jun 29 10:27:00 kvm01 cockpit-certificate-ensure[6430]: .+......+......+.......+...+.........+...+...+........++++++++> 
Jun 29 10:27:00 kvm01 cockpit-certificate-ensure[6430]: ....+....+..............+.+..+...+.......+...+.....+....+..+.+> 
Jun 29 10:27:00 kvm01 cockpit-certificate-ensure[6430]: ----- 
Jun 29 10:27:00 kvm01 systemd[1]: Started Cockpit Web Service.    
```
Webブラウザを立ち上げてhttps://KVMに割り当てているIPアドレス:9090
に接続します。
ここで求められるユーザとパスワードはサーバにsshした際に入力したものと同じです。
![image43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/cfc54a78-0200-f748-6eeb-af3f9c3f0bd2.png)
ログインが成功すると以下のような画面に遷移します。
「管理者アクセスをオンにする」を押下します。
求められるパスワードはログインしたユーザのパスワードでOKです。
![image44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/f6c3e83f-4aa3-d03b-7082-ce0738027dde.png)
![image45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/99fd0d4b-6043-b75e-0e32-0a3317418876.png)
画面右上が管理アクセスとなっていればOKです。
![image46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/183504a1-f1af-2d9d-7db7-642055f297db.png)
rootユーザでcockpitにログインできるようにします。画面左にあるアカウントタブを押下してrootユーザを選択。パスワードの設定を押下します。反映出来たらrootユーザでログインしなおしましょう。
![image47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/2a0d9168-0848-c762-d7dc-b2faefea0593.png)
## KVMにVMを立ち上げてみる
/var/lib/libvirt/images上にubuntuのOSイメージをダウンロードします。
```
root@kvm01:~# cd /var/lib/libvirt/images
root@kvm01:~# wget https://releases.ubuntu.com/22.04.1/ubuntu-22.04.1-live-server-amd64.iso
root@kvm01:/var/lib/libvirt/images# ls -ltr
total 5971380
-rw-r--r-- 1 libvirt-qemu kvm  1474873344 Aug  9  2022 ubuntu-22.04.1-live-server-amd64.iso
```
cockpitの仮想マシンタブを押下すると以下のような画面が表示される。
仮想マシンの作成を押下する。
![image48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/7a00b1e2-ad71-77ea-4057-8cd77e6780b6.png)
以下のような設定を入れて作成。
![image49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/73e31d45-6deb-af18-bf4c-3032769e7902.png)
正常に作成されるとVMの名前が表示されます。またVMの名前を押下するとVNCコンソールでVMを操作することが出来ます。
![image50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/12e19869-773d-d9ea-f7aa-00e72b05d4ff.png)
![image51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/a97216fd-b2fc-bab1-e963-d27016f2470f.png)
初回起動が完了すると、いつも通りssh接続することも可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/e27b3b8e-38ef-9f39-6647-76384a3edae6.png)