分页: 1 / 1

在线迁移阿里云ECS实例到本地方法-UEFI云主机

发表于 : 2025年 11月 8日 08:12
admin
为什么要在线迁移阿里云ECS实例到本地?
(1)迁移过程不会停止阿里云ECS实例的业务。
(2)对于某些低配置阿里云ECS实例,需要一个低成本的本地开发和测试环境。
(3)获得数据自主权。

在线迁移方法

阿里云ECS配置情况:

sshd端口:tcp 22222

普通用户:sam

ECS实例相关信息:
# df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/vda3 xfs 40G 7.3G 33G 19% /
devtmpfs devtmpfs 4.0M 0 4.0M 0% /dev
tmpfs tmpfs 479M 0 479M 0% /dev/shm
efivarfs efivarfs 256K 25K 227K 10% /sys/firmware/efi/efivars
tmpfs tmpfs 192M 508K 191M 1% /run
tmpfs tmpfs 479M 0 479M 0% /tmp
/dev/vda2 vfat 200M 6.2M 194M 4% /boot/efi
tmpfs tmpfs 96M 4.0K 96M 1% /run/user/1000

# fdisk -l /dev/vda
Disk /dev/vda: 40 GiB, 42949672960 bytes, 83886080 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 60305B8B-FAB9-4889-BB3B-30DB00E88663

Device Start End Sectors Size Type
/dev/vda1 2048 4095 2048 1M BIOS boot
/dev/vda2 4096 413695 409600 200M EFI System
/dev/vda3 413696 83886046 83472351 39.8G Linux filesystem

#### 备注:这是一台采用UEFI固件引导的虚拟机。

# which dd
/usr/bin/dd

# echo "sam ALL=(root) NOPASSWD: /usr/bin/dd" >> /etc/sudoers

本地宿主机:
# mkdir -p /vm/aliyun_VM_UEFI
# cd /vm/aliyun_VM_UEFI

# ssh -p 22222 sam@aliyun_ECS_IP "sudo /usr/bin/dd if=/dev/vda bs=2M | xz -9 -c" | xz -dc -T0 > local_aliyun_ECS_UEFI.img

完成后,查看虚拟机文件。
# file local_aliyun_ECS_UEFI.img
local_aliyun_ECS_UEFI.img: DOS/MBR boot sector, extended partition table (last)

挂载虚拟机文件local_aliyun_ECS_UEFI.img

# kpartx -av local_aliyun_ECS_UEFI.img
add map loop0p1 (252:0): 0 2048 linear 7:0 2048
add map loop0p2 (252:1): 0 409600 linear 7:0 4096
add map loop0p3 (252:2): 0 83472351 linear 7:0 413696

# ls /dev/mapper/
control loop0p1 loop0p2 loop0p3

查看分区表结构:
# fdisk -l /dev/loop0
Disk /dev/loop0: 40 GiB, 42949672960 bytes, 83886080 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 60305B8B-FAB9-4889-BB3B-30DB00E88663

Device Start End Sectors Size Type
/dev/loop0p1 2048 4095 2048 1M BIOS boot
/dev/loop0p2 4096 413695 409600 200M EFI System
/dev/loop0p3 413696 83886046 83472351 39.8G Linux filesystem

尝试挂载/dev/loop0p3
mount /dev/mapper/loop0p3 /mnt
mount: /mnt: fsconfig system call failed: 结构需要清理.
dmesg(1) may have more information after failed mount system call.

无法直接挂载,dmesg查看报错信息:
# dmesg |grep loop0p3
# dmesg |grep loop0
[26238.931664] loop0: detected capacity change from 0 to 83886080

查看阿里云主机上的分区信息和UUID相关信息:
# df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/vda3 xfs 40G 7.3G 33G 19% /
devtmpfs devtmpfs 4.0M 0 4.0M 0% /dev
tmpfs tmpfs 479M 0 479M 0% /dev/shm
efivarfs efivarfs 256K 25K 227K 10% /sys/firmware/efi/efivars
tmpfs tmpfs 192M 508K 191M 1% /run
tmpfs tmpfs 479M 0 479M 0% /tmp
/dev/vda2 vfat 200M 6.2M 194M 4% /boot/efi
tmpfs tmpfs 96M 4.0K 96M 1% /run/user/1000

# blkid
/dev/vda2: SEC_TYPE="msdos" UUID="ED53-FE18" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="EFI System Partition" PARTUUID="3b88ca58-6477-4db5-95c9-0246c990cddc"
/dev/vda3: LABEL="root" UUID="9b0a5dd2-8e1c-4f27-bbcd-4e349381a982" BLOCK_SIZE="512" TYPE="xfs" PARTLABEL="root" PARTUUID="93ddc05b-315c-4d4b-88c9-8649334e3499"
/dev/vda1: PARTLABEL="biosboot" PARTUUID="0a37002f-bbb1-4f57-ac02-1a050a39d516"

