为什么要这样折腾?
众所周知,云服务器可选的发行版是有限的,并且某些发行版因为并不是原版安装的,会有一些问题。而且,云服务器提供的发行版可能会存在一些我们不希望看到的插件,所以便有了更换云服务器操作系统的需求。
准备工作:
需要的东西:服务器(废话),虚拟机(推荐KVM),你希望使用的发行版安装镜像(我这里是AlmaLinux8.10),带live环境的Linux发行版镜像(用于复制和覆盖硬盘数据,我这里用的Manjaro,KDE桌面),filebrowser(用于上传自定义的镜像)。
我这里提供一下快捷下载:
AlmaLinux-8.10-x86_64-boot.iso
filebrowser2.28.0-linux-x64.zip
系统因为大小限制切分压缩分卷了,要全部下载解压:
manjaro-kde-23.1.4-240406-linux66.part1.rar
manjaro-kde-23.1.4-240406-linux66.part2.rar
镜像制作:
虚拟机创建,磁盘分区以及系统安装
创建一个虚拟机,将虚拟机的硬盘设置得尽可能小,刚好把系统装下还剩一点空间能正常启动那是最好,这里我尝试的大小是8G。
然后,按照你所想要的方式把系统安装进硬盘。大部分云服务器都是通过MBR
引导启动的系统,但是以防万一还是搞个双引导的,即MBR
和EFI
,采用GPT
分区,设置biosboot
分区即可。
我这里演示因为AlmaLinux8的安装程序不能调整硬盘分区位置,而为了后续扩容,数据分区需要在最后面(我这里是根分区),就先用live镜像的KDE分区工具
进行预先分区了,如下图所示:
后续即可在安装程序里指定对应的分区:
打包安装好的系统
在配置完成你所希望的功能后,我们需要对系统进行打包。
对于KVM
虚拟机,我们可以使用virtiofs
功能,将宿主机的一个目录映射进虚拟机,方便我们进行打包。
如图所示配置virtiofs
文件系统,设置好名称和映射路径即可
然后,将虚拟机重启进入live镜像环境,创建一个用于挂载的文件夹,挂载virtiofs
文件系统:
su
mkdir /data
mount -t virtiofs data /data
然后,使用dd
目录克隆虚拟机硬盘:
dd if=/dev/vda of=/data/Alma8.img bs=4M status=progress
请注意,if=
后面是要克隆的设备,of=
后面是要输出的文件,设备可能会因环境而已,例如变成/dev/sda
我制作好的镜像
如果你实在不想折腾的话,也可以用我做好的镜像:AlmaLinux8.10-8G.zip
在云服务器上面部署filebrowser上传镜像
利用filebrowser,或者ssh自带的scp等工具,把live环境镜像和需要用于覆盖的预先制作好的镜像传到服务器。
对于scp,先cd到你目录或者直接在文件所在目录打开终端,然后:
scp ./Alma8_8G.img root@172.16.0.11:/root
对应的参数自己进行替换,上面只是个示例。这都不会还不愿意百度就别搞了
如果用fiebrowser,从我的直链下载,解压并且执行就行了:
wget https://fs.duifene.com/res/r2/u6620344/filebrowser2.28.0-linux-x64_e9fc85fa59bcbc39d5c7.zip
unzip ./filebrowser2.28.0-linux-x64_e9fc85fa59bcbc39d5c7.zip
./filebrowser -a 0.0.0.0
如果证书报错,替换为:
wget https://fs.duifene.com/res/r2/u6620344/filebrowser2.28.0-linux-x64_e9fc85fa59bcbc39d5c7.zip --no-check-certificate
什么?wget和uzip没找到命令?装啊!自己去必应搜索!
确认你云服务器防火墙放行了8080
端口,因为默认fiebrowser就是走8080
端口,然后不出意外的话,你访问你服务器的ip加端口8080(例如172.16.0.11:8080
)就可以看到filebrowser的界面了,默认的用户名和密码都是admin
。
登上去,把文件上传了就行,需要一点时间。个人建议是把自定义的系统镜像压缩后上传,因为有大量空的数据,压缩比例还是挺大的,上传完成云服务器解压就行。
配置GRUB从live环境iso启动live系统
以下操作都需要root权限运行!请执行su
获取root权限
打开配置文件
使用文本编辑器编辑配置文件命令行文本编辑器不会用去学完再来
nano /etc/grub.d/40_custom
在文件后面添加如下内容,部分内容根据所选的live发行版的iso文件结构目录和镜像所在位置进行改变:
例如Ubuntu的配置方法:
menuentry "ubuntu-20.04.2.0-desktop-amd64.iso" {
insmod ext2
set isofile="/home/linux-terminal/Downloads/ubuntu-20.04.2.0-desktop-amd64.iso"
loopback loop (hd0,5)$isofile
linux (loop)/casper/vmlinuz boot=casper iso-scan/filename=$isofile quiet noeject noprompt splash
initrd (loop)/casper/initrd
}
具体参数的含义:
menuentry
:此条目将显示在 GRUB2 引导菜单上。您可以将其命名为任何您喜欢的名称。insmod
命令插入一个模块。由于 ISO 文件存储在我的 ext4 主目录下,因此需要 ext2 模块。如果它存储在 NTFS 分区上,则需要insmod ntfs
。请注意,GRUB 可能无法识别 XFS 和 Btrfs 文件系统,因此不建议将 ISO 文件存储在 XFS 或 Btrfs 分区上。set isofile
:指定 ISO 映像文件的路径。这里我使用的是保存在 Downloads 文件夹下的 Ubuntu 20.04 Desktop ISO 文件。环回
:挂载ISO文件。 hd0 表示计算机中的第一个硬盘驱动器,5 表示 ISO 文件存储在第 5 个磁盘分区上。linux
命令从指定路径加载 Linux 内核。 casper/vmlinuz.efi 是 Ubuntu ISO 映像中的 Linux 内核。initrd
命令从指定路径加载初始 ramdisk。它只能在运行linux命令后使用。初始 ramdisk 是安装到 RAM 上的最小根文件系统。casper/initrd.lz
是 Ubuntu ISO 映像中的 initrd 文件。
请注意,GRUB不区分 IDE 和 SCSI。在Linux内核中:
/dev/hda
指第一个 IDE 硬盘,/dev/sda
指第一个 SCSI 或 SATA 硬盘。/dev/nvme0n1
指第一个 NVMe SSD。/dev/nvme1n1
指第二个 NVMe SSD。
但在 GRUB 中,第一个硬盘驱动器始终称为 hd0
,无论接口类型是什么。另请注意,GRUB 中的分区号从 1
开始,而不是从 0
开始。
如果ISO文件存储在MBR
磁盘的扩展分区上,则分区号从5开始,而不是1。例如,扩展分区内的第一个逻辑分区将编号为5;扩展分区内的第二个逻辑分区编号为 6。要检查分区编号,您可以在终端窗口中运行 lsblk
或 sudo parted -l
命令来检查分区编号。
如何查找 Linux 内核和 initrd 文件名:
对于不同的 Linux ISO 映像,Linux 内核和 initrd(初始 ramdisk) 文件可能有所不同。对于 Ubuntu,Linux 内核位于 /casper/vmlinuz,initrd 映像文件位于 /casper/initrd。命名都是比较类似的,照着找就行了。例如AlmaLinux8.10的iso:
具体每个发行版的示例配置:
请不要照抄,要根据需要改动
Debian:
menuentry "debian-live-10.8.0-amd64-lxqt.iso" {
insmod ext2
set isofile="/home/linux-terminal/Downloads/debian-live-10.8.0-amd64-lxqt.iso"
loopback loop (hd0,5)$isofile
linux (loop)/live/vmlinuz-4.19.0-14-amd64 boot=live findiso=$isofile
initrd (loop)/live/initrd.img-4.19.0-14-amd64
}
Arch:
menuentry "archlinux-2021.03.01-x86_64.iso" {
insmod ext2
set isofile="/home/linux-terminal/Downloads/archlinux-2021.03.01-x86_64.iso"
loopback loop (hd0,5)$isofile
linux (loop)/arch/boot/x86_64/vmlinuz-linux archisolabel=ARCH_202103 img_dev=/dev/sda5 img_loop=$isofile earlymodules=loop
initrd (loop)/arch/boot/x86_64/initramfs-linux.img
}
Clonezilla:
menuentry "clonezilla-live-20210127-groovy-amd64.iso" {
insmod ext2
set isofile="/home/linux-terminal/Downloads/clonezilla-live-20210127-groovy-amd64.iso"
loopback loop (hd0,5)$isofile
linux (loop)/live/vmlinuz boot=live findiso=$isofile
initrd (loop)/live/initrd.img
}
RHEL/AlmaLinux/RockyLinux:
menuentry "rhel-8.3-x86_64-boot.iso" {
insmod ext2
set isofile="/home/linux-terminal/Downloads/rhel-8.3-x86_64-boot.iso"
loopback loop (hd0,5)$isofile
linux (loop)/isolinux/vmlinuz noeject inst.stage2=hd:/dev/sda5:$isofile
initrd (loop)/isolinux/initrd.img
}
Fedora:
menuentry "Fedora-Workstation-Live-x86_64-33-1.2.iso" {
insmod ext2
set isofile="/home/linux-terminal/Downloads/Fedora-Workstation-Live-x86_64-33-1.2.iso"
loopback loop (hd0,5)$isofile
linux (loop)/isolinux/vmlinuz root=live:CDLABEL=Fedora-WS-Live-33-1-2 rd.live.image verbose iso-scan/filename=$isofile
initrd (loop)/isolinux/initrd.img
}
OpenSUSE Leap:
menuentry "openSUSE-Leap-15.2-KDE-Live-x86_64-Build31.383-Media.iso" {
insmod ext2
set isofile="/home/linux-terminal/Downloads/openSUSE-Leap-15.2-KDE-Live-x86_64-Build31.383-Media.iso"
loopback loop (hd0,5)$isofile
linux (loop)/boot/x86_64/loader/linux boot=isolinux root=live:CDLABEL=openSUSE_Leap_15.2_KDE_Live rd.live.image verbose iso-scan/filename=$isofile
initrd (loop)/boot/x86_64/loader/initrd
}
Kali Linux:
menuentry "kali-linux-2021.1-live-amd64.iso" {
insmod ext2
set isofile="/home/linux-terminal/Downloads/kali-linux-2021.1-live-amd64.iso"
loopback loop (hd0,5)$isofile
linux (loop)/live/vmlinuz boot=live findiso=$isofile
initrd (loop)/live/initrd.img
}
Linux Mint:
menuentry "linuxmint-20.1-cinnamon-64bit.iso" {
insmod ext2
set isofile="/home/linux-terminal/Downloads/linuxmint-20.1-cinnamon-64bit.iso"
loopback loop (hd0,5)$isofile
linux (loop)/casper/vmlinuz boot=casper iso-scan/filename=$isofile quiet noeject noprompt splash
initrd (loop)/casper/initrd.lz
}
更新GRUB
使用以下命令更新 GRUB 引导菜单:
sudo grub-mkconfig -o /boot/grub/grub.cfg
在 Fedora、CentOS、RHEL、OpenSUSE 上,运行的命令是:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
在 Debian、Ubuntu、Linux Mint 上,您可以使用以下命令更新 GRUB 启动菜单。
sudo update-grub
实操示例:
在manjaro的live镜像找到那两个文件:
根据镜像修改配置文件:
menuentry "manjaro.iso" {
insmod ext2
set isofile="/root/manjaro.iso"
loopback loop (hd0,5)$isofile
linux (loop)/boot/vmlinuz-x86_64 archisolabel=MANJARO img_dev=/dev/vda5 img_loop=$isofile earlymodules=loop
initrd (loop)/boot/initramfs-x86_64.img
}
以下是我实战的终端输出,修改文件附加的就和上面的一样:
[root@NekoWorks ~]# df -hT
Filesystem Type Size Used Avail Use% Mounted on
devtmpfs devtmpfs 1.9G 0 1.9G 0% /dev
tmpfs tmpfs 2.0G 0 2.0G 0% /dev/shm
tmpfs tmpfs 2.0G 8.6M 2.0G 1% /run
tmpfs tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
/dev/vda5 ext4 37G 7.3G 30G 20% /
/dev/vda3 ext4 574M 156M 407M 28% /boot
/dev/vda2 vfat 50M 4.0K 50M 1% /boot/efi
tmpfs tmpfs 393M 0 393M 0% /run/user/0
[root@NekoWorks ~]# nano /etc/grub.d/40_custom
[root@NekoWorks ~]# sudo grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
done
重启之前的准备:
由于dd
是从前往后覆盖,覆盖的范围是目标文件大小,为了防止原文件在dd读取之前被覆盖,建议是原地复制一遍镜像文件,然后指定复制后的文件进行覆盖。注意,这一步需要在原系统完成
切换到云服务器的vnc模式登陆服务器(阿里云改名叫救援模式了),这样才能看到虚拟机的启动过程,并且看到引导菜单。
重启后看到新增的启动项并且可以正常引导就说明成功了。
把自定义的镜像覆盖原系统
复制好文件后,按如下命令进行覆盖(对应参数请自己替换):
dd if=/run/miso/img_dev/root/Alma8.10-8G.img of=/dev/vda bs=1M status=progress
如果不出意外的话,应该执行完成之后,重启就可以进入你之前封装的系统了。
如果你使用的是我的镜像,那用户名是vanilla
,密码是GTX1080Ti
,root密码相同
扩容分区
由于在其用的是小容量的虚拟机硬盘,所以覆盖过去后,分区大小还是一样的,需要扩容。
安装cloud-utils-growpart
软件包:
yum install cloud-utils-growpart
确定需要扩容的分区(一般是/
如果你用的是我的镜像,那应该是vda5):
[root@NekoWorks ~]# df -hT
Filesystem Type Size Used Avail Use% Mounted on
devtmpfs devtmpfs 1.9G 0 1.9G 0% /dev
tmpfs tmpfs 2.0G 0 2.0G 0% /dev/shm
tmpfs tmpfs 2.0G 8.6M 2.0G 1% /run
tmpfs tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
/dev/vda5 ext4 5.2G 2.8G 2.5G 53% /
/dev/vda3 ext4 574M 156M 407M 28% /boot
/dev/vda2 vfat 50M 4.0K 50M 1% /boot/efi
tmpfs tmpfs 393M 0 393M 0% /run/user/0
然后,执行扩容:
[root@NekoWorks ~]# growpart /dev/vda 5
CHANGED: partition=5 start=5543936 old: size=11227136 end=16771071 new: size=78342111 end=83886046
注意,有一个5
之前有一个空格
这还没完,需要登陆cockpit面板进一步操作,我的系统我已经预装了cockpit面板和mcsm面板,cockpit面板的用户名和密码和系统同步,mcsm的没有设置,打开即可进行初始化。cockpit面板端口9090
,例如172.16.0.11:9090
;mcsm的面板端口23333
,例如172.16.0.11:23333
。
登陆cockpit面板,找到硬盘分区,增长内容:
更改密码
如果你使用的是我的镜像,为了安全,完成工作后请立即更换密码:
passwd
passwd vanilla
同时,记得打开mcsm面板创建账户,以免被他人创建并利用!
到此,系统更换工作即可完成。