超小鸡纯手工dd重装VPS官方系统镜像全过程

Cera香港最近接入CMIN2,趁此机会翻出来一台吃灰的Cera小鸡,属于上古商家CloudIPLC。从我开始抓小鸡起,这家的系统模板就从来没更新过,没有Ubuntu 24,那么只能自己dd。但是又不知道一键脚本里面都有什么秘密,所以还是手工一步一步来,刷官方镜像。

加大难度:VNC也是坏的。感觉老板已经躺平了,或者是心思已经不在VPS业务了

那么计划一下:

  1. 安装一个已经EOL的Debian 11,先进去再说
  2. 手动刷一个Alpine v3.22的救援环境
  3. 从救援环境里刷Ubuntu官方镜像到硬盘

需求:

  • KVM
  • 商家有DHCP服务器(99%都有,oneman都有)
  • 用来存ssh公钥的地方,普通的Github账号就行
  • 5G硬盘
  • 384MB内存

刷Alpine v3.22的救援环境

注意把https://github.com/[用户名].keys替换成实际的公钥地址。

# 下载Alpine v3.22
mkdir -p /boot/alpine
wget --output-document=/boot/alpine/vmlinuz-alp https://dl-cdn.alpinelinux.org/alpine/v3.22/releases/x86_64/netboot/vmlinuz-virt
wget --output-document=/boot/alpine/initramfs-alp https://dl-cdn.alpinelinux.org/alpine/v3.22/releases/x86_64/netboot/initramfs-virt
REL_KERNEL=$(grub-mkrelpath /boot/alpine)

# 创建启动项
cat <> /etc/grub.d/40_custom

menuentry 'Alpine Linux Ramdisk' {
    # Find the partition where we downloaded the files
    search --no-floppy --file --set=root ${REL_KERNEL}/vmlinuz-alp
    
    # Load the kernel
    # ip=dhcp: Auto-configure network
    # modloop: Load kernel modules from the official mirror (keeps RAM usage low)
    # console: Output to both screen and serial port (for VNC/Cloud Consoles)
    # ssh_key: Inject ssh key and start sshd server
    linux ${REL_KERNEL}/vmlinuz-alp ip=dhcp alpine_repo=http://dl-cdn.alpinelinux.org/alpine/v3.22/main modloop=http://dl-cdn.alpinelinux.org/alpine/v3.22/releases/x86_64/netboot/modloop-virt console=tty0 console=ttyS0,115200 ssh_key=https://github.com/[用户名].keys
    
    # Load the RAM disk
    initrd ${REL_KERNEL}/initramfs-alp
}
EOF

# 下次启动到救援环境
update-grub
grub-reboot 'Alpine Linux Ramdisk'
reboot

这里的几步都很直白:从alpine官网下载启动文件,然后添加启动项。

刷Ubuntu官方镜像到硬盘

然后就是等待,DHCP会需要一点时间。服务器公钥会变化,因为救援环境是临时生成的,所以需要删除ssh客户端的known_hosts,或者看客户端自己怎么跳过公钥不匹配错误。载入ssh私钥,登录root。

因为救援环境自带的shell非常基础,粘贴多行代码可能会挂掉,所以先安装bash。

apk add bash
bash

然后就可以粘贴刷机代码了

# 安装刷机工具
setup-apkrepos -c1
apk add qemu-img e2fsprogs parted lsblk

# 检测要刷到哪块硬盘
DISK=$(lsblk -d -n -o NAME,SIZE -b | sort -k2 -n -r | head -n1 | awk '{print "/dev/"$1}')
echo "[-] Target Disk: $DISK"

# 创建一个临时分区用来下载镜像
echo "[-] Creating temporary buffer partition..."
parted -s $DISK mklabel gpt
parted -s $DISK mkpart primary ext4 4GiB 100%
partprobe $DISK
mkfs.ext4 -qF ${DISK}1
mount -t ext4 ${DISK}1 /mnt

# 下载镜像
wget -P /mnt 'https://cloud-images.ubuntu.com/minimal/releases/noble/release/ubuntu-24.04-minimal-cloudimg-amd64.img'

# 刷机
qemu-img convert -p -f qcow2 -O raw /mnt/ubuntu-24.04-minimal-cloudimg-amd64.img $DISK