# cat /etc/fstab
#
# /etc/fstab
# Created by anaconda on Sat Oct 11 14:51:04 2025
#
# Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
UUID=9b0a5dd2-8e1c-4f27-bbcd-4e349381a982 / xfs defaults 0 0
UUID=ED53-FE18 /boot/efi vfat defaults,uid=0,gid=0,umask=077,shortname=winnt 0 2
/swapfile swap swap defaults 0 0

查看结果得知:
/dev/vda3 也就是本地/dev/loop0p3 文件系统是xfs
/dev/vda2 也就是本地/dev/loop0p2 文件系统是vfat

先用xfs_repair尝试修复/dev/mapper/loop0p3
# xfs_repair -L /dev/mapper/loop0p3
Phase 1 - find and verify superblock...
Phase 2 - using internal log
- zero log...
ALERT: The filesystem has valuable metadata changes in a log which is being
destroyed because the -L option was used.
- scan filesystem freespace and inode maps...
clearing needsrepair flag and regenerating metadata
record 108 greater than high key of block (2/225335) in rmap tree
sb_ifree 841, counted 827
sb_fdblocks 8717240, counted 8713360
- found root inode chunk
Phase 3 - for each AG...
- scan and clear agi unlinked lists...
- process known inodes and perform inode discovery...
- agno = 0
data fork in ino 695445 claims free block 85873
imap claims in-use inode 695445 is free, correcting imap
data fork in ino 695767 claims free block 91487
data fork in ino 695767 claims free block 91511
imap claims a free inode 696126 is in use, correcting imap and clearing inode
cleared inode 696126
- agno = 1
data fork in ino 17195040 claims free block 2209427
data fork in ino 17195040 claims free block 2209429
- agno = 2
data fork in ino 34028824 claims free block 4252861
imap claims in-use inode 34028824 is free, correcting imap
data fork in ino 34652447 claims free block 4268751
imap claims in-use inode 34652447 is free, correcting imap
- agno = 3
- agno = 4
- agno = 5
- agno = 6
data fork in ino 100663432 claims free block 12597622
- agno = 7
- agno = 8
data fork in ino 134422808 claims free block 34630
- process newly discovered inodes...
Phase 4 - check for duplicate blocks...
- setting up duplicate extent list...
- check for inodes claiming duplicate blocks...
- agno = 0
- agno = 3
- agno = 1
- agno = 2
- agno = 4
- agno = 5
- agno = 6
- agno = 7
- agno = 8
Missing reverse-mapping record for (0/34630) len 1 owner 134422808 off 0
Missing reverse-mapping record for (2/74447) len 1 owner 34652447 off 0
Missing reverse-mapping record for (0/76043) len 1 owner 607856 bmbt off 0
Incorrect reverse-mapping: saw (6/14691) len 19 owner 100663432 off 21; should be (6/14691) len 20 owner 100663432 off 21
Incorrect reverse-mapping: saw (0/91487) len 38 owner 695767 off 567; should be (0/91511) unwritten len 481 owner 695767 off 591
Incorrect reverse-mapping: saw (0/1166653) len 122 owner 607856 off 1126; should be (0/1166654) unwritten len 1 owner 607856 off 1127
Incorrect reverse-mapping: saw (0/1166653) len 122 owner 607856 off 1126; should be (0/1166656) unwritten len 1 owner 607856 off 1129
Incorrect reverse-mapping: saw (0/1166653) len 122 owner 607856 off 1126; should be (0/1166658) unwritten len 1 owner 607856 off 1131
Incorrect reverse-mapping: saw (0/1166653) len 122 owner 607856 off 1126; should be (0/1166728) unwritten len 847 owner 607856 off 1201
clearing reflink flag on inodes when possible
Phase 5 - rebuild AG headers and trees...
- reset superblock...
Phase 6 - check inode connectivity...
- resetting contents of realtime bitmap and summary inodes
- traversing filesystem ...
- traversal finished ...
- moving disconnected inodes to lost+found ...
disconnected inode 34028824, moving to lost+found
disconnected inode 34652447, moving to lost+found
Phase 7 - verify and correct link counts...
Maximum metadata LSN (2:94322) is ahead of log (1:2).
Format log to cycle 5.
done
修复成功。尝试再次挂载。
# mount /dev/mapper/loop0p3 /mnt
# df -hT |grep loop0p3
/dev/mapper/loop0p3 xfs 40G 7.3G 33G 19% /mnt
挂载成功。

再挂载/dev/mapper/loop0p2
# mount /dev/mapper/loop0p2 /mnt/boot/efi
# df -hT |grep loop0p2
/dev/mapper/loop0p2 vfat 200M 6.2M 194M 4% /mnt/boot/efi
也挂载成功。查看/dev/mapper/loop0p3和/dev/mapper/loop0p2 UUID是否与原来阿里云ECS实例上的分区表一致:

