阿里云轻量应用服务器 Ubuntu 迁移 Arch Linux 操作手册

阿里云轻量应用服务器 Ubuntu 迁移 Arch Linux 操作手册

这篇记录一次在阿里云轻量应用服务器上,把正在运行的 Ubuntu 换成 Arch Linux 的过程。适用这台 x86_64、单盘、GPT、UEFI、ext4、DHCP 的机器,整理日期是 2026-10-17。

高风险:这是替换操作系统,不是普通升级。 会中断服务,并可能导致 SSH 失联或无法启动。先完成异地备份,并确认控制台还能连上、能看到启动画面,再进入会改磁盘的步骤。不要把全文复制后一次执行。

1. 记录范围与成功结论

本次采用的路线是:

1
2
3
4
5
6
7
8
Ubuntu 正常运行
→ 在 /opt/arch-install/root.x86_64 准备 Arch 基础系统
→ 下载 ISO 到 /boot/iso/archlinux.iso
→ 用现有 Ubuntu GRUB loopback 启动 Arch Live,copytoram=y
→ 在 Live 中替换 /dev/vda3 的根目录内容,保留 ext4 和 UUID
→ 挂载 EFI,arch-chroot 到硬盘 Arch
→ 配置 initramfs、GRUB、DHCP 和 admin SSH 密码登录
→ 退出、卸载、重启,从硬盘启动 Arch Linux

迁移结束后,系统可以从硬盘启动并登录。现场记录没有逐条留下全部命令输出,部分截图也只有失效链接,因此不能把后面每一条建议都说成已经在这台机器上执行并验证过。

正文按三种材料区分:

  • 现场参数:设备、UUID、路径、地址和配置,都来自这台机器当时的记录。
  • 整理后的操作:把步骤重排,把被压成一行的配置拆开,并修正其中的错误和风险。
  • 安全修订方案:根目录替换改为“先隔离旧文件,再复制且不删除源目录”,用来代替嵌套源目录上的 rsync --delete。这个修订方案没有在这台机器上再执行一遍。

本文不是通用无人值守重装脚本。其他机器必须重新确认磁盘、UUID、引导方式、网卡及恢复条件。

2. 本次真实环境与参数

项目原记录值说明
平台阿里云轻量应用服务器沿用原实例
原系统Ubuntu有 Docker 等应用数据
原主机名iZwz99y3lhlxdjrkl7geclZ来自终端提示符
架构x86_64使用 x86_64 Bootstrap / ISO
内存3.5 GiBUbuntu 检查时 available 约 2.7 GiB
Swap0 B内存不足时不能依赖交换空间
系统盘/dev/vda,50 GiBVirtio 磁盘
分区表GPT对话后续检查总结确认
/dev/vda11 MiB原对话称 BIOS Boot;本次 UEFI 不使用它,保留
/dev/vda2200 MiB,FAT32EFI System Partition,挂载 /boot/efi
EFI UUID4AA9-6FC3必须现场复核
/dev/vda349.8 GiB,ext4Ubuntu 根分区,随后作为 Arch 根分区
根 UUIDb4cbd348-1941-41f0-908b-42f34f456dcc保留文件系统时保持不变
原可用空间约 24.2 GiB,使用率 46%后续下载、复制会改变此值
启动方式UEFI/sys/firmware/efi 存在
Secure Boot 检查This system doesn't support Secure Boot不等于所有云实例都支持相同配置
原 EFI 启动项Boot0006* Ubuntu路径 \EFI\ubuntu\shimx64.efi
原 BootOrder0006,0000,0001,0002,0003,0004,0005历史状态,不能当作新系统启动顺序
网卡eth0新系统用 net.ifnames=0 配合配置
IPv4 租约172.17.31.160/18私网地址,不写死为静态地址
网关172.17.63.253来自 DHCP 租约
网络方案systemd-networkd + DHCPDNS 使用 systemd-resolved
串口ttyS0,115200n8保留启动日志输出
Bootstrap 原文件~/archlinux-bootstrap-x86_64.tar.zst这里的 ~ 是下载用户的家目录
安装源/opt/arch-install/root.x86_64与目标根目录在同一分区
ISO 版本2026.10.01本次历史版本,不代表以后最新版本
ISO 本地路径/boot/iso/archlinux.iso位于 /dev/vda3
Live 挂载目标/mnt/target必须实际挂载,空目录不算
Arch 引导名称ArchLinuxEFI 路径通常 \EFI\ArchLinux\grubx64.efi
最终 SSH 用户admin使用密码登录,禁止 root SSH 登录
新主机名配置archlinux原对话给出的设置

**未提供的参数:**公网 IP、最终 ArchLinux EFI 启动编号、最终内核版本及最终完整验收输出。本文不补造这些值。原对话的 0007 只是 EFI 编号示例。

3. 必须区分的四种执行环境

标签当前环境/ 的含义可以做什么
UUbuntu 宿主正在运行的 /dev/vda3下载、检查、准备 Bootstrap、配置旧 GRUB
BUbuntu 内的 Bootstrap chroot安装源目录安装 Arch 软件及配置未来系统;仍用 Ubuntu 内核
LArch Live ISO通常 airootfs / overlay离线挂载磁盘、替换根文件、进入目标 chroot
TLive 中的目标 chroot/mnt/target 对应的硬盘根配置将来从硬盘启动的 Arch;仍使用 Live 内核
A重启后的硬盘 Arch/dev/vda3验证真实启动、网络和 SSH 服务

判断时组合使用:

1
2
3
cat /etc/os-release
findmnt /
uname -r

cat /etc/os-release 在 B、L、T、A 都可能显示 Arch,单独使用不能证明已从硬盘启动。uname -r 在 chroot 中仍显示宿主内核。提示符也可能沿用宿主设置,不能作为充分证据。

在 L 中进入 T 前,额外检查:

