Alpine Linux 存储迁移

我的两个虚拟机都在一个 500G 的 NVME 硬盘上,由于前期没想到数据备份(snapshot)操作。所以划分的有点太大了,导致现在做数据备份之后剩余存储空间所剩无几,Truenas给出了红色告警。

而且 Alpine Linux 本身就非常节省资源,即使安装了很多应用,根目录也只占用了8G左右,所以 打算把根目录所在的硬盘容量缩减至25G,这也是完全够用的。

如果你问:如果哪天需要临时放一点大文件,没有那么多存储空间怎么办呢。

答案就是:新建虚拟硬盘,挂载到给需要的目录上。这样系统备份不会和数据备份耦合,磁盘空间也不用有那么高的无效占用。数据如果需要备份,再单独创建 snapshot。

本文使用了 GPT-4o 的给出的方案。但在实际的操作过程中,修复了失败的步骤。

切记,一定要对原先的系统备份, 备份!备份!不管使用什么样的方法备份,一定要做好可靠的备份(最好的情况是你能随时随意的回滚到原先的状态)。

迁移 Linux 根目录到新的磁盘上是一个复杂的过程,需要谨慎操作,确保数据安全。以下是一个基本步骤指南:

1. 准备新磁盘

  1. 连接新磁盘:确保新磁盘已正确连接到系统上。
  2. 分区和格式化:使用 fdiskgdisk 等工具对新磁盘进行分区,然后使用 mkfs 格式化分区。

假设新的硬盘是空白的,那么需要先从分区开始,分区最好和迁移前的分区保持一致。

下面那我自己经常用的经典三分区为例

  1. 查看硬盘和分区布局
fdisk -l # 查看硬盘和分区布局

Disk /dev/sda: 64 GiB, 68719476736 bytes, 134217728 sectors
Disk model: Virtual Disk    
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: 2EE79404-614A-40F1-9901-5561C9BC321F

Device       Start       End   Sectors  Size Type
/dev/sda1     2048   2203647   2201600    1G EFI System
/dev/sda2  2203648   6397951   4194304    2G Linux filesystem
/dev/sda3  6397952 134215679 127817728 60.9G Linux filesystem
  1. 对新硬盘创建分区表,创建分区,和设置分区类型
fdisk /dev/sdX # 替换 sdX 为新磁盘的设备名,进入 fdisk CLI。


    g   # 输入 g 设置 GPT 分区表

    n   # 输入 n 创建第一个分区
        +100M   # 分区起始点应该是 2048,默认的就是这个值,在第二个问题中输入 +100M 即 创建第一个分区为 100M,第一个分区结束点自然为 2203647
    n   # 再次输入 n 创建第二个分区,此为交换分区,按照自己的需要设置,建议不低于768M
        +2G
    n   # 再次输入 n 创建第三个分区,也就是 日常使用的 根分区,这一步使用默认值就可以使用剩下的全部空间

    t   # 改变分区类型(标记出三个分区如何使用)
        1   # 对于 第一个分区 选择 1 设置为 EFI System
        swap    # 第二个分区 选择 swap
        linux   # 第三个分区 选择 linux

    w   # 输入 w 写入这些操作,注意!该操作不可逆,确认好再动手。
  1. 初始化 EFI 分区(ESP)
# 沿用之前的 EFI 分区,这样就不用格式化了,后续步骤也会省一部分
dd if=/dev/sdb1 of=/dev/sda1 # 拷贝原有的 EFI(但是不能直接用)。假设 sdb1 为老EFI,sda1为新EFI

# 或者第二种办法, 但是需要重新做 EFI 引导
# EFI 分区是 fat32 文件系统,替换 sdX 为新磁盘的设备名
mkfs.vfat -F32 /dev/sdX1
  1. 初始化 swap 分区(optional)
mkswap /dev/sda2

# 启用交换分区:
# swapon /dev/sdXn
# /etc/fstab
# /dev/sdXn none swap sw 0 0
  1. 格式化 Linux 分区
mkfs.ext4 /dev/sdX3 # 假设使用 ext4 文件系统,root 分区在第三个

2. 挂载新磁盘

  1. 创建挂载点
mkdir /mnt/new_root
  1. 挂载新分区
mount /dev/sdX1 /mnt/new_root

3. 复制数据

  1. 使用 rsync 复制数据
# 拷贝的目录取决于你挂载的位置
rsync -avxHAX / /mnt/new_root
  • -a:归档模式,保留所有属性。
  • -v:详细输出。
  • -x:不跨文件系统。
  • -H:保留硬链接。
  • -A:保留 ACL。
  • -X:保留扩展属性。

4. 更新配置

4.1. 更新fstab:编辑 /mnt/new_root/etc/fstab,更新新的根分区 UUID。

blkid # 获取新分区的 UUID
# 编辑 fstab 没有什么特别要注意的地方,对照着 UUID 复制粘贴上去就可以了。

4.2. * 安装引导程序(如 GRUB):

* 本步骤可选, 前提是没有破坏原有 EFI,也就是 使用了 dd 对原有的 EFI 进行完整复制操作.
如果你的原系统可以正常引导,且 EFI 分区和原有 EFI 完全一致,那么可以直接跳过这一步。

https://askubuntu.com/questions/254491/failed-to-get-canonical-path-of-cow

grub-install --recheck --root-directory=/mnt/new_root /dev/sda

4.3. 挂载设备相关分区

mount --bind /dev /mnt/new_root/dev
mount --bind /proc /mnt/new_root/proc
mount --bind /sys /mnt/new_root/sys

4.4. 进入 chroot 环境

# chroot 就是变更根目录, 这样的目的就是相当于直接进入了迁移好的新硬盘
chroot /mnt/new_root

4.5. 更新引导程序

update-grub

5. 完成迁移

  1. 退出 chroot 环境
exit
  1. 重启系统:重启计算机,并从新磁盘启动。

注意事项

  • 备份数据:在开始之前,确保所有重要数据已备份。

  • 小心操作:操作分区和引导程序时要非常小心,以免数据丢失。

  • 检查设备名:在每个步骤中,确保正确使用设备名(如 /dev/sdX)。

这只是一个基本的指南,具体操作可能因系统配置不同而有所变化。确保在操作前理解每个步骤的含义。

Conclusion

  1. 不要在 Alpine 下执行 fdisk, grub-install, Alpine 的软件是有问题的,不通用。
  2. GPT 给出的方案会有部分细节是错误的,或者省略了一大个步骤,那么需要你自己来根据经验来判断哪里有问题。
  3. 做好备份,一定要做好备份。
  4. 参考:https://askubuntu.com/questions/254491/failed-to-get-canonical-path-of-cow
  5. 如果你不是缩容操作,而是迁移到一个更大的硬盘上,完全可以使用 dd 克隆整个盘,然后考虑给ext4分区扩容。该方法仅适用于缩容,因为 dd 无法做到这一点。