使用Python从qcow2镜像文件创建自定义EC2 AMI

3 投票
1 回答
6133 浏览
提问于 2025-04-18 08:26

我正在写一个服务,需要根据一个qcow2格式的镜像文件,在每个EC2区域注册自定义的AMI。

我一直在研究apache-libcloudboto这两个库,但发现它们的AMI注册功能主要是用来根据正在运行的实例来创建AMI,而我想要的是基于我的qcow2镜像文件来创建AMI。

如果这个问题没有简单的解决办法,我也愿意尝试复杂的方案。如果出于某种原因,qcow2镜像文件无法使用,我也可以使用RAW格式的镜像文件。

1 个回答

3

我已经成功地通过编程实现了这个过程。我的解决方案使用的是原始图像文件,因为这些文件可以直接写入磁盘。如果你需要将qcow2格式的图像文件转换成原始格式,可以手动使用qemu-img,或者查看一个简单的Python实现来进行转换。

以下是我基于原始图像文件进行AMI注册的步骤大纲:

  1. 选择一个AMI和相应的AKI作为“工具实例”。它不需要和你要注册的图像使用相同的操作系统。如果AMI在/etc/sudoers中启用了requiretty,你需要确保在尝试通过SSH连接节点时请求一个伪终端,比如使用Paramiko的Channel.get_pty()方法。

  2. 根据选择的AMI和AKI启动一个工具实例。它必须是EBS优化的(m1.large大小的实例与EBS配合得很好),并且应该附加一个足够大的二级EBS卷,以容纳你想要注册的整个未压缩图像。我使用/dev/sdb作为这个设备的名称。

  3. 一旦工具实例可以通过SSH访问,让它将原始图像文件写入二级卷。个人来说,我会从网上下载一个.raw.xz文件,这就是我想写入的图像,所以我的命令是sudo sh -c 'curl RAW_XZ_URL | xzcat > /dev/xvdb'。需要注意的是,根据我的经验,/dev/sdX设备在实际实例上是以/dev/xvdX的形式访问的,但这可能并不适用于所有情况。

  4. 一旦工具命令完成,你可以销毁工具节点,前提是你已经设置了/dev/sdb卷在节点终止时不被删除。如果没有设置,那就停止节点。如果是通过编程执行工具命令,你可以使用Paramiko的Channel.recv_exit_status()方法来等待命令完成,然后检查返回的0状态,表示成功。

  5. 一旦工具实例不再运行,记得对/dev/sdb卷进行快照。

  6. 快照完成后,你可以将其注册为AMI。确保使用你一直在用的相同AKI,以及正确的根设备名称(我使用完整的磁盘映像,所以我的根设备名称是/dev/sda而不是/dev/sda1)。亚马逊建议你现在使用hd0 pv-grub AKI,而不是hd00。

实现这个过程的一种方法是通过apache-libcloudparamiko这两个Python库,它们都可以通过pip安装。一个很好的例子是Fedimg库,它实现了这个确切的方法,以便在所有EC2区域自动注册新的AMI,随着Fedora云镜像构建的完成。

在实际实施这个过程时,有很多时机、异常处理和其他“陷阱”需要注意。这只是一个大致的步骤概述,帮助你通过我的方法解决这个挑战。

撰写回答