1
2
3
mountpoint /mnt/target
findmnt -M /mnt/target
cat /mnt/target/etc/os-release

必须确认它是 /dev/vda3,且文件内容已经是 Arch。chroot 不是独立 Live 环境,不能用于安全覆盖仍在运行的 Ubuntu 根文件系统。

4. 风险边界与恢复准备

开始前完成:

  1. 在控制台创建可用的系统盘备份/快照,并核实当前产品的恢复方式;另做异地数据备份。
  2. 单独导出 Docker Compose、环境文件、数据库一致性备份、卷数据、网站配置、证书、SSH 公钥和应用配置。磁盘快照不自动保证数据库一致性。
  3. 验证阿里云远程控制台能实际连接、看到启动画面并输入命令。控制台是输入输出入口,不自动提供独立救援系统。
  4. 确认 TCP 22 入站规则允许管理员访问,并记录公网连接地址。
  5. 保存分区、UUID、路由、EFI 配置到本地电脑;服务器内的唯一副本不算异地备份。
  6. 规划停机窗口,停止业务写入后再制作最终数据备份。

禁止操作:

  • 不对 /dev/vda3 执行 mkfs、wipefs 或 DD;安装源和 ISO 都在该分区内。
  • 不对 /dev/vda2 重新格式化;本次复用现有 EFI。
  • 不在运行中的 Ubuntu 对 / 执行删除或镜像覆盖。
  • 不因 copytoram=y 或根目录为 airootfs 就认定 ISO 已完全脱离系统盘。
  • 不用 umount -l、强制卸载或批量 losetup -D 绕过占用问题。
  • 不将示例 EFI 编号、公网地址或旧 DHCP 租约直接当成新机器参数。

恢复边界:在替换前,旧 Ubuntu 仍可能作为回退入口;替换后,保留 Ubuntu EFI 文件不等于 Ubuntu 仍能启动。必须通过 Live、外部救援或备份恢复。

5. 环境检查(U)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
uname -m
lsblk -f
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS
findmnt /
cat /proc/cmdline
test -d /sys/firmware/efi && echo UEFI || echo BIOS
sudo parted /dev/vda print
sudo blkid /dev/vda2 /dev/vda3
sudo efibootmgr -v
sudo mokutil --sb-state
ip -br addr
ip route
systemctl is-active systemd-networkd NetworkManager
ls -lh /boot
sudo ls -lh /boot/efi/EFI/ubuntu/
free -h
df -h /
grep -E 'CONFIG_(BLK_DEV_LOOP|BLK_DEV_INITRD|VIRTIO_BLK|VIRTIO_NET)=' /boot/config-$(uname -r)

原 Ubuntu 内核中 CONFIG_BLK_DEV_INITRD、CONFIG_BLK_DEV_LOOP、CONFIG_VIRTIO_BLK、CONFIG_VIRTIO_NET 均为 y。这证明 Ubuntu 内核能力,不能替代新 Arch 内核/initramfs 验证。

原 GRUB 设置为 GRUB_DEFAULT=0、隐藏菜单、超时 1 秒;后面改为显示菜单,方便控制台选择。

6. Bootstrap 解压与基础安装(U → B)

6.1 下载与校验

本次文件已经下载到普通用户的 ~。下载入口使用 Arch 官方下载页。压缩包与签名必须来自同一个版本。

在解压前验证签名:

1
gpg --verify archlinux-bootstrap-x86_64.tar.zst.sig archlinux-bootstrap-x86_64.tar.zst

若缺少签名公钥,从官方发布信息核对签名者及完整指纹后再导入。不能仅因“Good signature”就忽略公钥来源。原记录没有完整保留本次签名验证输出。

6.2 安装 Ubuntu 工具并解压

1
2
3
4
5
6
sudo apt update
sudo apt install -y curl wget gnupg zstd tar xz-utils rsync parted gdisk efibootmgr
sudo mkdir -p /opt/arch-install
sudo tar --numeric-owner -xpf ~/archlinux-bootstrap-x86_64.tar.zst -C /opt/arch-install
ls /opt/arch-install/root.x86_64/usr/bin/pacman
ls /opt/arch-install/root.x86_64/usr/bin/bash

不要先 sudo -i 再照抄 ~/...,否则 ~ 会变成 root 家目录。原记录曾安装 kexec-tools,但最终采用 GRUB ISO 路线,本文不要求使用 kexec。

6.3 进入 Bootstrap

以下手工挂载方式沿用原记录。各挂载只执行一次;重复操作前先检查 findmnt -R "$ARCHROOT"。

1
2
3
4
5
6
7
8
9
10
11
12
13
sudo -i
ARCHROOT=/opt/arch-install/root.x86_64
cp -L /etc/resolv.conf "$ARCHROOT/etc/resolv.conf"
mount --bind "$ARCHROOT" "$ARCHROOT"
mount -t proc proc "$ARCHROOT/proc"
mount --rbind /sys "$ARCHROOT/sys"
mount --make-rslave "$ARCHROOT/sys"
mount --rbind /dev "$ARCHROOT/dev"
mount --make-rslave "$ARCHROOT/dev"
mount --rbind /run "$ARCHROOT/run"
mount --make-rslave "$ARCHROOT/run"
chroot "$ARCHROOT" /bin/bash
cat /etc/os-release

现在进入 B。不要在这里运行会重启宿主或切换宿主网络的操作。

6.4 配置镜像与安装软件(B)

1
2
3
4
5
6
7
8
9
10
11
cat > /etc/pacman.d/mirrorlist <<'EOF'
Server = https://mirrors.aliyun.com/archlinux/$repo/os/$arch
Server = https://mirrors.tuna.tsinghua.edu.cn/archlinux/$repo/os/$arch
EOF
pacman-key --init
pacman-key --populate archlinux
pacman -Syu --needed archlinux-keyring
pacman -S --needed base linux linux-firmware mkinitcpio grub efibootmgr \
openssh sudo vim nano curl wget rsync e2fsprogs dosfstools \
iproute2 iputils systemd arch-install-scripts
pacman -Q linux grub openssh systemd