注意到这里用的是qemu-img,不是dd。官方提供的是压缩后的qcow2镜像,需要解压。所以做了标题党

到这里其实就算完成了,是不是很简单呢?

配置新安装的系统

但是,如果我们现在就重启,我们不知道root密码,也没配置网络,虽然系统会正确加载,但我们登陆不进去,等于刷成了板砖。所以要在重启之前配置好。以下内容,会根据系统本身而有所变化。这里以Ubuntu 24为例。

官方镜像不会占满整块磁盘,以下代码会把根分区扩充到整块磁盘

umount /mnt
partprobe $DISK
echo fix | parted $DISK print ---pretend-input-tty
echo yes | parted --align optimal $DISK resizepart 1 100%  ---pretend-input-tty

然后我们挂载各种虚拟文件系统,准备chroot进去改配置。注意${DISK}1${DISK}16可能根据发行版不同而变化。

mdev -s
mount -t ext4 ${DISK}1 /mnt
mount -t ext4 ${DISK}16 /mnt/boot
mount -t proc proc /mnt/proc
mount -t sysfs sys /mnt/sys
mount -o bind /dev /mnt/dev
mount -t devpts pts /mnt/dev/pts

然后是一些杂七杂八的配置了。对于Ubuntu 24,我会做这些(注意替换新的root公钥)

# 扩充文件分区
chroot /mnt resize2fs ${DISK}1

# 配置root公钥
chroot /mnt install --directory --mode=700 /root/.ssh
echo '[新的root公钥]' | chroot /mnt install --mode=600 /dev/stdin /root/.ssh/authorized_keys

# 生成新的服务器公钥
chroot /mnt ssh-keygen -A

# 配置grub(可选)
chroot /mnt sed -i 's/GRUB_TIMEOUT=0/#GRUB_TIMEOUT=0/' /etc/default/grub.d/50-cloudimg-settings.cfg
chroot /mnt sed -i 's/GRUB_TIMEOUT_STYLE=hidden/GRUB_TIMEOUT_STYLE=menu/' /etc/default/grub 
chroot /mnt sed -i 's/GRUB_TIMEOUT=0/GRUB_TIMEOUT=3/' /etc/default/grub
chroot /mnt update-grub

# 配置网络,直接从DHCP获取
chroot /mnt install --mode=644 /dev/stdin /etc/systemd/network/90-failover.network <<EOF
[Match]
Name=*

[Network]
DHCP=ipv4
EOF

我一般还会加上最后一步:安装qemu-guest-agent。如果商家支持,我一般还是愿意在控制面板上看到VPS的统计数据。对于Ubuntu 24,只要安装上就好了,系统会在检测到支持的时候自动启动agent。

# 配置DNS,这个是Ubuntu 24默认的systemd-resolved的变通方案,其它系统可能不一样
mkdir -p /run/resolvconf/run/systemd/resolve
echo 'nameserver 1.1.1.1' > /run/resolvconf/run/systemd/resolve/stub-resolv.conf
mount --bind /run/resolvconf/run /mnt/run

# 如果存在母鸡接口,就安装agent
if [[ -e /dev/virtio-ports/org.qemu.guest_agent.0 ]]; then
    chroot /mnt apt-get update
    chroot /mnt apt-get install -y qemu-guest-agent
    # Ubuntu 24: will auto start agent with udev rule
fi

然后就可以reboot啦。注意服务器公钥又会变化,所以需要再删除一次ssh客户端的known_hosts

总结

  • 全程只用了ssh,没有用VNC
  • 官方镜像
  • 命令都是手打的,清楚都干了些啥
  • 内存需求远小于netboot.xyz或者其他脚本

开机,就可以看到纯净的系统,而且apt upgrade少于10个。

其它系统的官方镜像

点赞
  1. yumin9822说道:

    感谢分享,技术贴

  2. zwlkangaroo说道:

    厉害了,现在习惯用科技lion的脚本也还行

  3. Zilzyk说道:

    感谢楼主分享,一直以来都是用脚本,有机会了也手动 dd 试试。

发表回复

电子邮件地址不会被公开。必填项已用 * 标注

×
订阅图标按钮