You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

手动从OS磁盘EBS卷创建AMI的所需修改及增量备份启动异常问题

解决增量备份生成EC2 AMI时的Kernel Panic问题,及自动化方案

首先给你明确答案:是的,你必须手动执行import-image做的那些系统适配修改,否则你的VMware裸盘镜像无法在EC2上正常启动。下面我会一步步拆解问题、给出具体的修改步骤、自动化方案,以及纠正你对Packer的误解。

为什么会出现Kernel panic - not syncing: VFS: Unable to mount root fs?

你已经观察到了关键差异:AWS的import-image工具会对导入的裸盘镜像做EC2专属的系统适配修改,而你的手动快照/卷完全没做这些。这些修改是让VMware的OS能在EC2的虚拟化环境下正常启动的核心:

  • 安装AWS PV/ENA驱动(用于EC2的存储、网络适配)
  • 修改initramfs/initrd,添加EC2启动所需的模块(比如你看到的.vmimport后缀的镜像文件)
  • 调整GRUB启动配置,适配EC2的块设备命名、控制台输出
  • 修正/etc/fstab,用UUID而非固定设备名挂载根文件系统(EC2的块设备名可能动态变化)
  • 禁用VMware相关服务/驱动,避免启动冲突

你的VMware裸盘是针对VMware的硬件层做的配置,直接放到EC2上,内核找不到适配的存储驱动,自然无法挂载根文件系统,触发panic。

你需要手动执行的具体修改步骤(以CentOS 7为例)

你可以把VMware裸盘挂载到一个临时EC2实例(建议用同版本的CentOS 7 AMI启动),然后通过losetup挂载镜像,chroot进去执行以下操作:

1. 安装AWS驱动和工具

# 安装AWS PV驱动、网络工具、CloudFormation bootstrap工具
yum install -y aws-cli ec2-net-utils aws-cfn-bootstrap

# 安装ENA驱动(针对HVM实例,现代EC2实例都用这个)
yum install -y kernel-devel-$(uname -r) gcc git
git clone https://github.com/amzn/amzn-drivers.git
cd amzn-drivers
make -C kernel/ena
make -C kernel/ena install

2. 生成适配EC2的initramfs

# 生成包含VMimport模块的initramfs
dracut -f /boot/initramfs-$(uname -r).img.vmimport $(uname -r)

3. 修改GRUB启动配置

编辑/boot/grub2/grub.cfg(或者修改/etc/default/grub后用grub2-mkconfig -o /boot/grub2/grub.cfg重新生成):

  • 把启动项中的root=/dev/sda1改成根文件系统的UUID(可以用blkid查看)
  • 添加console=ttyS0参数(用于EC2控制台查看启动日志)
  • 指定initramfs路径为刚才生成的.vmimport文件

示例修改后的GRUB条目核心部分:

linux16 /vmlinuz-3.10.0-327.36.3.el7.x86_64 root=UUID=<你的根分区UUID> ro console=ttyS0 crashkernel=auto rhgb quiet
initrd16 /initramfs-3.10.0-327.36.3.el7.x86_64.img.vmimport

4. 修正/etc/fstab

把根文件系统的挂载项从/dev/sda1改成UUID,比如:

UUID=<你的根分区UUID> /                       xfs     defaults        0 0

5. 清理VMware相关组件

# 禁用vmtoolsd服务
systemctl disable vmtoolsd

# 删除VMware相关驱动文件(如果存在)
rm -rf /usr/lib/vmware*

如何通过代码/脚本自动化这些操作?

你可以写一个bash脚本,结合AWS CLI实现全自动化:

  1. 启动一个临时EC2实例(用同OS版本的AMI)
  2. 将VMware裸盘从S3下载到临时实例
  3. 用losetup挂载裸盘镜像,创建挂载点并挂载分区
  4. chroot到挂载的文件系统,执行上述修改脚本
  5. 卸载分区和镜像,创建EBS快照
  6. 基于快照创建AMI(HVM镜像无需指定AKI,PV镜像需要找对应OS的AKI)
  7. 终止临时EC2实例

示例脚本核心片段:

# 挂载裸盘镜像
losetup /dev/loop0 vmware_disk.raw
partprobe /dev/loop0
mount /dev/loop0p1 /mnt/vm_disk

# chroot执行修改
chroot /mnt/vm_disk /bin/bash << EOF
# 这里放上面的修改命令:安装驱动、生成initramfs、修改GRUB、修正fstab等
EOF

# 卸载并清理
umount /mnt/vm_disk
losetup -d /dev/loop0

Packer是否适用?你之前的理解有误!

Packer完全可以满足你的需求,而且是非常优的自动化方案:

  • Packer不需要依赖source_ami,它支持直接从raw镜像导入并做provisioning。你可以用amazon-import builder,或者先把raw镜像上传到S3,用Packer的chroot provisioner修改镜像,再导入生成AMI。
  • 对于增量备份,Packer的amazon-ebs builder支持previous_snapshot_id参数,可以基于之前的增量快照构建新的快照,再生成AMI,大大减少耗时。
  • Packer可以把所有系统适配修改写到provisioner里(比如shell脚本),完全自动化整个流程,不需要手动操作。

举个简单的Packer配置思路:

source "amazon-ebs" "centos7" {
  region              = "us-east-1"
  instance_type       = "t2.micro"
  source_ami_filter {
    filters = {
      name                = "CentOS Linux 7 x86_64 HVM EBS*"
      root-device-type    = "ebs"
    }
    owners      = ["125523088429"] # CentOS官方账号ID
    most_recent = true
  }
  ssh_username        = "centos"
  previous_snapshot_id = "${var.previous_snapshot_id}" # 增量备份用的之前的快照ID
}

build {
  sources = ["source.amazon-ebs.centos7"]

  provisioner "shell" {
    inline = [
      "yum install -y aws-cli ec2-net-utils",
      "dracut -f /boot/initramfs-$(uname -r).img.vmimport $(uname -r)",
      # 其他修改步骤...
    ]
  }

  post-processor "amazon-ami" {
    ami_name = "centos7-incremental-{{timestamp}}"
  }
}

更优方案:用AWS原生的增量导入功能

如果你不想自己处理系统适配,AWS的VM Import/Export服务其实支持增量导入VMware镜像:

  1. 首次全量导入VMware VM到AWS生成AMI
  2. 后续增量备份VMware的变更数据,用AWS的增量导入工具(结合VMware的快照)直接生成新的AMI,AWS会自动处理系统适配和增量同步
  3. 你可以用AWS CLI的import-image命令,指定--disk-containers中的SnapshotId为之前的快照,实现增量导入

这个方案完全不需要自己做系统修改,所有适配工作由AWS完成,而且增量效率很高。


内容的提问来源于stack exchange,提问作者Subbu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:09:00