镜像配置每个 Server 独占一行,单引号 heredoc 保留 $repo、$arch 给 pacman 展开。

原对话曾使用 pacman -Sy --needed archlinux-keyring 随后 pacman -Syu。本文优先完整升级;若旧密钥环确实阻止升级,应按官方密钥环恢复流程处理,不能长期停在仅同步数据库的状态,也不要关闭签名检查。

6.5 系统基础配置(B)

1
2
3
4
5
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
sed -i 's/^#en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen
locale-gen
printf 'LANG=en_US.UTF-8\n' > /etc/locale.conf
printf 'archlinux\n' > /etc/hostname

原对话还建议 hwclock --systohc。chroot 共享宿主硬件接口,该命令可能修改宿主 RTC;本路线不需要在 Bootstrap 内执行,正式启动后按云环境时间同步方案处理。

配置 networkd 和 admin SSH 见第 11、12 节,可先在 B 中准备;迁移后的 T 中必须再次核对。安装源内只配置,不提前安装硬盘 EFI 引导。

6.6 退出并清理准备挂载(U)

1
2
3
4
5
exit
cd /
ARCHROOT=/opt/arch-install/root.x86_64
findmnt -R "$ARCHROOT"
umount -R "$ARCHROOT"

必须在 Ubuntu 宿主执行,且前面的自绑定挂载确实存在。若 busy,先关闭所有 Bootstrap shell、离开目录并排查进程,不能强制卸载。

检查安装源大小与内核:

1
2
3
4
du -sh /opt/arch-install/root.x86_64
ls -lh /opt/arch-install/root.x86_64/boot/vmlinuz-linux
ls -lh /opt/arch-install/root.x86_64/boot/initramfs-linux.img
df -h /

本文修订流程会临时保留旧 Ubuntu 文件并再复制一份 Arch;必须有足够剩余磁盘空间。3.5 GiB 内存不适合假定能额外装下完整 Arch 安装源,因此不把整套安装源搬到 tmpfs。

7. 下载阿里云 ISO 并检查(U)

本次用户指定且随后反馈已下载的 URL:

1
2
3
4
5
sudo mkdir -p /boot/iso
sudo wget -c \
https://mirrors.aliyun.com/archlinux/iso/2026.10.01/archlinux-2026.10.01-x86_64.iso \
-O /boot/iso/archlinux.iso
ls -lh /boot/iso/archlinux.iso

原对话还提供了以下候选地址,不表示现在一定可下载:

  • https://geo.mirror.pkgbuild.com/iso/2026.10.01/archlinux-2026.10.01-x86_64.iso
  • http://mirrors.cloud.aliyuncs.com/archlinux/iso/2026.10.01/archlinux-2026.10.01-x86_64.iso

公网镜像策略和内网可达性会变化;轻量应用服务器不保证可访问 ECS 内网镜像。HTTP 下载尤其需要可信签名验证。切换源时只对确定是同一文件的下载使用断点续传;校验失败应重新下载。

原记录中的 SHA256 为:

1
684ded26c63240ff4a41e8c25ee84ea6da233f557364821f13d12c2b0a9059a5

该值是历史对话提供值,本文未独立验证其对应的 ISO,不能作为唯一信任依据。 应从可信官方发布渠道取得该版本的校验文件/签名,核对版本、文件名、完整散列及签名者。对本地重命名文件执行 sha256sum /boot/iso/archlinux.iso,与已验证的原始文件条目比较;不能不改路径就直接拿原名校验本地重命名文件。

检查 ISO 内部布局:

1
2
3
4
5
sudo mkdir -p /mnt/archiso
sudo mount -o loop,ro /boot/iso/archlinux.iso /mnt/archiso
ls -lh /mnt/archiso/arch/boot/x86_64/
sudo cat /mnt/archiso/boot/grub/loopback.cfg
sudo umount /mnt/archiso

必须核对内核、initramfs 的实际路径,后文仅适用原记录中的路径。copytoram=y 会占用大量内存;检查内存预算并停止不必要的业务。ISO 文件大小不等于最终全部内存占用。

8. Ubuntu GRUB loopback 引导 Live(U)

备份:

1
2
3
sudo cp -a /etc/default/grub /etc/default/grub.before-arch
sudo cp -a /etc/grub.d/40_custom /etc/grub.d/40_custom.before-arch
sudo cp -a /boot/grub/grub.cfg /boot/grub/grub.cfg.before-arch

编辑 /etc/grub.d/40_custom,保留原脚本头部,在末尾加入以下菜单。以 ISO 自带配置为最终依据,若路径或参数不同则先修正:

1
2
3
4
5
6
7
8
9
10
menuentry "Arch Linux Live ISO" --id arch-live {
insmod part_gpt
insmod ext2
insmod loopback
search --no-floppy --fs-uuid --set=root b4cbd348-1941-41f0-908b-42f34f456dcc
set isofile="/boot/iso/archlinux.iso"
loopback loop $isofile
linux (loop)/arch/boot/x86_64/vmlinuz-linux img_dev=/dev/disk/by-uuid/b4cbd348-1941-41f0-908b-42f34f456dcc img_loop=$isofile earlymodules=loop copytoram=y console=tty0 console=ttyS0,115200n8
initrd (loop)/arch/boot/x86_64/initramfs-linux.img
}

在 /etc/default/grub 修改已有定义,不叠加重复定义:

1
2
3
GRUB_DEFAULT=0
GRUB_TIMEOUT_STYLE=menu
GRUB_TIMEOUT=10

确认菜单第 0 项仍是 Ubuntu;0 只表示第一个菜单项,不固有代表 Ubuntu。

