とある事情で Ubuntu 18.04 のクリーンで直ぐにぶち壊せる環境が欲しかったので virt-builder
で入れようとしたらすごくハマった件。
virt-builder でゲストを作って virt-resize でリサイズして virt-customize でカスタマイズ - Qiita でやってたのをもっと簡素化して Ubuntu 18.04 でやりました。CentOS 7 とか 8 なら同じ手順でサクッと出来たんですけど・・
環境
- ホスト CentOS 8.2.2004
- ゲスト Ubuntu 18.04
- qemu-kvm 2.12.0
- libvirt 4.5.0
- libguestfs-tools 1.38.4
コンソールに何も表示されない
virt-builder
でイメージを作ってから virt-install
でインポートします。
virt-builder ubuntu-18.04 \ --output /var/lib/libvirt/images/ubuntu-18.04.img \ --arch x86_64 \ --hostname ubuntu-18.04 \ --root-password password:password \ --timezone Asia/Tokyo virt-install \ --name ubuntu-18.04 \ --hvm \ --virt-type kvm \ --ram 4096 \ --vcpus 4 \ --arch x86_64 \ --os-type linux \ --os-variant ubuntu18.04 \ --boot hd \ --disk path=/var/lib/libvirt/images/ubuntu-18.04.img \ --network network=default \ --graphics none \ --serial pty \ --console pty \ --import
がしかし virt-install
の後のコンソールになにも表示されず、うんともすんとも言わなくなりました。
シリアルコンソールが有効になっていないだけ? と思いつつ --graphics vnc,port=5901,listen=127.0.0.1
にして VNC で繋いでみたところ、普通にログインプロンプトが表示されていました。
ログインして cat /proc/cmdline
してみたところ次のとおりです。console=ttyS0
がなくシリアルコンソールが利用可能になっていません。
BOOT_IMAGE=/boot/vmlinuz-4.15.0-20-generic root=UUID=8a5c65a8-9852-4c2a-9789-627cb736abe5 ro quiet splash vt.handoff=1
/etc/default/grub
に GRUB_CMDLINE_LINUX=console=ttyS0,115200
を追記して update-grub
してからリブートすれば virsh console
が利用可能になったので、これを virt-builder
に仕込みます。
IPアドレスが付与されない
virt-builder ubuntu-18.04 \ --output /var/lib/libvirt/images/ubuntu-18.04.img \ --arch x86_64 \ --hostname ubuntu-18.04 \ --root-password password:password \ --timezone Asia/Tokyo \ --append-line '/etc/default/grub:GRUB_CMDLINE_LINUX="console=ttyS0,115200"' \ --run-command 'update-grub'
これで virt-install
するとコンソールにもプロンプトが表示されてログインできました。
がしかし ip addr
してみたところIPアドレスが付与されていません。
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: enp1s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 52:54:00:6e:c8:5e brd ff:ff:ff:ff:ff:ff
cat /etc/netplan/01-netcfg.yaml
してみたところ次の通りでした。設定のデバイス名と実際のデバイス名に齟齬があることが原因です。
network: version: 2 renderer: networkd ethernets: ens2: dhcp4: yes
次の Issue も見つかりました。
この Issue にもある通り net.ifnames=0 biosdevname=0
を追加してデバイス名を eth0 に固定してしまえば良いと思うので virt-builder
に仕込みます。
SSHホスト鍵が存在しない
virt-builder ubuntu-18.04 \ --output /var/lib/libvirt/images/ubuntu-18.04.img \ --arch x86_64 \ --hostname ubuntu-18.04 \ --root-password password:password \ --timezone Asia/Tokyo \ --append-line '/etc/default/grub:GRUB_CMDLINE_LINUX="console=ttyS0,115200 net.ifnames=0 biosdevname=0"' \ --run-command 'update-grub' \ --write '/etc/netplan/01-netcfg.yaml: network: version: 2 renderer: networkd ethernets: eth0: dhcp4: yes '
これで virt-install
するとDHCPでIPアドレスが付与されるようになりました。
がしかしSSHでログインしようとすると Connection reset
とか返されて接続出来ません。
コンソールから /var/log/auth.log
を見てみると次の通り。ホスト鍵が生成されていないことが原因でした。
error: Could not load host key: /etc/ssh/ssh_host_rsa_key error: Could not load host key: /etc/ssh/ssh_host_ecdsa_key error: Could not load host key: /etc/ssh/ssh_host_ed25519_key fatal: No supported key exchange algorithms [preauth]
ホスト鍵が無ければ sshd の開始時に自動で作成されるものだと思っていたんですが、ディストリビューションに依るものなのでしょうか。CentOS 8 の場合は sshd.service
に先立って開始する sshd-keygen.target
に含まれる sshd-keygen@rsa.service
sshd-keygen@ecdsa.service
sshd-keygen@ed25519.service
によってホスト鍵がなければ作成されるようになっています。
virt-builder --notes ubuntu-18.04
してみたところ、次のように --firstboot-command
に仕込むように記載がありました。
--firstboot-command "dpkg-reconfigure openssh-server"
これを virt-builder
に仕込みます。
SSHでrootログインが出来ない
virt-builder ubuntu-18.04 \ --output /var/lib/libvirt/images/ubuntu-18.04.img \ --arch x86_64 \ --hostname ubuntu-18.04 \ --root-password password:password \ --timezone Asia/Tokyo \ --append-line '/etc/default/grub:GRUB_CMDLINE_LINUX="console=ttyS0,115200 net.ifnames=0 biosdevname=0"' \ --run-command 'update-grub' \ --firstboot-command 'dpkg-reconfigure openssh-server' \ --write '/etc/netplan/01-netcfg.yaml: network: version: 2 renderer: networkd ethernets: eth0: dhcp4: yes '
これでゲストの初回起動時にSSHのホスト鍵が作成されます。
がしかし SSH でログインしようとしてみたところ、パスワード入力のプロンプトは表示されるものの正しいパスワードを入力しても Permission denied, please try again.
とか返されてログインできません。
sshd がデフォだと root でパスワード認証ではログインできないためでした。ちょっとした確認のために直ぐぶっ壊せる環境をホスト内で閉じたネットワークの中に作りたかっただけなので、root でパスワードログインできるように virt-builder
で /etc/ssh/sshd_config
に追記します。
SSHホスト鍵が存在しない、ふたたび
virt-builder ubuntu-18.04 \ --output /var/lib/libvirt/images/ubuntu-18.04.img \ --arch x86_64 \ --hostname ubuntu-18.04 \ --root-password password:password \ --timezone Asia/Tokyo \ --append-line '/etc/default/grub:GRUB_CMDLINE_LINUX="console=ttyS0,115200 net.ifnames=0 biosdevname=0"' \ --append-line '/etc/ssh/sshd_config:PermitRootLogin yes' \ --run-command 'update-grub' \ --firstboot-command 'dpkg-reconfigure openssh-server' \ --write '/etc/netplan/01-netcfg.yaml: network: version: 2 renderer: networkd ethernets: eth0: dhcp4: yes '
これで PermitRootLogin yes
になるので root でログインできるはずです。
がしかしSSHでログインしようとするとまた Connection reset
とか返されて接続できなくなりました。
どうやら dpkg-reconfigure openssh-server
が何かしらの原因で失敗してホスト鍵が作成されなかったようです。
コンソールからログインして dpkg-reconfigure openssh-server
してみたところ「/etc/ssh/sshd_config
が変更されてるみたいなんやけどどないする?」みたいな TUI のプロンプトが表示されました。たぶんこれが原因でコケたのでしょう。
--frontend noninteractive
を付ければプロンプトは表示されなくなるようなので、これを virt-builder
に仕込みます。
最終形
virt-builder ubuntu-18.04 \ --output /var/lib/libvirt/images/ubuntu-18.04.img \ --arch x86_64 \ --hostname ubuntu-18.04 \ --root-password password:password \ --timezone Asia/Tokyo \ --append-line '/etc/default/grub:GRUB_CMDLINE_LINUX="console=ttyS0,115200 net.ifnames=0 biosdevname=0"' \ --append-line '/etc/ssh/sshd_config:PermitRootLogin yes' \ --run-command 'update-grub' \ --firstboot-command 'dpkg-reconfigure --frontend noninteractive openssh-server' \ --write '/etc/netplan/01-netcfg.yaml: network: version: 2 renderer: networkd ethernets: eth0: dhcp4: yes ' virt-install \ --name ubuntu-18.04 \ --hvm \ --virt-type kvm \ --ram 4096 \ --vcpus 4 \ --arch x86_64 \ --os-type linux \ --os-variant ubuntu18.04 \ --boot hd \ --disk path=/var/lib/libvirt/images/ubuntu-18.04.img \ --network network=default \ --graphics none \ --serial pty \ --console pty \ --import