如何在模板中指定没有偏好的子网,如 Web 界面?

How to specify subnet with no preference like web interface in a template?

使用控制台创建竞价型实例时,不强制选择子网。我可以...

Subnet: No preference (default subnet in any Availability Zone)

但是在使用 cloudformation 模板创建 spot 实例时,我需要选择一个子网,但我不确定选择哪个子网以获得最优惠的价格。 这是否意味着使用 Web 界面比 cloudformation 模板(对于 spot 实例)更好?

Spot 实例定价由 long term trends of supply and demand for EC2 instances 决定,而不是您选择将 Spot 实例启动到哪个子网。

为您的每个 AWS 解决方案开发一个 cloudformation 模板总是有益的。这与 "Infrastructure as Code" 的口头禅一致,它具有许多积极的好处,例如重用、通过修订控制跟踪更改的能力、牛而不是宠物等。

关于默认子网:对于您的账户,每个区域都有一个默认 VPC,其中包含每个可用区的默认子网。这是 AWS 提供的一项便利功能,因此您可以快速启动实例。这些默认子网是 public subnets,如果您在其中启动实例,这些实例将获得 public ips 并暴露在互联网上。为了更好的安全性,开发一个私有子网并将实例启动到私有子网中并通过堡垒主机访问它们。

要求及相应的分配策略

我将您的要求 "best price" 解释为获取为成本优化配置的 SpotFleet [1]。 AWS 在文档 [2]:

中描述了如何创建成本优化的现货车队

To optimize the costs for your use of Spot Instances, specify the lowestPrice allocation strategy so that Spot Fleet automatically deploys the cheapest combination of instance types and Availability Zones based on the current Spot price.

您已经在上述评论中提供的 CloudFormation 模板中为此案例指定了正确的 AllocationStrategy lowestPrice。 AWS 将此分配策略描述为:

The Spot Instances come from the pool with the lowest price. This is the default strategy.

什么是 Spot 实例池?

A Spot Instance pool is a set of unused EC2 instances with the same instance type (for example, m5.large), operating system, Availability Zone, and network platform [i.e. EC2-Classic or EC2-VPC, see [3]].

The Spot Fleet selects the Spot Instance pools that are used to fulfill the request, based on the launch specifications included in your Spot Fleet request, and the configuration of the Spot Fleet request [which is lowestPrice in our case]. [2]

这回答了你问题的一部分:

不,子网不直接决定现货价格。可用区决定价格,即同一实例类型、操作系统和网络平台的实例如果位于同一可用区,则它们始终具有相同的现货价格。由于子网不能跨越多个可用区,因此特定子网中实例的现货价格始终相同 - 即(可用区、实例类型、OS、网络平台)组合的价格。

自动子网和可用区选择

您在问题中声明必须选择一个子网。那不是真的。您的 LaunchSpecification [4] 的 NetworkInterfaces 属性是可选的。 如果省略它,CloudFormation 的行为与 AWS 管理控制台完全相同。 您可以在文档 [5]:

Spot Fleet Examples 部分中阅读相关内容

Example 1: Launch Spot Instances Using the Lowest-Priced Availability Zone or Subnet in the Region

The following example specifies a single launch specification without an Availability Zone or subnet. The Spot Fleet launches the instances in the lowest-priced Availability Zone that has a default subnet. The price you pay does not exceed the On-Demand price.

{
  "TargetCapacity": 20,
  "IamFleetRole": "arn:aws:iam::123456789012:role/aws-ec2-spot-fleet-tagging-role",
  "LaunchSpecifications": [
      {
          "ImageId": "ami-1a2b3c4d",
          "KeyName": "my-key-pair",
          "SecurityGroups": [
              {
                  "GroupId": "sg-1a2b3c4d"
              }
          ],
          "InstanceType": "m3.medium",
          "IamInstanceProfile": {
              "Arn": "arn:aws:iam::123456789012:instance-profile/my-iam-role"
          }
      }
  ]
}

如果您确实需要为您的实例分配一个 NetworkInterface(例如,因为您需要一个 public IP 地址),[5]:

中也列出了一个解决方案
      {
          "ImageId": "ami-1a2b3c4d",
          "KeyName": "my-key-pair",
          "InstanceType": "m3.medium",
          "NetworkInterfaces": [
              {
                  "DeviceIndex": 0,
                  "SubnetId": "subnet-1a2b3c4d",
                  "Groups": [ "sg-1a2b3c4d" ],
                  "AssociatePublicIpAddress": true
              }
          ],
          "IamInstanceProfile": {
              "Arn": "arn:aws:iam::880185128111:instance-profile/my-iam-role"
          }
      }

据我所知,这正是您在 CloudFormation 模板中实现的。 AWS 声明这种方法:

The Spot service launches the instances in whichever subnet is in the lowest-priced Availability Zone.

You can't specify different subnets from the same Availability Zone in a Spot Fleet request.

这意味着,您应该为要在其中分布实例的每个可用区创建一个启动规范。每个启动规范都应因 SubnetId 而异:

[...]
  LaunchSpecifications: [
      {
          [...]
          "NetworkInterfaces": [
              {
                  "DeviceIndex": 0,
                  "SubnetId": "subnet-1a2b3c4d",  // choose a subnet from AZ a
                  "Groups": [ "sg-1a2b3c4d" ],
                  "AssociatePublicIpAddress": true
              }
          ],
          [...]
      },
      {
          [...]
          "NetworkInterfaces": [
              {
                  "DeviceIndex": 0,
                  "SubnetId": "subnet-xxxxxxxx",  // choose a subnet from AZ b
                  "Groups": [ "sg-1a2b3c4d" ],
                  "AssociatePublicIpAddress": true
              }
          ],
          [...]
      },
      [... etc. for each AZ]
  ],
[...]

参考资料

[1] https://docs.aws.amazon.com/de_de/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-spotfleet.html
[2] https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-fleet.html#spot-fleet-allocation-strategy
[3] https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-classic-platform.html
[4] https://docs.aws.amazon.com/de_de/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-networkinterfaces
[5] https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-fleet-examples.html#fleet-config1