1
2
3
4
5
sudo update-grub
sudo grub-script-check /boot/grub/grub.cfg
sudo grep -A 15 'Arch Linux Live ISO' /boot/grub/grub.cfg
sudo grub-reboot arch-live
sudo grub-editenv list

应看到 next_entry=arch-live。这是旧 GRUB 的一次性菜单选择,与 UEFI 的 BootNext 是两个层级。语法检查不证明 ISO 一定可启动;一次性引导也不保证失败后自动回到 Ubuntu。

确认备份、控制台均可用,再执行:

1
sudo reboot

Live 不继承 Ubuntu 的 admin 密码,首次从控制台进入。不要因 SSH 暂时不通就判断启动失败。

9. Live 验证与 ISO 源分区占用(L)

1
2
3
4
5
6
7
8
9
10
11
cat /etc/os-release
findmnt /
cat /proc/cmdline
lsblk -f
findmnt -S /dev/vda3
findmnt /run/archiso/bootmnt
findmnt -R /run/archiso
losetup -a
free -h
ip -br addr
ip route

原对话确认 Live 根为 airootfs。但还必须检查完整依赖链:

1
2
/dev/vda3 → 挂载的源文件系统 → archlinux.iso → ISO loop
→ airootfs.sfs → squashfs loop → Live 根

也可能看到 squashfs 后端已转到 /run/archiso/copytoram/...,表示数据在内存路径。存在 loop 本身不是错误;关键是 loop 后端是否仍位于 /dev/vda3。 对可疑后端路径用 findmnt -T 实际后端路径 追溯文件系统,不能只搜索 /mnt/target 字样;同一分区可能挂在 /run/archiso/img_dev。

9.1 允许继续的条件

  • Live 根不是 /dev/vda3。
  • 活跃 Live squashfs/overlay 的后端不依赖该分区中的 ISO 或其他文件。
  • /dev/vda3 没有被 archiso 以只读形式继续占用,或已经通过正常卸载完成释放。
  • 所有可能需要的工具已经可用,网络/控制台可工作,内存有余量。

若仍有 ISO 依赖:停在本节,不 remount 强行写入、不删 ISO、不 detach 正在用的 loop。 核对 /proc/cmdline 和该 ISO 的 copytoram 实现,必要时重新从正确参数启动或使用独立救援介质。仅当确认某个挂载/loop 已不被 Live 根依赖时,才按“最内层挂载 → 对应 loop → 外层源挂载”逐个正常释放并复查。不能把固定 loop0、loop1 写进批量卸载命令。

ISO 释放后尚未挂载目标时,findmnt -S /dev/vda3 应没有相关挂载。先按只读方式检查安装源:

1
2
3
4
5
6
mkdir -p /mnt/target
mount -o ro /dev/vda3 /mnt/target
findmnt -M /mnt/target
cat /mnt/target/opt/arch-install/root.x86_64/etc/os-release
ls -lh /mnt/target/opt/arch-install/root.x86_64/boot/
du -sh /mnt/target/opt/arch-install/root.x86_64

安装源必须为 Arch 且有内核。注意 ext4 普通只读挂载仍可能回放日志;若用于事故取证应采用专门的无写入流程,本文是安装流程。

9.2 Live 网络临时恢复

Live 网卡名可能不是 eth0,因为上述 Live 菜单没有设置 net.ifnames=0。先用 ip -br link 识别实际名字,再为实际网卡配置 DHCP、启动 networkd;不要直接照搬网卡名。临时修改 Live 的配置不会自动进入硬盘 Arch。

10. 根文件系统替换:安全修订方案(L)

10.1 为什么不直接照抄原来的 rsync –delete

原记录设置:

1
2
SRC=/mnt/target/opt/arch-install/root.x86_64
DST=/mnt/target

源目录位于目标内部。对目标使用 --delete,若安装源保护失效,rsync 会把源当成目标多余内容删除,后续出现文件消失或迁移中断。ISO 也有同样风险。

原记录用 --exclude='/opt/arch-install/***' 等保护目录;标准 rsync 排除规则通常同时影响发送端与接收端删除保护,但保护依赖路径和选项,不是任意情形的保证。不能添加 --delete-excluded,也不能只写发送端隐藏规则就以为接收端安全。详见 rsync 官方手册。

此外,原 -n 模拟没有 -i 或 -v,可能看不到足够的逐项变化;被排除的旧 /dev、/run、/tmp 内容也会留下。仅去掉 --delete 则会残留大量旧 Ubuntu 文件,尤其旧 /bin、/lib 等结构可能与 Arch 的符号链接冲突。

本文改为先在同一 ext4 内隔离旧内容,再 rsync 无删除复制。 这样能避免在嵌套源上运行删除同步;需要足够磁盘空间,并且中途失败后不能直接重启。

10.2 写入前关卡

以下只适用于“尚未替换,旧根仍是 Ubuntu”的机器。已经成功安装 Arch 的机器不要重跑第 10 节。

完成第 9 节的 ISO 释放检查后:

1
2
3
4
5
6
umount /mnt/target
mount -o rw /dev/vda3 /mnt/target
findmnt -M /mnt/target
findmnt -R /mnt/target
blkid /dev/vda3
df -h /mnt/target

此时目标下不得挂载 EFI 或其他子文件系统。findmnt -R /mnt/target 应只有目标本身。Bootstrap 的 /dev、/sys 等也不能仍有子挂载。若存在,先查清并正常卸载;本文不使用强制卸载。

剩余空间应大于安装源再复制一份所需空间,并留出包缓存、initramfs 和日志余量。原可用空间不能替代此时检查。

10.3 隔离旧 Ubuntu 文件

