virt-install で KVM に CentOS8 を無人インストール

virt-install を使って CentOS8 の VMを作る時のメモです。

# CentOS8 のISOをダウンロードする

どこかから適当にダウンロードしてください。
2019/9 時点では `CentOS-8-x86_64-1905-dvd1.iso`。

# kickstart.cfg を作る 

無人インストールの応答ファイルである `kickstart.cfg` を作ります。
`{{ }}` は適宜置き換えてください。

```
install
cmdline
eula --agreed
reboot

# DVDイメージからインストールする
cdrom

# use AppStream repo
repo --name="AppStream" --baseurl=file:///run/install/repo/AppStream

# テキストモード
text

# skip X configuration
skipx

# Keyboard layouts
# キーボードレイアウトはjp, us
keyboard --vckeymap=jp106 --xlayouts='jp','us'

# System language
lang en_US.UTF-8

# ネットワーク設定
# `net.ifnames=0 biosdevname=0` を指定しているなら、--device=eth0。
# 指定していないなら、--device=ens0。
network  --bootproto=static --ip={{ IP_paddress }} --netmask={{ netmask }} --device=eth0 --noipv6 --activate

# DHCP使う場合
#network  --bootproto=dhcp --device=eth0 --noipv6 --activate



# ホスト名
# e.g.) yourmachine.example.com
network  --hostname={{ hostname }}

# System services
services --disabled="chronyd"

# System timezone
timezone Asia/Tokyo --isUtc --nontp

# use vda only
ignoredisk --only-use=vda

# パーティショニング
# LVM構成のおまかせパーティション。
clearpart --all --initlabel
autopart --type=lvm

# Root password
# `auth` の `--passalgo=` で指定したアルゴリズムで暗号化した文字列を渡す
rootpw --iscrypted "{{ encrypted_password }}"

# 平文で指定するなら以下の文を使う
#rootpw --plaintext "{{ cleartext_password }}"

# System authorization information
auth --enableshadow --passalgo=sha512

# SELinux 無効化
selinux --disabled

# firewalld 無効化
firewall --disabled

# 初回起動後のセットアップを無効化
firstboot --disabled

%packages
@^minimal-environment
kexec-tools

@core
# インストールのときに入れてしまう rpm を指定する
# e.g)
# dnf-utils
# chrony
# wget
%end

%post

# インストール直後から sshの鍵認証でログインできるように
# authorized_key を入れておく。
# 不要ならこのブロック削除。
# <ここから>
mkdir -p /root/.ssh
chmod 700 /root/.ssh
cat <<EOF > /root/.ssh/authorized_keys
{{ authorized_key }}
EOF
chmod 600 /root/.ssh/authorized_keys
# <ここまで>

%end
```

# VMストレージのイメージファイルを作る

`qemu-img` で qcow2 形式のイメージファイルを作ります。

```shell
qemu-img create -f qcow2 vmimage.qcow2 100G
```

100G は最大サイズです。いきなり 100ギガバイトの qcow2 ファイルができるわけではありません。

# インストール

以下の素材がそろったらインストール。
- kickstart.cfg
- qcow2 イメージファイル
- CentOS8 のISOイメージファイル

libvirt-4.5.0 では、まだ centos8.0 が無かったので、`--os-variant centos7.0` にしてます。

```shell
virt-install \
    --name {{ vm_name }} \
    --initrd-inject {{ /path/to/kickstart.cfg }} \
    --hvm \
    --virt-type kvm \
    --ram {{ memory_in_megabytes }} \
    --vcpus {{ number_of_cpus }} \
    --arch x86_64 \
    --cpu kvm64 \
    --os-type linux \
    --os-variant centos7.0 \
    --disk path={{ /path/to/qcow2 }},format=qcow2,bus=virtio,cache=none \
    --location {{ /path/to/CentOS-8-x86_64-1905-dvd1.iso }} \
    --serial pty \
    --network bridge={{ ethernet_device_name_on_kvm_host }} \
    --extra-args "edd=off console=tty0 console=ttyS0,115200 ks=file:/kickstart.cfg" \
    --force
```
イーサネットデバイスを `eth0` にしたいなら、`--extra-args` に `net.ifnames=0 biosdevname=0` をつけてください。
つけない場合、`ens0` です。正確には、predictable network interface name です。
https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/

```shell
virt-install \
    --name {{ vm_name }} \
    --initrd-inject {{ /path/to/kickstart.cfg }} \
    --hvm \
    --virt-type kvm \
    --ram {{ memory_in_megabytes }} \
    --vcpus {{ number_of_cpus }} \
    --arch x86_64 \
    --cpu kvm64 \
    --os-type linux \
    --os-variant centos7.0 \
    --disk path={{ /path/to/qcow2 }},format=qcow2,bus=virtio,cache=none \
    --location {{ /path/to/CentOS-8-x86_64-1905-dvd1.iso }} \
    --serial pty \
    --network bridge={{ ethernet_device_name_on_kvm_host }} \
    --extra-args "edd=off net.ifnames=0 biosdevname=0 console=tty0 console=ttyS0,115200 ks=file:/kickstart.cfg" \
    --force
```

インストールが終わったら、VMが再起動されて、`virt-install` が終了し、コマンドプロンプトが戻ってきます。
KVMホストの性能にも依存しますが、20秒程度でVMが起動してsshログインできるようになります。

# トラブルシュート

`virt-install`したのとは別のターミナルで、VMにコンソール接続するとインストールの進捗状況を見ることができます。

```
virsh console {{ vm_name }}
```

10分たってもインストールが終わらなかったら、無人インストールがとまっていないかコンソールで見てみて、kickstart.cfg を修正してください。