启动附加了指定 EBS 卷的新 EC2 实例

启动附加了指定 EBS 卷的新 EC2 实例

我想使用 python boto 库启动一个 EC2 实例,并附加一个之前创建的 EBS 卷(除了根卷)。

连接后,我通过其名称标签查找卷,并尝试创建包含该卷的块设备列表。我遇到了各种错误,但最终创建了以下代码,至少成功启动了一个实例。

volumes=conn.get_all_volumes(filters={'tag:Name':'TestVolume'})
vol=volumes[0]
print repr(vol)

disks=ec2.blockdevicemapping.BlockDeviceMapping()
xvdf=ec2.blockdevicemapping.BlockDeviceType(volume_id=vol.id,
    size=vol.size,volume_type=vol.type)
disks['/dev/xvdf']=xvdf

base_image="ami-9a562df2" #ubuntu 14.04
reservation=conn.run_instances(
    base_image,
    instance_type="t2.micro",
    block_device_map=disks)

打印语句显示它能够查找卷并报告正确的卷 ID。但是,当实例启动时,会创建一个新的未格式化的 32GB 卷并将其附加到该卷。

我找不到能清楚说明这一点的文档。将特定 EBS 卷添加到 block_device_map 的正确方法是什么?

答案1

无法启动带有现有 EBS 卷的新 EC2 实例。

相反,在新的 EC2 实例启动后附加现有的 EBS 卷。您有两个选择:

  1. 在实例的初始启动过程中附加现有 EBS 卷。使用 cloud init,您可以运行附加卷的初始脚本。

http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html

  1. 启动新的 EC2 实例后,等待其启动完成,然后从 Python 脚本中附加现有的 EBS 卷。

编辑:根据评论添加了更多详细信息。

所有各种语言的 SDK 都调用基本 AWS API。请查看基本 AWS API 文档RunInstances

http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RunInstances.html

在该命令上,有一个BlockDeviceMapping参数,如果您遵循它的数据结构,则不包括卷 ID 属性。

我不熟悉 Python SDK,但 SDK 可能会重载类BlockDeviceMapping来表示启动规范(不允许卷 ID)和正在运行的实例的映射(可以包含卷 ID)。

我通常使用适用于 .NET 的 AWS SDK,很少参考该 SDK 的特定文档。我通常参考基本 API 文档(如我上面提到的),然后“找到”在 .NET SDK 中使用的适当方法。但如果存在差异,我会将基本 API 文档视为正确的。

答案2

与 Matt 所说的不同,完全可以在创建 AMI 期间将现有的 EBS 卷附加到 AMI 上。

首先,您应该拥有卷的快照,这可以通过控制台和 aws-cli 完成。

然后根据此 EBS 快照创建 AMI:

#!/bin/bash

aws --region=sa-east-1 ec2 \
register-image \
--name "image" \
--description "new_image" \
--architecture x86_64 \
--kernel-id aki-912fbcfd \
--root-device-name "/dev/xvda" \
--block-device-mappings "[
{
 \"DeviceName\": \"/dev/xvda\",
 \"Ebs\": {
 \"SnapshotId\": \"snap-0dfgkhdfjkhg77\",
 \"DeleteOnTermination\": false
  }
}
]"

然后根据上面的AMI启动实例,这里我省略了创建spot-instance的例子,创建On-Demand实例更简单:

#!/bin/bash
AWS_DEFAULT_OUTPUT="text"
ami="ami-xxxxxxx"
price="0.0022"
region="sa-east-1"
sgroup="sg-54654765"
zone="sa-east-1b"
key="key"

aws ec2 request-spot-instances  \
    --region $region \
    --spot-price $price  \
    --type "persistent" \
    --instance-interruption-behavior "stop" \
    --launch-specification \
    "{ \"KeyName\": \"$key\", 
       \"ImageId\": \"$ami\" , 
       \"InstanceType\": \"t1.micro\"
     }"

所有这些都可以轻松编写脚本和编程。

相关内容