将 EBS 附加到 Spot 队列中的 EC2 实例

Attaching an EBS to an EC2 instance from a Spot Fleet

我希望在 Cloudformation 中创建一个 Spot Fleet,它一次运行一个游戏服务器;如果价格飙升并且服务器需要终止,它将使用 2 分钟提醒来正常关闭并将任何内容存储在 EBS 卷上。舰队启动的下一个实例将装载该卷并从上一个实例停止的地方重新启动游戏服务器。

  SpotFleet:
    Type: "AWS::EC2::SpotFleet"
    Properties:
      SpotFleetRequestConfigData:
        IamFleetRole: !Sub arn:aws:iam::${AWS::AccountId}:role/aws-ec2-spot-fleet-tagging-role
        TargetCapacity: 1
        LaunchSpecifications:
          - InstanceType: "m5.large"
            ImageId: "ami-abcd1234"
            IamInstanceProfile: !GetAtt InstanceProfile.Arn
            WeightedCapacity: 1

现在我坚持在 cf 模板中定义持久卷。最初我只是将它添加为资源:

  Volume:
    Type: "AWS::EC2::Volume"
    Properties:
      Size: 10
      AvailabilityZone: !Ref AWS::Region

但是我如何在队列中引用它?您可以根据队列中的 LaunchSpecifications 定义 BlockDeviceMappings http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-blockdevicemappings.html 但是从可用的属性来看,我似乎无法引用现有的卷,因此我认为这些卷没有持久化。

或者我想通过 VolumeAttachment 将卷附加到 spot 实例:

  VolumeAttachment:
    Type: "AWS::EC2::VolumeAttachment"
    Properties:
      Device: "dev/server"
      InstanceId: !Ref SpotFleet
      VolumeId: !Ref Volume

但显然 SpotFleet 在这里引用 returns 舰队名称,而不是任何已创建实例的 ID。 !Ref 和 !GetAtt 似乎都无法从舰队中提取这些 ID。

关于如何在 CloudFormation 中完成上述任务,我是否忽略了任何重要的事情,或者我是否应该考虑将 EC2:AttachVolume 和 EC2:DetachVolume 权限添加到 InstanceProfile 并简单地从内部手动附加卷EC2 实例?

非常感谢,

您要查找的是BlockDeviceMappings property, found in the SpotFleet SpotFleetRequestConfigData LaunchSpecifications, which is a property of SpotFleetRequestConfigData, which is a property of the AWS::EC2::SpotFleet resource type

BlockDeviceMappings 属性 将允许您定义附加 EBS 卷以附加到您的启动规范。这是在启动时控制设备映射的规范。

例如:

"BlockDeviceMappings" : [{
  "DeviceName" : "/dev/sdf",
  "Ebs" : {"VolumeSize": "10", "VolumeType" : "gp2", "DeleteOnTermination" : "true"}
}],

将在您的 Spot 队列实例的 /dev/sdf 设备上指定一个 10GB 的卷。

EC2 Spot 实例现在支持将 "Interruption behavior" 设置为 stop 而不是 terminate 的选项。

选择此选项后,Spot 实例将保留其实例 ID、EBS 卷、其私有和弹性 IP 地址以及其 EBS 卷,这些都保留在原位并已附加。

一些实例类型还支持 "hybernate" 选项,该选项将整个系统状态的快照写入 EBS,以允许实例 "resume" 而不是在容量再次可用时重新启动。

http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-interruptions.html