作者:张华 发表于:2020-07-04
版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明
我们将使用 non-GUI (text or console)的方式尽可能的自动通过KVM安装Ubuntu20.04虚机.
目前,Ubuntu20.04已经默认使用subiquity作为安装工具了 (之前使用debian-installer,使用preseed机制进行自动安装),subiquity使用cloud-init进行自动安装.
wget http://cdimage.ubuntu.com/ubuntu/releases/20.04/release/ubuntu-20.04-live-server-arm64.iso
wget http://cdimage.ubuntu.com/ubuntu-legacy-server/releases/20.04/release/ubuntu-20.04-legacy-server-amd64.iso
注:有个问题, 就是国内的网速太慢了(出口带宽有QoS限制), 采用console方式安装的话基本上就得走网络, 如果再遇到要下载snap就太慢了. 慢得无法忍受, 放弃. 最终采用GUI/vnc模式安装. 不过这种console方式可以方便我们在没有网络问题的国外机器上远程远程安装虚机.
打开硬件虚拟化,及安装KVM相关包.
sudo apt install cpu-checker -y
sudo kvm-ok #remember to enable VT-x and VT-d in BIOS
sudo apt install qemu qemu-kvm libvirt-daemon libvirt-clients bridge-utils virt-manager libosinfo-bin
sudo systemctl status libvirtd
lsmod |grep -i kvm
egrep -c '(vmx|svm)' /proc/cpuinfo
osinfo-query os|grep ubuntu
sudo virt-install --name=demo --ram=8192 --vcpus=2 --hvm --virt-type=kvm \
--connect=qemu:///system --os-variant=ubuntu20.04 --os-type=linux --accelerate \
--disk=/game/demo.qcow2,bus=virtio,format=qcow2,cache=none,sparse=true,size=32 \
--network=bridge=virbr0,model=rtl8139 --nographics -v \
--location 'http://mirrors.cloud.tencent.com/ubuntu/dists/focal/main/installer-amd64/' --extra-args='console=ttyS0,115200n8 serial'
正常情况下,上面使用(–extra-args=‘console=ttyS0,115200n8 serial’)参数应该就能自动通过console连接的(sudo virsh console demo), 但暂不清楚为什么不行 (实际上在后来调试时发现上面命令其实已经将下列内容添加到了虚机内部的/etc/default/grub文件).
GRUB_TERMINAL=serial
GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"
OK, 我们可以继续采用下列两种方法之一在虚机内部enable console, 方法一如下:
$ arp -an |grep $(sudo virsh domiflist demo |awk '/default/ {print $5}')
? (192.168.122.62) at 52:54:00:e8:fb:47 [ether] on virbr0
ssh [email protected]
sudo vim /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash console=ttyS0"
sudo update-grub
init 6
方法二如下:
sudo virsh destroy demo
sudo guestmount -d demo -i /mnt
$ sudo cat /mnt/etc/default/grub |tail -n2
GRUB_TERMINAL=serial
GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"
# but above GRUB_SERIAL_COMMAND doesn't work, so remove them and use the following
sudo vim /mnt/etc/default/grub
#GRUB_CMDLINE_LINUX=""
GRUB_CMDLINE_LINUX="console=tty0 console=ttyS0,19200n8"
sudo vim /mnt/boot/grub/grub.cfg
menuentry 'Ubuntu' --class ubuntu --class gnu-linux --class gnu ...
...
#linux /boot/vmlinuz-5.4.0-40-generic root=UUID=646ea42b-f96e-465a-b20a-546ba34b03d6 ro quiet splash $vt_handoff
linux /boot/vmlinuz-5.4.0-40-generic root=UUID=646ea42b-f96e-465a-b20a-546ba34b03d6 ro console=ttyS0,19200 earlyprint=serial,ttyS0,19200 quiet splash $vt_handoff
sudo guestunmount /mnt
sudo virsh start demo && sudo virsh --connect qemu:///system console demo
# NOTE: we use legacy iso (legacy way uses debian-installer + preseed, new way uses subiquity + init-cloud)
# for new way pls refer - https://ubuntu.com/server/docs/install/autoinstall-quickstart
# wget http://releases.ubuntu.com/20.04/ubuntu-20.04-live-server-amd64.iso
wget http://cdimage.ubuntu.com/ubuntu-legacy-server/releases/20.04/release/ubuntu-20.04-legacy-server-amd64.iso
wget http://mirrors.cloud.tencent.com/ubuntu/dists/focal/main/installer-amd64/current/legacy-images/netboot/ubuntu-installer/amd64/initrd.gz
wget http://mirrors.cloud.tencent.com/ubuntu/dists/focal/main/installer-amd64/current/legacy-images/netboot/ubuntu-installer/amd64/linux
wget https://help.ubuntu.com/lts/installation-guide/example-preseed.txt
sed -e "s/#.*//g" example-preseed.txt |awk '{if (length!=0) print $0}' > preseed.cfg
sed -i "s/archive.ubuntu.com/mirrors.cloud.tencent.com/g" preseed.cfg
sed -i "s/unassigned-hostname/openstack/g" preseed.cfg
sed -i "s/unassigned-domain/lan/g" preseed.cfg
sed -i "s/US\/Eastern/Asia\/Shanghai/g" preseed.cfg
sed -i "s/ubuntu-desktop/standard, ubuntu-server/g" preseed.cfg
sed -i "/ubuntu-server/a\d-i pkgsel\/include string openssh-server" preseed.cfg #append a line after the matched line
sed -i "/openssh-server/a\d-i pkgsel\/upgrade select none" preseed.cfg
sed -i "/confirm_nooverwrite/a\d-i passwd\/user-fullname string demo" preseed.cfg #create a new user demo
sed -i "/demo/a\d-i passwd\/user-password password password" preseed.cfg
sed -i "/user-password/a\d-i passwd\/user-password-again password password" preseed.cfg
sed -i "/user-password-again/a\d-i user-setup\/allow-password-weak boolean true" preseed.cfg
sudo python -m http.server #http://localhost:8000/preseed.cfg
sudo mount -o ro /bak/images/ubuntu-20.04-legacy-server-amd64.iso /mnt/
sudo virt-install --name demo --ram 8192 --vcpus 2 --virt-type kvm \
--connect=qemu:///system --os-variant=ubuntu20.04 --os-type=linux --accelerate \
--disk=/game/demo.qcow2,bus=virtio,format=qcow2,cache=none,sparse=true,size=32 \
--network bridge=virbr0 --graphics none --force --debug \
--cdrom=/bak/images/ubuntu-20.04-legacy-server-amd64.iso \
--boot kernel=./linux,initrd=./initrd.gz,kernel_args="console=ttyS0 url=http://192.168.99.135:8080/preseed.cfg debian-installer/allow_unauthenticated_ssl=true"
NOTE: 实际安装中,报找不着http://192.168.99.135:8080/preseed.cfg以致无法自动安装,奇怪.
参考 - https://ubuntu.com/server/docs/install/autoinstall-quickstart
# The crypted password is just "ubuntu".
cat > user-data << 'EOF'
#cloud-config
autoinstall:
version: 1
identity:
hostname: openstack
password: "$6$exDY1mhS4KUYCE/2$zmn9ToZwTKLhCw.b4/b.ZRTIZM30JZ4QrOQ2aOXJ8yk96xpcCof0kxKwuX1kqLG/ygbJ1f8wxED22bTL4F46P0"
username: ubuntu
EOF
touch meta-data
sudo python -m http.server
# Install ubuntu 20.04 with subiquity/cloud-init
sudo umount /mnt
sudo mount -o ro /bak/images/ubuntu-20.04-live-server-amd64.iso /mnt/ #remember to use live rather than legacy
truncate -s 20G /game/demo.img
sudo qemu-system-x86_64 -cdrom /bak/images/ubuntu-20.04-live-server-amd64.iso -bios /usr/share/qemu/OVMF.fd -nographic -serial mon:stdio -m 8096 -kernel /mnt/casper/vmlinuz -initrd /mnt/casper/initrd -append 'autoinstall ds=nocloud-net;s=http://localhost:8000/ console=ttyS0,115200n8' -hda /game/demo.img
# Boot the installed system
kvm -no-reboot -m 8092 -drive file=/game/demo.img,format=raw,cache=none,if=virtio
see - https://blog.csdn.net/quqi99/article/details/76553404