这是本手册新增的安全修订,并非原实例执行日志。使用 Live 的 Bash,核对每一项后执行。所有路径固定为本次目标,脚本通过条件检查后才移动文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
bash <<'BASH'
set -euo pipefail
DST=/mnt/target
SRC=$DST/opt/arch-install/root.x86_64
OLD=$DST/.ubuntu-retired

mountpoint -q "$DST"
test "$(findmnt -n -o UUID -M "$DST")" = b4cbd348-1941-41f0-908b-42f34f456dcc
test "$(findmnt -Rrn -o TARGET "$DST" | wc -l)" -eq 1
test -d "$SRC/usr"
grep -qx 'ID=arch' "$SRC/etc/os-release"
grep -qx 'ID=ubuntu' "$DST/etc/os-release"
test -f "$SRC/boot/vmlinuz-linux"
test ! -e "$OLD"
test ! -L "$OLD"
test -d "$DST/opt" && test ! -L "$DST/opt"
test -d "$DST/boot" && test ! -L "$DST/boot"

mkdir "$OLD"
mkdir "$OLD/opt" "$OLD/boot"
shopt -s dotglob nullglob

# 保留安装源父目录、ISO 父目录和 ext4 lost+found;其余顶层内容隔离。
for path in "$DST"/*; do
name=${path##*/}
case "$name" in
opt|boot|.ubuntu-retired|lost+found) continue ;;
esac
mv -- "$path" "$OLD/"
done

for path in "$DST/opt"/*; do
case "${path##*/}" in arch-install) continue ;; esac
mv -- "$path" "$OLD/opt/"
done
for path in "$DST/boot"/*; do
case "${path##*/}" in iso|efi) continue ;; esac
mv -- "$path" "$OLD/boot/"
done
BASH

同一文件系统内 mv 通常只是目录项移动,不立即复制全部旧数据。这里保留 boot/efi 空挂载点,实际 EFI 此时必须未挂载。若保留路径有异常符号链接或旧内容,先检查,不盲目继续。

任一命令失败,停止并检查现场。脚本不是事务,不会自动回滚,也不能在隔离完成一半时直接重跑。此时 Ubuntu 已不完整,不能重启。 .ubuntu-retired 是临时隔离副本,不是独立备份;启动文件和 EFI 也不是完整原样快照。

10.4 无删除复制 Arch

以下在同一个 Live Bash shell 定义选项,模拟与正式复制使用同一组规则:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
SRC=/mnt/target/opt/arch-install/root.x86_64
DST=/mnt/target
RSYNC_OPTS=(
-aHAXx --numeric-ids
--exclude='/opt/arch-install/***'
--exclude='/boot/iso/***'
--exclude='/boot/efi/***'
--exclude='/.ubuntu-retired/***'
--exclude='/dev/***'
--exclude='/proc/***'
--exclude='/sys/***'
--exclude='/run/***'
--exclude='/tmp/***'
--exclude='/mnt/***'
--exclude='/media/***'
)
rsync "${RSYNC_OPTS[@]}" --dry-run --itemize-changes "$SRC/" "$DST/"

确认源目标路径、无意外目录后执行:

1
2
rsync "${RSYNC_OPTS[@]}" --itemize-changes "$SRC/" "$DST/"
echo "rsync exit=$?"

应为退出码 0;出现 I/O 错误、空间不足、源文件消失或非零退出码,不能直接进入重启步骤。修复后可重试复制,但不要重新执行旧文件隔离脚本。

-aHAX 保留权限、链接、ACL 和扩展属性;--numeric-ids 按 UID/GID 保存属主;-x 不跨源子挂载,但不能替代挂载检查;"$SRC/" 尾随斜杠表示复制源内容。此处故意没有 --delete。

建立空的运行时目录并验收:

1
2
3
4
5
6
mkdir -p /mnt/target/{dev,proc,sys,run,tmp,mnt,media,boot/efi}
chmod 1777 /mnt/target/tmp
cat /mnt/target/etc/os-release
ls -ld /mnt/target/bin /mnt/target/sbin /mnt/target/lib /mnt/target/lib64
ls -lh /mnt/target/boot/vmlinuz-linux /mnt/target/boot/initramfs-linux.img
rsync "${RSYNC_OPTS[@]}" --dry-run --itemize-changes "$SRC/" "$DST/"

最终模拟应没有未解释的变化。安装后配置会有变化,后续不要为了“完全相同”再覆盖目标配置。保留安装源和旧文件隔离目录直到正式启动验证后再清理。

11. EFI 挂载、fstab、initramfs 和 GRUB(L → T)

11.1 挂载 EFI,生成 fstab(L)

1
2
3
4
5
6
mkdir -p /mnt/target/boot/efi
mount /dev/vda2 /mnt/target/boot/efi
findmnt -M /mnt/target/boot/efi
blkid /dev/vda2 /dev/vda3
genfstab -U /mnt/target > /mnt/target/etc/fstab
cat /mnt/target/etc/fstab

只保留现场需要的挂载,不得混入 Live ISO、loop、Bootstrap、自绑定或临时目录。本次核心应与以下一致:

1
2
UUID=b4cbd348-1941-41f0-908b-42f34f456dcc / ext4 defaults 0 1
UUID=4AA9-6FC3 /boot/efi vfat umask=0077 0 2

genfstab 生成的具体选项可能不同,应检查并按需要整理。生成用 > 覆盖而不是重复 >> 追加。UUID 以当前 blkid 为准;格式化后旧 UUID 不再可靠。

11.2 进入硬盘 Arch(T)

1
2
3
arch-chroot /mnt/target
cat /etc/os-release
pacman -Q linux grub openssh systemd

如果目标未挂载,不要进入一个普通空目录;如果还显示 Ubuntu,回到迁移阶段检查,不能继续安装 Arch 引导。

11.3 内核和 initramfs

1
2
3
4
5
ls -lh /boot/vmlinuz-linux
ls /usr/lib/modules
mkinitcpio -P
ls -lh /boot/initramfs-linux.img
lsinitcpio /boot/initramfs-linux.img

