下記の記事で cloud-init を使って KVM のゲストの IP アドレスとホスト名を自動設定しましたが、
そもそもこれ、ベースとなるイメージからゲストをダバーっと作りたかっただけです。
libguestfs
に含まれる virt-customize
を使えばゲストのイメージの中を簡単にいじれるようなので試してみました。
ホストに libguestfs をインストール
ホストに libguestfs
をインストールします。
yum -y install libguestfs libguestfs-tools libguestfs-tools-c
ベースイメージを作成
libguestfs-tools-c
付属する virt-builder
を使ってベースイメージのゲストを作成します。
イメージのボリュームを作成します。なおこの例では LVM を使っていますが、raw ファイルや qcow2 でもできます。
lvcreate vg1 -n base -L 6G
イメージを作成します。
virt-builder centos-7.2 \
-o /dev/vg1/base \
--arch x86_64 \
--root-password password:password \
--timezone Asia/Tokyo \
--run-command '
set -eux
mkdir -p /root/.ssh/pub
chmod 700 /root/.ssh
curl -fsSL https://github.com/ngyuki.keys > /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys
' \
--firstboot-command '
restorecon -RFv /root/.ssh/
'
--run-command
で指定したコマンドはイメージの作成時に chroot して実行されます(--run
でファイルも指定できる)。
--firstboot-command
で指定したコマンドはゲストの初回起動時にだけ実行されます(--firstboot
でファイルも指定できる)。
その他いろいろオプションはあります。詳しくは man virt-builder
。
イメージができたら virt-install
でインポートします。
virt-install \
--name base \
--disk path=/dev/vg1/base \
--network network=default \
--hvm --virt-type kvm \
--vcpus 1 --ram 1024 --arch x86_64 \
--os-type linux --os-variant rhel7 \
--boot hd --graphics none --serial pty --console pty \
--import --noreboot
起動してコンソールに接続します。
virsh start base
virsh console base
必要に応じてゲストの中身を修正し、終わったらシャットダウンします(--run-command
だけで完結するなら作業は不要)。
virsh shutdown base
virt-sysprep
でゲストのイメージから余計なものをいろいろ削除します(ログとか SSH ホスト鍵とか)。
virt-sysprep -d base --operations defaults,-ssh-userdir
実際にどんなことが行われるかは virt-sysprep --list-operations
でそれとなく察せられると思います。
この例では /root/.ssh
の削除だけ除外しています(デフォだと /root/.ssh
が削除されてしまうのでせっかく配置した SSH 公開鍵も消えてしまう)。
ゲストを作成
新しく作成するゲストのためのボリュームを作成します。
lvcreate vg1 -n sv01 -L 8G
ベースイメージは 6G でしたが、これから作成するゲストのイメージは 8G にしてパーティションの拡張を行います。それには virt-resize
を使えばできるのですが、拡張するパーティションの詳細を見るために virt-filesystems
でベースイメージのパーティションを調べます。
virt-filesystems -a /dev/vg1/base -hl
# Name Type VFS Label Size Parent
# /dev/sda1 filesystem ext4 - 512M -
# /dev/sda3 filesystem ext4 - 4.5G -
拡張するのは /dev/sda3
なので、下記のように virt-resize
で拡張しつつコピーします。
virt-resize --expand /dev/sda3 /dev/vg1/base /dev/vg1/sv01
出来上がった新しいイメージのパーティションを見てみます。
virt-filesystems -a /dev/vg1/sv01 -hl
# Name Type VFS Label Size Parent
# /dev/sda1 filesystem ext4 - 512M -
# /dev/sda3 filesystem ext4 - 6.5G -
ゲストをインポートします。
virt-install \
--name sv01 \
--disk path=/dev/vg1/sv01 \
--network network=default \
--hvm --virt-type kvm \
--vcpus 1 --ram 1024 --arch x86_64 \
--os-type linux --os-variant rhel7 \
--boot hd --graphics none --serial pty --console pty \
--import --noreboot
ゲストのホスト名を変更し、さらに初回起動時に IP アドレスが設定されるようにします。
virt-customize -d sv01 --hostname sv01 --firstboot-command '
nmcli con modify eth0 \
connection.autoconnect yes \
ipv4.method manual \
ipv4.addresses 192.168.33.21/24 \
ipv4.gateway 192.168.33.1 \
ipv4.dns 192.168.33.1
nmcli con up eth0
'
ゲストを開始します。
virsh start sv01
IP アドレスやホスト名がそれっぽく設定されていることを確認します。
ssh 192.168.33.21 uname -n