homelabでKVMとCockpitを利用するケースを見かけるようになったため、ESXi上にNestedでKVMを構築し、Cockpitで仮想マシンの構築ができるか試してみました。
構成
KVMとは
KVM (Kernel-based Virtual Machine) は、Linuxカーネルに組み込まれた仮想化技術です。KVM を使用すると、Linux をハイパーバイザーとして機能させることができます。
Cockpitとは
Cockpitは、Webベースのサーバー管理インターフェイスで、コマンドラインを使わなくてもサーバーの状態を確認したり、設定変更を行うことができます。また、KVMの仮想マシンも管理することができます。
Nested KVMのセットアップ
Nested KVMを用意するために、Ubuntuをインストールした仮想マシンを用意します。
KVM用のUbuntu VMの仮想マシンの設定の編集を開き、CPUのハードウェア仮想化にチェックを入れておきます。
ネットワークはまずはVLANを指定したポートグループを接続しておきます。
インストール
以下で必要なパッケージをインストールしておきます。
$ sudo apt install -y qemu-kvm virt-manager libvirt-daemon-system \ virtinst libvirt-clients bridge-utils
libvirtdのサービスを有効化しておきます。
$ sudo systemctl enable --now libvirtd $ sudo systemctl start libvirtd $ sudo systemctl status libvirtd
kvmグループにユーザを追加します。
$ sudo usermod -aG kvm $USER $ sudo usermod -aG libvirt $USER
Cockpitをインストールします。
$ sudo apt install cockpit $ sudo systemctl start cockpit $ sudo systemctl status cockpit
http://<IPアドレス>:9090
でCockpitのWeb UIにアクセスできることを確認します。
Cockpitはネットワーク管理にNetworkManagerを使っており、Cockpit上でネットワーク設定をするために、ネットワーク管理をNetworkManagerに変更します。
$ sudo vi /etc/netplan/01-custom-config.yaml network: renderer: NetworkManager version: 2 $ sudo netplan apply
systemd-networkd-wait-onlineのサービスがfailedになるため、サービスを停止させておきます。
$ systemctl status systemd-networkd-wait-online × systemd-networkd-wait-online.service - Wait for Network to be Configured Loaded: loaded (/lib/systemd/system/systemd-networkd-wait-online.service; enabled; vendor preset: disabled) Active: failed (Result: exit-code) Docs: man:systemd-networkd-wait-online.service(8) Process: 885 ExecStart=/lib/systemd/systemd-networkd-wait-online (code=exited, status=1/FAILURE) Main PID: 885 (code=exited, status=1/FAILURE) CPU: 6ms $ sudo systemctl stop systemd-networkd-wait-online.service $ sudo systemctl disable systemd-networkd-wait-online.service $ sudo systemctl mask systemd-networkd-wait-online.service
こちらの状態で、ログインし、ネットワークはこのように表示されます。
初期状態では、 virbr0
というブリッジが作成されており、libvirt が自動的に仮想ネットワークを用意してくれています。
$ brctl show bridge name bridge id STP enabled interfaces virbr0 8000.5254001f7a81 yes
$ nmcli device show virbr0 GENERAL.DEVICE: virbr0 GENERAL.TYPE: bridge GENERAL.HWADDR: 52:54:00:1F:7A:81 GENERAL.MTU: 1500 GENERAL.STATE: 100 (connected (externally)) GENERAL.CONNECTION: virbr0 GENERAL.CON-PATH: /org/freedesktop/NetworkManager/ActiveConnection/1 IP4.ADDRESS[1]: 192.168.122.1/24 IP4.GATEWAY: -- IP4.ROUTE[1]: dst = 192.168.122.0/24, nh = 0.0.0.0, mt = 0 IP6.GATEWAY: --
外部ネットワークへの通信は iptables によってNAT、DHCPはdnsmasqが行ってそうです。
$ sudo iptables -t nat -nvL Chain LIBVIRT_PRT (1 references) pkts bytes target prot opt in out source destination 1 40 RETURN all -- * * 192.168.122.0/24 224.0.0.0/24 0 0 RETURN all -- * * 192.168.122.0/24 255.255.255.255 0 0 MASQUERADE tcp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535 0 0 MASQUERADE udp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535 0 0 MASQUERADE all -- * * 192.168.122.0/24 !192.168.122.0/24
$ ps aux | grep dnsmasq libvirt+ 107607 0.0 0.0 10084 388 ? S 21:11 0:00 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/lib/libvirt/libvirt_leaseshelper
仮想マシンを管理するために、以下のインストールを行います。
$ sudo apt install cockpit-machines
こちらの状態で、仮想マシンを作成してみます。
デフォルトで、ネットワークはdefaultのvirbr0に接続するような設定になっています。
ネットワークの構成を図にすると以下のようになります。
┌─────────────────────┌──────────────┐───────────────────────┐ │ KVM Host │ ens192 │ │ │ └───────┬──────┘ │ │ │ NAT(iptables) │ │ ┌───────┴──────┐ │ │ │ virbr0 │ 192.168.122.1/24 │ │ └───────┬──────┘ │ │ │ interface member │ │ ┌───────┴──────┐ │ │ │ vnet0 │ 192.168.122.2/24 │ │ └───────┬──────┘ │ │ ┌───────┴──────┐ │ │ │ VM │ │ │ └──────────────┘ │ └────────────────────────────────────────────────────────────┘
VLANトランクへの変更
外部からのアクセスや、ネットワークをNested ESXiライクに変更するために、Nested KVMのポートグループをVLANトランクに変更します。
Cockpitのネットワークの設定で、bridge50
という名前でブリッジを追加します。
VLANの追加で、親に bridge50
を指定し、VLAN IDに50、名前を vlan.50
を入れ追加します。
仮想マシンのネットワークの設定を、インターフェイス形式を Bridge to LAN
、ソースを bridge50
に変更します。
この状態で、同じVLANからsshで接続できることを確認します。
ネットワークの構成を図にすると以下のようになります。
┌──────────────┐ │ Trunk VLAN │ └───────┬──────┘ ┌─────────────────────┌───────┴──────┐───────────────────────┐ │ KVM Host │ ens192 │ │ │ └───────┬──────┘ │ │ │ │ │ ┌───────┴──────┐ │ │ │ vlan.50 │ VLANID 50 │ │ └───────┬──────┘ │ │ │ interface member │ │ ┌───────┴──────┐ │ │ │ brige50 │ │ │ └───────┬──────┘ │ │ │ interface member │ │ ┌───────┴──────┐ │ │ │ vnet0 │ │ │ └───────┬──────┘ │ │ ┌───────┴──────┐ │ │ │ VM │ │ │ └──────────────┘ │ └────────────────────────────────────────────────────────────┘
現在の構成だと、KVMホストごとにネットワークの設定を行っているため、KVMホスト1台や数台に管理にはCockpitが向いていそうに見えます。