检查生成是否成功,确认磁盘、根文件系统能力覆盖 Virtio 和 ext4。不要用 chroot 中的 uname -r 作为安装内核版本依据。

若存在自动探测遗漏风险,可在 /etc/mkinitcpio.conf 的现有 MODULES=(...) 中合并加入:

1
MODULES=(virtio_pci virtio_blk ext4)

保留已有所需模块,不机械替换整行;修改后重新 mkinitcpio -P。本次磁盘是 Virtio block,换机器应按真实控制器确认所需模块。virtio_net 为联网能力,通常在根文件系统挂载后加载,不等同于根磁盘驱动。

11.4 安装 UEFI GRUB

确认 EFI 确实挂载在 /boot/efi,且 Live 以 UEFI 启动:

1
2
3
4
test -d /sys/firmware/efi
findmnt /boot/efi
grub-install --target=x86_64-efi \
--efi-directory=/boot/efi --bootloader-id=ArchLinux --recheck

200 MiB EFI 只放 GRUB EFI 文件,内核和 initramfs 放在 ext4 /boot,避免把整个 /boot 挂到小 EFI 分区。

编辑 /etc/default/grub,修改已有定义:

1
2
3
4
GRUB_DEFAULT=0
GRUB_TIMEOUT=5
GRUB_TIMEOUT_STYLE=menu
GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 net.ifnames=0 console=tty0 console=ttyS0,115200n8"

该参数保留原对话最后建议,去掉 quiet 方便首次排错;需要更多日志时可在控制台临时去掉 loglevel=3。

1
2
3
4
5
6
grub-mkconfig -o /boot/grub/grub.cfg
grub-script-check /boot/grub/grub.cfg
grep '^menuentry ' /boot/grub/grub.cfg
grep -E 'linux.*(vmlinuz|root=)' /boot/grub/grub.cfg
ls -lh /boot/efi/EFI/ArchLinux/grubx64.efi
efibootmgr -v

检查 GRUB 指向正确根 UUID、内核和 initramfs。仅存在一个名为 ArchLinux 的 EFI 条目不证明其文件和配置有效。

GRUB_DEFAULT=0 选择的是进入当前 GRUB 后的第一个菜单项;UEFI 是否先加载 ArchLinux 由 BootOrder/BootNext 决定,两者不能混为一谈。

12. systemd-networkd 和 DNS(B 或 T,最终在 T 复核)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mkdir -p /etc/systemd/network
cat > /etc/systemd/network/20-eth0.network <<'EOF'
[Match]
Name=eth0

[Network]
DHCP=ipv4

[DHCPv4]
UseDNS=yes
UseRoutes=yes
EOF
systemctl enable systemd-networkd systemd-resolved
ln -sfn /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf

记录里的 172.17.31.160/18 和 172.17.63.253 是租约,不写入静态配置。net.ifnames=0 必须确实进入最终内核命令行;若实际网卡不同,按实际名称修改配置。

1
2
3
cat /etc/systemd/network/20-eth0.network
readlink /etc/resolv.conf
systemctl is-enabled systemd-networkd systemd-resolved

chroot 中 DNS stub 链接可能暂时没有目标,因为目标 systemd-resolved 尚未运行;这不能直接等同于首次启动后 DNS 无效。如果 chroot 中需下载包,可临时使用 Live 的有效 DNS 文件,操作完成后恢复上述软链接。不要启动目标网络服务来“测试”,避免作用到宿主网络。

13. admin SSH 密码登录(T)

13.1 先确认配置落在硬盘系统

本次曾误查看 Live 的 /etc/ssh/sshd_config.d/10-archiso.conf,后续发现 /mnt/target 未挂载;重新挂载进入硬盘 Arch 后,目录仅有 20-systemd-userdb.conf 和 99-archlinux.conf。

因此,出现 10-archiso.conf 应先确认环境,不能直接认定硬盘被污染并删除 Live 配置。只有确认文件确实混入硬盘系统,备份并检查内容后才移除。

若丢失目标挂载,在 L 恢复:

1
2
3
4
5
6
mkdir -p /mnt/target
mount /dev/vda3 /mnt/target
cat /mnt/target/etc/os-release
mkdir -p /mnt/target/boot/efi
mount /dev/vda2 /mnt/target/boot/efi
arch-chroot /mnt/target

已挂载时不重复 mount。此恢复流程用于迁移已经完成的目标,不能代替系统迁移。

13.2 创建/确认用户与 sudo

1
id admin

仅不存在时执行:

1
useradd -m -G wheel -s /bin/bash admin

然后:

1
2
3
passwd admin
passwd -S admin
getent passwd admin

密码状态应为 P,shell 不能为 nologin。密码由管理员交互输入,不写入文档。

如需管理权限,使用 visudo 安全编辑 sudo 配置,启用:

1
%wheel ALL=(ALL:ALL) ALL

然后 visudo -c。原记录中的 EDITOR=visudo visudo 不合适;应直接 visudo,或 EDITOR=nano visudo。

13.3 SSH 配置

1
2
3
4
5
6
7
8
9
10
pacman -Q openssh
mkdir -p /etc/ssh/sshd_config.d
cat > /etc/ssh/sshd_config.d/10-password-login.conf <<'EOF'
PasswordAuthentication yes
KbdInteractiveAuthentication no
PermitRootLogin no
UsePAM yes
EOF
ssh-keygen -A
systemctl enable sshd

