hidemium's blog

日々学んだことをアウトプットする。

Nested KVMでCockpitを試してみる

homelabでKVMとCockpitを利用するケースを見かけるようになったため、ESXi上にNestedでKVMを構築し、Cockpitで仮想マシンの構築ができるか試してみました。

構成

  • vCenter 8.0U3
  • ESXi 8.0U3
  • Ubuntu 22.04 (Nested KVM)

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が向いていそうに見えます。

参考

  翻译: