AWS EC2 竞价实例可用性

4

我正在使用API调用request_spot_instances创建没有指定可用区的spot实例。通常API会随机选择一个可用区。有时,spot请求会返回无法容纳的状态,而我可以通过AWS控制台在另一个可用区成功地请求spot实例。在调用request_spot_instance之前,检查特定实例类型的spot实例的可用性的正确方法是什么?

2个回答

5

没有公开的API可以检查Spot实例的可用性。但是,您仍然可以通过以下步骤实现您的目标:

  1. 使用request_spot_fleet,并将其配置为启动单个实例。
  2. 在使用实例类型时要灵活,尽可能多地选择实例类型并将它们包括在请求中。为了帮助您选择实例,请查看Spot Instance Advisor以获取实例中断和节省率。
  3. 在Spot Fleet请求中,将AllocationStrategy配置为capacityOptimized,这将允许Fleet从您的实例列表中分配容量来获得最可用的Spot实例,并降低Spot中断的可能性。
  4. 不要设置最高价格SpotPrice,将使用默认的Spot实例价格。Spot的定价模型已经改变,不再基于竞标,因此Spot价格更加稳定,不会波动。

1
这可能有点过于复杂,但您可以通过代码的某些部分找到过去一小时的现货价格历史记录(可以更改)。它将为您提供实例类型、AZ和其他信息。从那里,您可以通过实例类型循环遍历AZ。如果在30秒内没有出现现货实例,请尝试下一个AZ。
至于Ahmed在他的答案中提到的,这些信息可以在spot_fleet_request中使用,而不是循环遍历AZs。如果在spot fleet request中传递了错误的AZ或子网,它可能会通过dryrun api调用,但仍然可能失败。只是提醒一下,如果您正在使用dryrun参数。
以下是代码输出:
In [740]: df_spot_instance_options
Out[740]:
    AvailabilityZone   InstanceType  SpotPrice  MemSize  vCPUs  CurrentGeneration Processor
0         us-east-1d        t3.nano      0.002      512      2               True  [x86_64]
1         us-east-1b        t3.nano      0.002      512      2               True  [x86_64]
2         us-east-1a        t3.nano      0.002      512      2               True  [x86_64]
3         us-east-1c        t3.nano      0.002      512      2               True  [x86_64]
4         us-east-1d       t3a.nano      0.002      512      2               True  [x86_64]
..               ...            ...        ...      ...    ...                ...       ...
995       us-east-1a    p2.16xlarge      4.320   749568     64               True  [x86_64]
996       us-east-1b    p2.16xlarge      4.320   749568     64               True  [x86_64]
997       us-east-1c    p2.16xlarge      4.320   749568     64               True  [x86_64]
998       us-east-1d    p2.16xlarge     14.400   749568     64               True  [x86_64]
999       us-east-1c  p3dn.24xlarge      9.540   786432     96               True  [x86_64]

[1000 rows x 7 columns]

这里是代码:

ec2c = boto3.client('ec2')
ec2r = boto3.resource('ec2')

#### The rest of this code maps the instance details to spot price in case you are looking for certain memory or cpu
paginator = ec2c.get_paginator('describe_instance_types')
response_iterator = paginator.paginate( )

df_hold_list = []
for page in response_iterator:
    df_hold_list.append(pd.DataFrame(page['InstanceTypes']))

df_instance_specs = pd.concat(df_hold_list, axis=0).reset_index(drop=True)
df_instance_specs['Spot'] = df_instance_specs['SupportedUsageClasses'].apply(lambda x: 1 if 'spot' in x else 0)
df_instance_spot_specs = df_instance_specs.loc[df_instance_specs['Spot']==1].reset_index(drop=True)

#unapck memory and cpu dictionaries
df_instance_spot_specs['MemSize'] = df_instance_spot_specs['MemoryInfo'].apply(lambda x: x.get('SizeInMiB'))
df_instance_spot_specs['vCPUs'] = df_instance_spot_specs['VCpuInfo'].apply(lambda x: x.get('DefaultVCpus'))
df_instance_spot_specs['Processor'] = df_instance_spot_specs['ProcessorInfo'].apply(lambda x: x.get('SupportedArchitectures'))

#look at instances only between 30MB and 70MB
instance_list = df_instance_spot_specs['InstanceType'].unique().tolist()

#---------------------------------------------------------------------------------------------------------------------
# You can use this section by itself to get the instancce type and availability zone and loop through the instance you want
# just modify instance_list with one instance you want informatin for
#look only in us-east-1
client = boto3.client('ec2', region_name='us-east-1')
prices = client.describe_spot_price_history(
    InstanceTypes=instance_list,
    ProductDescriptions=['Linux/UNIX', 'Linux/UNIX (Amazon VPC)'],
    StartTime=(datetime.now() -
               timedelta(hours=1)).isoformat(),
               # AvailabilityZone='us-east-1a'
    MaxResults=1000)

df_spot_prices = pd.DataFrame(prices['SpotPriceHistory'])
df_spot_prices['SpotPrice'] = df_spot_prices['SpotPrice'].astype('float')
df_spot_prices.sort_values('SpotPrice', inplace=True)
#---------------------------------------------------------------------------------------------------------------------

# merge memory size and cpu information into this dataframe
df_spot_instance_options = df_spot_prices[['AvailabilityZone', 'InstanceType', 'SpotPrice']].merge(df_instance_spot_specs[['InstanceType', 'MemSize', 'vCPUs',
                                            'CurrentGeneration', 'Processor']], left_on='InstanceType', right_on='InstanceType')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接