virt-install本身不解析kickstart,仅将其注入initrd并传递给anaconda;真正执行ks.cfg的是安装程序,秒级生成需预分配磁盘、禁用缓存、正确匹配os-variant、统一网络设备名并确保ks文件路径与内核参数准确对应。

virt-install 本身不执行 Kickstart 解析,它只是把 Kickstart 文件“塞进”安装内核启动流程里——真正起作用的是 CentOS/RHEL 安装程序(Anaconda)在虚拟机启动时读取并执行 ks.cfg。能否秒级生成,取决于你是否绕过了交互等待、网络延迟、磁盘预分配和 ISO 挂载开销。
kickstart 文件必须用 --initrd-inject + file: 方式注入,不能只靠 --location + ks= 参数
virt-install 启动时若用 --location(如 HTTP/NFS/ISO 路径),安装内核会从远程加载,此时 ks= 必须指向一个可被虚拟机直接访问的 URL(如 ks=@#@#@#@#@#@#@#@#@#@0)。但这种方式依赖网络稳定性,且每次启动都要 HTTP GET,无法离线或秒启。
更可靠的做法是:
- 把
ks.cfg和安装 ISO 打包进 initrd(通过--initrd-inject) - 再用
--extra-args="ks=file:/ks.cfg ..."告诉内核去 initrd 里找
这样整个 Kickstart 在内存中加载,无网络 I/O,启动后立刻进入自动化流程。
常见错误现象:
- ks 文件路径写成
ks=/ks.cfg(缺file:前缀)→ Anaconda 不识别,退回交互安装 - 未加
console=ttyS0,115200n8→ 安装过程黑屏,无法 debug -
--initrd-inject指向的文件权限不对(非 root 可读)→ 注入失败,virt-install不报错,但虚拟机卡在 “Loading vmlinuz…”
实操建议:
- 确保
ks.cfg放在宿主机本地,且root用户可读(chmod 600 /root/ks.cfg) - 命令中必须同时出现:
--initrd-inject=/root/ks.cfg和--extra-args="ks=file:/ks.cfg console=ttyS0,115200n8" - 不要混用
--cdrom和--location;批量场景推荐用--location指向本地 ISO 路径(如/var/lib/libvirt/images/CentOS-7-x86_64-Minimal-2009.iso),避免挂载开销
磁盘必须预创建为 qcow2 + preallocation=metadata,否则安装过程卡住
virt-install 的 --disk size=20 是“懒创建”:它只在第一次写入时才实际分配空间。Kickstart 安装过程中大量随机写(如格式化、解压 RPM),如果磁盘没预分配,IO 突增会导致安装卡顿甚至超时。
性能影响明显:
- 未预分配:首台虚拟机安装约 3–5 分钟(多数时间耗在磁盘扩展)
-
qemu-img create -f qcow2 -o preallocation=metadata:安装稳定在 90 秒内,后续克隆也快
实操建议:
- 提前用脚本批量生成磁盘:
qemu-img create -f qcow2 -o preallocation=metadata /var/lib/libvirt/images/vm-001.qcow2 40G - 在
virt-install中显式指定已存在磁盘:--disk path=/var/lib/libvirt/images/vm-001.qcow2,format=qcow2,bus=virtio,cache=none - 禁用缓存(
cache=none)可避免因宿主机 page cache 导致的写入延迟不可控
--os-variant 必须匹配真实系统版本,否则 virtio 驱动可能不生效
CentOS 7 和 CentOS 8 的内核对 virtio-blk、virtio-net 的默认启用逻辑不同。如果 --os-variant 错配(比如用 centos7.0 装 CentOS 8 ISO),Anaconda 可能 fallback 到 IDE/SATA 模式,导致磁盘识别为 sda 而不是 vda —— 这会让 Kickstart 中写的 part / --ondisk=vda 失败,直接中断安装。
验证方式:
- 运行
osinfo-query os | grep -i centos查看支持列表 - CentOS 7.x 对应
centos7.0或rhel7.0 - CentOS 8.x / Stream 8 对应
centos8或rhel8.0 - AlmaLinux/Rocky Linux 8 推荐用
rockylinux8(较新 libosinfo 版本才支持)
容易踩的坑:
- 用旧版 libosinfo(如 RHEL 7 自带的)查不到
centos8,强行指定会 fallback 到 generic linux → 网络/磁盘驱动异常 -
--os-variant错误不会报错,但虚拟机会以兼容模式启动,lspci | grep Virtio仍可见设备,只是驱动没加载
network=static 配置在 ks.cfg 里必须与 --network 参数一致,否则网卡 up 不了
virt-install 的 --network 决定了虚拟网卡的设备名和模型(如 bridge=br0,model=virtio → 设备名为 ens3 或 eth0,取决于内核参数),而 Kickstart 中的 network --device eth0 必须与之对齐。
典型冲突场景:
-
--network network=default(NAT 模式)→ 默认设备名是ens3(systemd 命名规则) - 但
ks.cfg写了network --device eth0→ 安装后找不到接口,IP 配置失败 - 解决办法:加内核参数
net.ifnames=0 biosdevname=0强制传统命名(eth0),并在--extra-args中带上
实操建议:
- 统一用
--extra-args="... net.ifnames=0 biosdevname=0" -
ks.cfg中明确写network --bootproto=static --ip=10.0.91.82 --device=eth0 - 如果用桥接(
bridge=br0),确保宿主机br0已 up 且有 IP,否则 DHCP 获取不到地址
关键点在于:Kickstart 不是独立配置,它和 virt-install 的参数、内核启动参数、宿主机网络状态构成一个强耦合链。少一个环节对不上,就不是“秒级生成”,而是“卡在某个地方等你 Ctrl+C”。