检查主配置是否包含有效的 Include /etc/ssh/sshd_config.d/*.conf,且位于适当的全局位置;检查更早配置及 Match 条件:

1
2
grep -RniE '^[[:space:]]*(Include|Match|PasswordAuthentication|PermitRootLogin|UsePAM|KbdInteractiveAuthentication|AllowUsers|DenyUsers|AuthenticationMethods)' \
/etc/ssh/sshd_config /etc/ssh/sshd_config.d/

OpenSSH 多数配置使用先取得的值,不能假定 99-... 总能覆盖前面文件;仅将文件改名为 00-... 也不能压过主文件在 Include 之前已设置的值。规则依据 OpenSSH 官方配置手册。

13.4 验证

1
2
3
4
5
6
mkdir -p /run/sshd
chmod 755 /run/sshd
sshd -t
sshd -T | grep -iE '^(passwordauthentication|permitrootlogin|usepam|kbdinteractiveauthentication) '
systemctl is-enabled sshd
passwd -S admin

期望有效值,各占一行,顺序不限:

1
2
3
4
passwordauthentication yes
permitrootlogin no
usepam yes
kbdinteractiveauthentication no

保留用户在本次纠正的 grep -iE 写法,忽略大小写。sshd -T 通常输出小写;若没有匹配,不能只归因于大小写,应先不加管道运行 sshd -T 或 sshd -T 2>&1 检查报错。

如果有 Match,还要用 sshd -T -C 带真实 user=admin、客户端地址和相应连接条件检查。全局检查不能覆盖所有用户条件。

chroot 中 systemctl enable sshd 设置未来开机启动;systemctl start sshd 或 status 不能用于证明新系统服务已运行。实际监听与密码登录必须在 A 中验证。

密码登录按本次要求保留。使用强密码,控制公网 TCP 22 可访问范围;用户未要求切换密钥,本文不把关闭密码认证作为完成条件。

14. 重启前验收与正确重启(T → L)

逐项确认:

  • 已确认目标根是 /dev/vda3 上的 Arch,源文件复制完成且无未解决错误。
  • /etc/fstab 的根/EFI UUID 与现场 blkid 一致,无 Live 临时挂载。
  • 内核与 initramfs 非空,mkinitcpio -P 无致命错误,支持真实磁盘。
  • EFI 挂载正确;GRUB EFI 文件、配置与根 UUID 一致。
  • eth0 DHCP 文件正确,最终内核参数含 net.ifnames=0。
  • networkd、resolved、sshd 均为 enabled。
  • admin 存在且密码状态为 P,SSH 语法和有效配置检查通过。
  • 控制台可用,TCP 22 规则正确,记录了可信主机密钥指纹。
  • 已识别真实 ArchLinux EFI 编号及首次启动选择。

可记录主机指纹用于客户端核对:

1
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

先退出 T,再在 L 卸载:

1
2
3
4
5
exit
cd /
sync
umount -R /mnt/target
findmnt -R /mnt/target

最后检查不应有目标挂载。busy 时先关闭其他 chroot shell、离开目录,再用 fuser -vm /mnt/target 或 lsof 排查;不能强制或 lazy 卸载后当作成功。

检查 EFI:

1
efibootmgr -v

找到真实 ArchLinux 启动号后设置一次性启动。下面是命令格式,XXXX 不是可执行的实际编号:

1
efibootmgr -n XXXX

再次 efibootmgr 验证 BootNext。BootNext 仅影响下一次启动,后续稳定启动还需要正确的 BootOrder。原 0006 是 Ubuntu,原示例 0007 不能照搬。

全部满足后,在 Live 执行:

1
reboot

不要在 chroot 中重启,也不要使用强制重启跳过同步与卸载。

15. 首次登录和持久启动验证(A)

在本地电脑用真实公网地址连接:

1
ssh admin@你的服务器公网IP

若提示主机密钥变化,先在控制台核对第 14 节记录的指纹;核对无误后再清理客户端对应旧记录。不能直接关闭主机密钥校验。

登录后:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cat /etc/os-release
uname -r
findmnt /
findmnt /boot/efi
cat /proc/cmdline
ip -br addr
ip route
networkctl status eth0
resolvectl status
getent hosts archlinux.org
systemctl is-active sshd systemd-networkd systemd-resolved
systemctl --failed
sudo ss -lntp
sudo journalctl -b -p err
sudo efibootmgr -v

应确认 Arch、磁盘根 /dev/vda3、正常 IPv4 租约和默认路由、可解析 DNS、SSH 监听 TCP 22,且没有影响启动/联网的失败服务。通过公网成功密码登录是 admin SSH 的最终验证。

核对 BootCurrent 是 ArchLinux,并检查持久 BootOrder。若需调整,efibootmgr -o 使用真实编号并保留其他必要项;不要用固定示例覆盖全部顺序。建议在备份和控制台仍可用时再做一次受控重启,验证没有 BootNext 帮助也能正常从 Arch 启动。该二次验收是本文新增建议,原记录未保留二次重启输出。

最后做完整更新:

1
sudo pacman -Syu

涉及内核/引导更新后,应根据更新结果安排验证,不在未确认网络和引导前盲目连环重启。

16. 安装残留清理(A,验收完成后)

可以暂时保留源、ISO 和隔离旧文件作为排错材料;它们含敏感信息,应限制访问。清理前确认当前系统确实从硬盘运行,并将所需数据移出服务器或恢复到新应用。

1
2
3
4
5
findmnt /
findmnt -R /opt/arch-install
findmnt -R /.ubuntu-retired
losetup -a
sudo du -sh /opt/arch-install /.ubuntu-retired /boot/iso

逐个核对实际绝对路径不是符号链接、内部无挂载、ISO 不再作 loop 后端,确认内容无需保留后,才可分别执行以下永久删除命令:

1
2
3
sudo rm -rf --one-file-system -- /opt/arch-install
sudo rm -rf --one-file-system -- /.ubuntu-retired
sudo rm -f -- /boot/iso/archlinux.iso

/.ubuntu-retired 仅由本文修订流程创建;若按原过程安装,可能不存在。--one-file-system 只是额外保护,不替代挂载检查(同一文件系统 bind mount 仍需排除)。

保留 Ubuntu EFI 文件不会恢复 Ubuntu。若后续需要移除旧 EFI 项或文件,先核对 BootCurrent、备份 EFI、确认不依赖其回退路径,再单独处理;不要批量删除整个 EFI 目录。新 GRUB 配置中也不应保留指向已删除 ISO 的默认启动项。

17. 故障排查

现象优先检查处理边界
下载 ISO 很慢/失败镜像可达性、HTTP 状态、文件是否实际上是 HTML改可信镜像,重新验证版本和签名,不能只看文件名
pacman 下载慢mirrorlist 是否一行一个 Server、DNS、HTTPS改阿里云/清华源,完整 pacman -Syu;已装 openssh 不必为了设置密码再同步数据库
core/extra 数据库不存在是否尚未同步,pacman -Q openssh 是否有结果本地包查询和仓库数据库是两回事;不关闭签名检查
GRUB 找不到 ISO 内核ISO 是否下载完整、内部路径、根 UUID、isofile回旧系统检查 ISO 的 loopback.cfg,语法通过不等于可启动
Live OOM / 无法复制到 RAMfree -h、实际 ISO 大小、copytoram 参数换独立救援方案或增加可用内存,不以强制卸载代替 RAM 复制
Live 根是 airootfs,但 vda3 仍被占用archiso 全部挂载及 loop 后端链停止迁移,按第 9 节排查;不能仅 remount rw
/mnt/target 未挂载mountpoint、findmnt -M挂载正确根分区,确认 Arch 后再 chroot;不重复格式化
目标仍显示 Ubuntu源目标路径、rsync 返回码、是否复制到错误目录完成迁移后再装引导;不要通过改 os-release 伪造成功
rsync 源文件消失是否误用 –delete、源是否嵌套、目标/源是否颠倒停止;保留现场,从备份恢复源,不立即重启
rsync 空间不足df -h / df -i、源大小、隔离目录占用保留可用安装源,改用独立存储或审慎释放已备份数据,不能盲删全部旧文件
mkinitcpio 失败/usr/lib/modules、内核包、磁盘驱动、/boot 容量在目标 chroot 修复并重建,不沿用宿主 uname 推断
EFI variables 不可用Live 是否 UEFI 启动、efivarfs、固件权限修复 UEFI 访问条件;--no-nvram 只写文件不保证固件能找到
找不到 ArchLinux EFI 项grub-install 是否成功、ESP 是否实际挂载核对文件及 NVRAM;不能只建一个名字当作修复完成
开机又进 Ubuntu/旧 GRUBBootOrder、BootNext、BootCurrent调整真实 ArchLinux 项;GRUB_DEFAULT 不控制 EFI 层
开机没有网络实际网卡名、/proc/cmdline、networkd 日志确保 Name 匹配实际设备,DHCP 有租约和路由
有 IP 但无法解析域名resolved 状态、resolv.conf 链接、租约 DNS分别处理链路和 DNS,不写死旧私网租约
SSH 拒绝连接/超时控制台是否已启动、22 入站、sshd 监听及网络区分网络超时、无监听与认证失败
SSH 密码认证失败passwd -S、有效配置、Match/AllowUsers/PAM、日志在硬盘目标修复;Live 的密码和配置不能验证硬盘账号
sshd -T | grep 无输出先执行无管道 sshd -T、看错误流使用用户确认的 -iE;仍无结果则查语法/密钥/环境
sshd 目录出现 10-archiso.conf当前是 L 还是 T不自动删除 Live 配置;先进入正确硬盘系统
chroot systemctl 提示未运行 systemd当前环境是否 T/Benable 可配置未来启动;active/status 只在 A 作最终验收
卸载 target busyshell 当前目录、其他 chroot、进程、ISO 链cd /、退出其他 shell,排查后正常卸载,不强制

在正式 Arch 的控制台排查网络/SSH:

1
sudo journalctl -b -u systemd-networkd -u systemd-resolved -u sshd

若无法从硬盘启动,从可用 Live/救援环境挂载根和 EFI,核对目标 os-release 后进入 T,重建 initramfs、GRUB 并复核 fstab。无需因 SSH 不通就立即重装整个系统。

18. 相对最初方案的修正

  1. 替换嵌套源 rsync --delete:采用旧文件隔离 + 无删除复制,避免源被接收端删除,旧目录与符号链接结构也先移开。
  2. 模拟同步加可见输出:使用 --dry-run --itemize-changes,不能把“没看到输出”当作删除清单安全。
  3. 严格检查 ISO 依赖链:copytoram 参数和 airootfs 不是分区已释放的证据;loop 是否安全取决于后端位置。
  4. 区分 Live 和 chroot:验证目标实际挂载及 os-release,再配置硬盘 SSH;不把 Live 的 10-archiso.conf 当作目标必然污染。
  5. 恢复配置换行:GRUB、networkd、mirrorlist、sshd 配置各指令单独一行,避免导出文本的一行粘贴错误。
  6. 校验值标注来源:保留原 ISO SHA256,但不把未经独立核实的历史值当作可信发布校验。
  7. 不固化租约/示例编号:IP 和网关继续 DHCP;0007 仅示例;最终 EFI 编号现场取得。
  8. 修正 sudo 编辑方式:用 visudo 或 EDITOR=nano visudo,不使用 EDITOR=visudo visudo。
  9. 不在 chroot 验证服务运行或重启:只配置 enable,退出后从 Live 正常卸载重启,再检查服务 active。
  10. 增加持久启动验收:BootNext 仅一次;确认 BootOrder 并做受控二次启动后再删除安装材料。

19. 参考资料与使用说明

本手册描述历史成功迁移及经过审查的操作建议,不承诺镜像地址永远可用或所有轻量服务器都支持相同启动流程。具体工具行为以当前安装版本的本地手册和现场检查为准。