使用Python从qcow2镜像文件创建自定义EC2 AMI
我正在写一个服务,需要根据一个qcow2格式的镜像文件,在每个EC2区域注册自定义的AMI。
我一直在研究apache-libcloud
和boto
这两个库,但发现它们的AMI注册功能主要是用来根据正在运行的实例来创建AMI,而我想要的是基于我的qcow2镜像文件来创建AMI。
如果这个问题没有简单的解决办法,我也愿意尝试复杂的方案。如果出于某种原因,qcow2镜像文件无法使用,我也可以使用RAW格式的镜像文件。
1 个回答
我已经成功地通过编程实现了这个过程。我的解决方案使用的是原始图像文件,因为这些文件可以直接写入磁盘。如果你需要将qcow2格式的图像文件转换成原始格式,可以手动使用qemu-img
,或者查看一个简单的Python实现来进行转换。
以下是我基于原始图像文件进行AMI注册的步骤大纲:
选择一个AMI和相应的AKI作为“工具实例”。它不需要和你要注册的图像使用相同的操作系统。如果AMI在
/etc/sudoers
中启用了requiretty
,你需要确保在尝试通过SSH连接节点时请求一个伪终端,比如使用Paramiko的Channel.get_pty()
方法。根据选择的AMI和AKI启动一个工具实例。它必须是EBS优化的(
m1.large
大小的实例与EBS配合得很好),并且应该附加一个足够大的二级EBS卷,以容纳你想要注册的整个未压缩图像。我使用/dev/sdb
作为这个设备的名称。一旦工具实例可以通过SSH访问,让它将原始图像文件写入二级卷。个人来说,我会从网上下载一个
.raw.xz
文件,这就是我想写入的图像,所以我的命令是sudo sh -c 'curl RAW_XZ_URL | xzcat > /dev/xvdb'
。需要注意的是,根据我的经验,/dev/sdX
设备在实际实例上是以/dev/xvdX
的形式访问的,但这可能并不适用于所有情况。一旦工具命令完成,你可以销毁工具节点,前提是你已经设置了
/dev/sdb
卷在节点终止时不被删除。如果没有设置,那就停止节点。如果是通过编程执行工具命令,你可以使用Paramiko的Channel.recv_exit_status()
方法来等待命令完成,然后检查返回的0
状态,表示成功。一旦工具实例不再运行,记得对
/dev/sdb
卷进行快照。快照完成后,你可以将其注册为AMI。确保使用你一直在用的相同AKI,以及正确的根设备名称(我使用完整的磁盘映像,所以我的根设备名称是
/dev/sda
而不是/dev/sda1
)。亚马逊建议你现在使用hd0 pv-grub AKI,而不是hd00。
实现这个过程的一种方法是通过apache-libcloud
和paramiko
这两个Python库,它们都可以通过pip
安装。一个很好的例子是Fedimg库,它实现了这个确切的方法,以便在所有EC2区域自动注册新的AMI,随着Fedora云镜像构建的完成。
在实际实施这个过程时,有很多时机、异常处理和其他“陷阱”需要注意。这只是一个大致的步骤概述,帮助你通过我的方法解决这个挑战。