【虚拟化】使用packer手搓安装linux,windows镜像并导入virsh进行管理(含Kickstart安装与linux内核参数配置)
声明:本文所有内容均来自互联网 & AIGC,无加密资料,引用已注明出处(见参考资料),侵删
参考资料A:1, 2,
参考资料B:1, 2, 3
文章目录
- 1、Packer安装与使用
- 2、配置文件并且安装镜像(含内核panic解决)
- 3、将创建出的raw镜像导入virsh进行管理
1、Packer安装与使用
Packer介绍
- Packer 是 hashicorp 公司开源的一个虚拟机镜像构建工具,与它类似的工具还有 OpenStack diskimage-builder、AWS EC2 Image Builder ,但是这两个只支持自家的平台。Packer 能够支持主流的公有云、私有云以及混合云,比它俩高到不知道哪里去了。
- 可以这么来理解:Packer 在 IaaS 虚拟化领域的地位就像 Docker 在 PaaS 容器虚拟中那样重要,一个是虚拟机镜像的构建,另一个容器镜像的构建,有趣的是两者都是在 2013 年成立的项目。
虚拟化工具链介绍:
- KVM:Linux 内核态的虚拟化组件。
- QEMU:Linux 用户态的虚拟化组件。QEMU 跟 KVM 结合提供完整的虚拟化技术支撑,属于架构的最底层。
- Libvirt:介于架构底层和架构上层之间,它将底层的虚拟化特性抽象成统一的 API(应用程序编程接口),从而提供给上层调用。
- Packer 和 Vagrant:虚拟化客户端工具,它们属于架构的最上层,直接跟终端用户交互。同时,在客户端之间也会产生相应联系,我们将 Packer 的输出物作为 Vagrant 的输入源。
本地环境安装packer
- pacer官方下载, 官网
# 进入local目录
cd /usr/local# 以packer_1.8.5_linux_amd64.zip为例。
wget https://releases.hashicorp.com/packer/1.8.5/packer_1.8.5_linux_amd64.zip# 运行以下命令,解压Packer安装包。
unzip packer_1.8.5_linux_amd64.zip# 如果返回Packer版本号,表示您已正确安装Packer。
packer -v# 路径不对与配置环境变量
ls /usr/local/bin/packer #找packer
which packer
sudo mv /some/incorrect/path/packer /some/incorrect/path/packer.old # 移除重命名
nano ~/.bashrc # 或者使用你常用的编辑器,如 vi
export PATH=/usr/local/bin:$PATH # 配置环境变量
source ~/.bashrc # 或者 source ~/.bash_profile, source ~/.zshrc
sudo ln -s /usr/libexec/qemu-kvm /usr/local/bin/qemu-system-x86_64 # 符号链接(找不到qemu)
使用packer构建镜像
# 计算文件md5
md5sum example.txt# 验证配置文件
packer fix packer1_fixed.json
packer validate packer1_fixed.json# 构建镜像:
packer build packer1_fixed.json
PACKER_LOG=1 packer build packer1_fixed.json# 连接镜像
vncviewer localhost:5900
ssh 127.0.0.1 -p 1234
2、配置文件并且安装镜像(含内核panic解决)
vim,可以使用:%d
删除所有行,然后粘贴
Rocky安装配置文件
{"builders": [{"vm_name": "packer-xxx","type": "qemu","accelerator": "kvm","qemu_binary": "/usr/libexec/qemu-kvm","qemuargs": [["-m","4096M"],["-smp","cpus=1,maxcpus=4,cores=4"]],"headless": true,"name": "rocky-kvm","iso_checksum": "md5:xxx","iso_url": "/tmp/xxx.iso","output_directory": "build/images","disk_interface": "virtio","disk_size": "40000M","format": "qcow2","net_device": "virtio-net","shutdown_command": "echo 'root' | sudo -S shutdown -P now","ssh_username": "root","ssh_password": "root","ssh_wait_timeout": "3600s","vnc_bind_address": "0.0.0.0", "display": "vnc=0.0.0.0:123","boot_command": ["<enter><wait>","/vmlinuz<wait>"," initrd=/initrd.img<wait>"," inst.stage2=hd:LABEL=Rocky-9.4-x86_64<wait>"," inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks.cfg<wait>"," modprobe.blacklist=nouveau<wait>"," console=ttyS0<wait>"," loglevel=7<wait>","<enter><wait>"]}],"provisioners": [{"inline": ["sudo yum update -y","sudo yum install -y openssh-server","sudo systemctl enable sshd","sudo systemctl start sshd","sudo systemctl status sshd","sudo ufw allow ssh","sudo ufw enable"],"type": "shell"}]
}
验证镜像没有问题,virt可以成功安装
# kvm拉起
#!/bin/bash
virt-install \
--virt-type=kvm \
--name=rocky_t1 \
--vcpus=2 \
--memory=4096 \
--location=/tmp/xxx.iso \
--disk path=/home/vms/xxx.qcow2,size=40,format=qcow2 \
--network bridge=br0 \
--graphics none \
--extra-args='console=ttyS0' \
--force
boot的过程中出现了Kernel Panic问题
- 安装rocky过程中出现end kernel panic not syncing attemped to kill init , exit code = 0x0007f00,
- Kickstart 文件 (ks.cfg) 是用于自动化安装 Linux 操作系统(例如 RHEL、CentOS、Rocky Linux等)的一种配置文件。这个文件包括了从分区配置到软件包安装在内的所有安装选项和配置。
- 下面是一个基本的 Kickstart 文件示例,可以帮助你更好地理解其结构和用途。
- 编辑你的 Packer 模板文件,添加 HTTP 目录,并在 boot_command 中指定 inst.ks 参数。
- 在 boot_command 参数中,{{ .HTTPIP }} 和 {{ .HTTPPort }} 是 Packer 在构建映像时动态填充的变量。Packer 会在构建过程中自动启动一个 HTTP 服务器,监听这些 IP 和端口, 在你的 Packer 项目目录中创建一个名为 http 的目录,并将 ks.cfg 文件放入该目录。
- 虽然最后没有用上Kickstart文件
- 对于{{ .HTTPIP }} 和 {{ .HTTPPort }}访问不到Kickstart文件的情况,可以
python3 -m http.server 8000
启一个本地服务出来,然后直接访问对应的文件即可。
your-packer-project/
|-- http/
| |-- ks.cfg
|-- your-packer-template.json
# Kickstart file# System language
lang en_US.UTF-8# Keyboard layout
keyboard us# Timezone
timezone America/New_York --utc# Root password (encrypted)
rootpw --iscrypted $6$AhFGgUlibP7$ywUmF4e0Qj5nZjhtH/d1fJQiVe.6MKyXt4KtugZYlH4x1fCm0UF1/nR9XP.VbsZKgffQOpR5EHzAqC8QvOnpR/# Network configurations
network --bootproto=dhcp --device=eth0 --onboot=on
network --hostname=yourhostname# Disk partitioning
bootloader --location=mbr --boot-drive=sda
clearpart --all --initlabel
autopart --type=lvm# Disable firewall and SELinux
firewall --disabled
selinux --disabled# System authorization
authconfig --enableshadow --passalgo=sha512# Reboot after installation
reboot# Package installation information
%packages
@core
wget
curl
vim
%end# Post-installation script
%post
# Any required post-installation scripts can be added here
echo "Post-installation script execution" > /root/ks-post.log
%end
换镜像尝试
- 阿里云centos6.9
- 亲测可以拉起来的Kickstart配置文件,for centos6.9, 1
- 手动在配置里补充分配了磁盘
# centos 6.8 # Disk partitioning
part /boot --fstype="ext4" --size=1024
part pv.01 --grow --size=1
volgroup vg0 pv.01
logvol / --vgname=vg0 --size=10240 --name=root --fstype=ext4
logvol swap --vgname=vg0 --size=2048 --name=swapinstall
cdrom
lang en_US.UTF-8
keyboard us
network --bootproto=dhcp
rootpw vagrant
firewall --disabled
selinux --permissive
timezone UTC
unsupported_hardware
bootloader --location=mbr
text
skipx
zerombr
clearpart --all --initlabel
autopart
auth --enableshadow --passalgo=sha512 --kickstart
firstboot --disabled
reboot
user --name=vagrant --plaintext --password vagrant
key --skip%packages --nobase --ignoremissing --excludedocs
# vagrant needs this to copy initial files via scp
openssh-clients
sudo
kernel-headers
kernel-devel
gcc
make
perl
wget
nfs-utils
-fprintd-pam
-intltool# unnecessary firmware
-aic94xx-firmware
-atmel-firmware
-b43-openfwwf
-bfa-firmware
-ipw2100-firmware
-ipw2200-firmware
-ivtv-firmware
-iwl100-firmware
-iwl1000-firmware
-iwl3945-firmware
-iwl4965-firmware
-iwl5000-firmware
-iwl5150-firmware
-iwl6000-firmware
-iwl6000g2a-firmware
-iwl6050-firmware
-libertas-usb8388-firmware
-ql2100-firmware
-ql2200-firmware
-ql23xx-firmware
-ql2400-firmware
-ql2500-firmware
-rt61pci-firmware
-rt73usb-firmware
-xorg-x11-drv-ati-firmware
-zd1211-firmware%post
# Force to set SELinux to a permissive mode
sed -i -e 's/\(^SELINUX=\).*$/\1permissive/' /etc/selinux/config
# sudo
echo "%vagrant ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/vagrant
解决问题,改虚拟机内核参数
- linux内核参数,是用于引导Linux内核时传递给内核的选项,这些选项可以控制内核的行为。内核参数可以通过在启动引导程序(如GRUB)上进行配置来设置。
- 增加 console=ttyS0 selinux=0,去掉 rhgb quiet
- console=ttyS0, 这个参数用于指定系统输出的控制台设备。特别是在虚拟机环境下或没有物理显示器的远程服务器上,这个参数会非常有用,将系统启动信息和登录提示输出到串行端口 ttyS0。
- selinux=0: 禁用 SELinux(Security-Enhanced Linux),它是一种强制访问控制安全模块,在系统引导时禁用 SELinux。
- rhgb :用于在启动过程中显示图形引导界面的选项。可以去掉
- quiet:抑制启动时的大部分内核消息,只在有错误或非常重要的信息时才会显示。
- 要调整这些内核参数,可以编辑 /etc/default/grub 文件。修改后需要更新 GRUB 配置文件。
GRUB_CMDLINE_LINUX="console=ttyS0 selinux=0"
,sudo grub2-mkconfig -o /boot/grub2/grub.cfg
- 如果使用 UEFI 引导,则命令可能是:
sudo grub2-mkconfig -o /boot/efi/EFI/<distribution>/grub.cfg
"provisioners": [{"type": "shell","inline": ["sudo sed -i 's/^GRUB_CMDLINE_LINUX=\"\\(.*\\)\"/GRUB_CMDLINE_LINUX=\"console=ttyS0 selinux=0 \\1\"/' /etc/default/grub","sudo sed -i 's/rhgb quiet//' /etc/default/grub","sudo grub2-mkconfig -o /boot/grub2/grub.cfg"]}]
关于多个iso镜像安装时的难点补充
- 额外多一个驱动的挂载,相当于需要挂载2个iso镜像,并且需要指定启动顺序(不然会找不到启动盘)
qemuargs = [["-serial", "file:serial.out"],["-drive", "file=packer.raw,media=disk,if=virtio"],["-drive", "file=win_dvd.iso,media=cdrom,index=2"],["-drive", "file=driver.iso,media=cdrom,index=3"],["-boot", "order=d"] # 会按照index来
]
3、将创建出的raw镜像导入virsh进行管理
关于packer的配置信息(CPU、内存等)
- 在使用 Packer 创建镜像时,packer.json 文件 通常定义了如何构建镜像的过程,包括使用的构建器(如 Amazon AMI、Azure Image、Docker、QEMU、VirtualBox 等)、构建中要执行的步骤(诸如 Shell 脚本、Ansible、Chef 等)以及包含在镜像中的软件和配置。
- packer.json 文件中确实包含了一些硬件配置参数,但这些参数通常用于构建镜像时的临时虚拟机配置,而不是最终镜像本身的硬件配置。这些配置仅在构建镜像时的虚拟机中有效。
- 构建完成的镜像(如 AWS AMI、Azure Image 或 VMware 磁盘文件等)只是操作系统和软件的快照,并不包含固定的硬件配置。 最终使用这些镜像时,虚拟机的硬件配置(如 CPU、内存)是由使用这些镜像时所处的虚拟化平台决定的。
关于virsh的配置信息
- 在使用 Packer 创建虚拟机镜像时,通过 packer.json 文件定义了一些参数,比如 CPU、内存以及磁盘等。实际上,当使用 virsh 或 virt-install 导入 Packer 创建的镜像时,重新指定这些参数需要保持与虚拟机环境与镜像预期配置相一致,避免出现带不动或者资源浪费的情况 (这里后面可以考虑用脚本实现)。
- RAW 快照是一种不包含文件系统信息的磁盘映像,通常用于捕获磁盘的字节级副本。这些快照可以包含整个磁盘的内容,从操作系统的文件到任何存储在磁盘上的数据。
sudo virt-install \--name packer-rocky \--ram 4096 \--vcpus 2 \--os-type linux \--disk path=packer-rocky.raw,format=raw \--import \--network network=default \--noautoconsole
如果virsh管理的虚拟机是vnc连接的,该如何获得他的端口
- 启动后没有反应
- 获取虚拟机的 VNC 连接信息,包括端口号。
sudo virsh domdisplay packer-centos
- 检查配置文件:
sudo virsh edit packer-centos | grep "<graphics>"
- 检查配置文件:
sudo virsh dumpxml packer-centos | grep "<graphics>"
- 通过 netstat 或 ss 等工具查看开放端口:
sudo netstat -tlnp | grep qemu
在输出中查找类似 :59XX 的端口,XX 即为 VNC 显示器编号. - 可以edit在device元素里添加
<graphics type='vnc' port='-1' listen='0.0.0.0'/>
,然后shutdown和start一下 - 如果virsh shutdown 关机关不掉,可以sudo virsh destroy强制重启,此时配置文件生效
- 原先是domdisplay出来的是127.xxx,现在是localhost xxx,这个时候vnc就可以连接上了!
补充一个关于镜像、虚拟机磁盘的概念
- 在虚拟化环境中,术语“镜像”(image)和“虚拟机磁盘”(virtual disk)有时可以互换使用,但它们具体含义和使用场景可能存在细微的差异。
- 虚拟机磁盘:用于运行中的虚拟机作为主要存储介质。动态变化,包含实际运行数据。
- 镜像:用于创建虚拟机实例的模板或基础。静态,通常不在运行中修改。
- 虚拟机磁盘文件(如 VMDK、VHD、QCOW2)是虚拟机的主要存储设备,包含虚拟机操作系统和所有数据。镜像常用于创建新的虚拟机实例,类似于从预制的模板生成新的虚拟机。
- 镜像文件可以理解为虚拟机磁盘的一种具体实例或模板,有时还包含配置元数据等其他信息。
支持HCL构建镜像,更加直观
- windows
- aliyun, bytedance
- packer 支持HCL、JSON两种格式文件作为模板,建议您使用HCL格式文件。引用
packer {required_plugins {qemu = {source = "github.com/hashicorp/qemu"version = ">= 1.0.10"}}
}variable "checksum" {type = stringdefault = "xxxxxxx"
}variable "ssh_password" {type = stringdefault = "xxxxx"
}source "qemu" "autogenerated_1" {accelerator = "kvm"boot_command = ["<tab> inst.text ", "console=ttyS0,115200n8 ", "inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks/rocky9.ks ", "nameserver=1.1.1.1 ", "<enter><wait> "]boot_wait = "0s"communicator = "ssh"format = "qcow2"headless = trueiso_checksum = "sha256:${var.checksum}"iso_url = "../../../Rocky-9.2-x86_64-minimal.iso"qemu_binary = "/usr/libexec/qemu-kvm"qemuargs = [["-m", "4096"], ["-smp", "2,sockets=2,cores=1,threads=1"], ["-cpu", "host"], ["-serial", "file:serial.out"]]shutdown_command = "/sbin/halt -h -p"shutdown_timeout = "120m"ssh_password = "${var.ssh_password}"ssh_timeout = "1500s"ssh_username = "root"http_content = {"/ks/rocky9.ks" = file("../../kickstart/rocky9.ks")}
}build {description = "\tMinimal Rockylinux 9 Qemu Imageni\n__________________________________________"sources = ["source.qemu.autogenerated_1"]provisioner "shell" {script = "./provisioner.sh"}# provisioner "file" { // 拷贝配置文件
# destination = "/etc/cloud/cloud.cfg"
# source = "../../resource/cloud.cfg"
# }}
无人值守ks
- 通常,我们在安装操作系统的过程中,需要大量的和服务器交互操作,为了减少这个交互过程,kickstart就诞生了。使用这种kickstart,只需事先定义好一个Kickstart自动应答配置文件ks.cfg(通常存放在安装服务器上),并让安装程序知道该配置文件的位置,在安装过程中安装程序就可以自己从该文件中读取安装配置,这样就避免了在安装过程中多次的人机交互,从而实现无人值守的自动化安装。
- 生成kickstart配置文件的三种方法:
- 方法1、每安装好一台Centos机器,Centos安装程序都会创建一个kickstart配置文件,记录你的真实安装配置。如果你希望实现和某系统类似的安装,可以基于该系统的kickstart配置文件来生成你自己的kickstart配置文件。(生成的文件名字叫anaconda-ks.cfg位于/root/anaconda-ks.cfg)
- 方法2、Centos提供了一个图形化的kickstart配置工具。在任何一个安装好的Linux系统上运行该工具,就可以很容易地创建你自己的kickstart配置文件。
kickstart配置工具命令为redhat-config-kickstart(RHEL3)或system-config-kickstart(RHEL4,RHEL5).网上有很多用CentOS桌面版生成ks文件的文章,如果有现成的系统就没什么可说。但没有现成的,也没有必要去用桌面版,命令行也很简单。 - 方法3、阅读kickstart配置文件的手册。用任何一个文本编辑器都可以创建你自己的kickstart配置文件。
- 无人值守ks,