# blkid |grep loop0p3
/dev/mapper/loop0p3: LABEL="root" UUID="9b0a5dd2-8e1c-4f27-bbcd-4e349381a982" BLOCK_SIZE="512" TYPE="xfs" PARTLABEL="root" PARTUUID="93ddc05b-315c-4d4b-88c9-8649334e3499"
# blkid |grep loop0p2
/dev/mapper/loop0p2: SEC_TYPE="msdos" UUID="ED53-FE18" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="EFI System Partition" PARTUUID="3b88ca58-6477-4db5-95c9-0246c990cddc"
查看结果与原ECS分区表UUID一致,不需要修改分区表和引导配置文件。

# chroot /mnt
bash: warning: setlocale: LC_ALL: cannot change locale (zh_CN.UTF-8)
/usr/bin/sh: warning: setlocale: LC_ALL: cannot change locale (zh_CN.UTF-8)
/usr/bin/sh: warning: setlocale: LC_ALL: cannot change locale (zh_CN.UTF-8)
/usr/bin/sh: warning: setlocale: LC_ALL: cannot change locale (zh_CN.UTF-8)
cat: /proc/17191/comm: No such file or directory
不用理会,不影响操作。
# ntsysv
关闭如下服务:
aliyun.service
cloud-config.service
cloud-final.service
cloud-init-local.service
cloud-init.service
dm-event.socket
systemd-journald-audit.socket
systemd-resolved.service
保存退出。
# exit
# cd /vm/mail2.bluepoint-ha.com/
# umount /mnt/boot/efi
# umount /mnt

接下来卸载虚拟机文件local_aliyun_ECS_UEFI.img
# kpartx -d local_aliyun_ECS_UEFI.img

# 在本地宿主机器上添加KVM虚拟机
操作系统选:CentOS Stream 10
硬盘路径:/vm/aliyun_VM_UEFI/local_aliyun_ECS_UEFI.img
硬盘总线选:VirtIO
虚拟网络接口
网络源:桥接设备(可以根据实际情况设置)
设备名称:br0
设备型号:virtio
虚拟机其他参数根据实际情况填写。
选择 在安装前自定义配置 点击完成。
在 概况 固件 选择 UEFI x86_64:/usr/share/edk2/ovmf/OVMF_CODE.fd 点击 应用 然后 点击 开始安装
# 备注:固件类型不要选错,否则无法启动迁移下来的虚拟机。

# 启动虚拟机后,如何修改网卡从自动获取IP到设置成静态IP?采用nmcli命令
# nmcli connection show
NAME UUID TYPE DEVICE
Wired connection 1 d891114a-1919-36c4-8f60-40f53c87a982 ethernet eth0
lo 16d312cc-0114-4031-b331-48a67c2c1750 loopback lo
cloud-init eth0 1dd9a779-d327-56e1-8454-c65e2556c12c ethernet --

编写一个删除和创建网卡配置的shell脚本set_eth0.sh
# vim set_eth0.sh
#!/bin/bash
/usr/bin/nmcli connection delete "cloud-init eth0"
/usr/bin/nmcli connection delete "Wired connection 1"
/usr/bin/nmcli connection add type ethernet con-name "eth0" ifname eth0 \
ipv4.method manual \
ipv4.addresses 192.168.1.109/24 \
ipv4.gateway 192.168.1.1 \
ipv4.dns "192.168.1.1,8.8.8.8" \
autoconnect yes
:wq 保存退出。
# chmod 755 set_eth0.sh
# sh set_eth0.sh

如何在本地迁移过来的KVM虚拟机上也可以安装和更新软件包和安全补丁?
(1)在阿里云ECS上配置VPN服务端,并安装squid。squid配置如下:
http_port 10.8.0.1:3128 # 只监听VPN网关IP
acl localnet src # 10.8.0.0/24 只允许VPN网段的主机访问squid
http_access allow localnet
http_access allow localhost
http_access deny all
(2)阿里云ECS防火墙添加如下规则:
firewall-cmd --add-port=3128/tcp --permanent
firewall-cmd --reload
(2)本地KVM虚拟机配置VPN客户端,用以连接阿里云ECS VPN服务端。
(3)配置本地KVM虚拟机配置 dnf 使用代理:
vim /etc/dnf/dnf.conf
# 添加以下内容
proxy=http://10.8.0.1:3128
这样,在线迁移过来的ECS(本地KVM虚拟机)也可以安装和更新软件包和安全补丁了。
备注:由于是使用了ssh加密通道和xz压缩和解压缩方法进行的在线迁移,迁移下来的mail.bluepoint-ha.com_aliyun_ECS.img
文件有少部分数据丢失,需要到阿里云ECS上面scp下载这部分丢失的数据到本地KVM虚拟主机上(注意设置到这些文件的用户和属主)。
如有不懂的地方请发邮件到tot@bluepoint-ha.com咨询。