一天内不能使用 boto3 发出多个 spot 请求

cannot make more than one spot request using boto3 in one day

您好, 只要它是当天的第一个现场请求,我的代码就可以工作。如果我终止实例并发出另一个 spot 请求,它只会返回我的旧请求。

我的代码或 AWS 有问题吗???有解决办法吗??

我尝试克隆我的 AMI,然后使用克隆 AMI 更改价格或更改规范中的实例数 但它仍然无法正常工作???

!/home/makayo/.virtualenvs/boto3/bin/python

"""

http://boto3.readthedocs.io/en/latest/reference/services/ec2.html#EC2.Client.describe_spot_instance_requests

"""

import boto3
import time

myid=

s = boto3.Session()
ec2 = s.resource('ec2')
client = boto3.client('ec2')
images = list(ec2.images.filter(Owners=[myid]))

def getdate(datestr):
    ix=datestr.replace('T',' ')
    ix=ix[0:len(ix)-5]
    idx=time.strptime(ix,'%Y-%m-%d %H:%M:%S')
    return(idx)
zz=sorted(images, key=lambda images: getdate(images.creation_date))

#last_ami
myAmi=zz[len(zz)-1]
#earliest
#myAmi=latestAmi=zz[0]

"""
[{u'DeviceName': '/dev/sda1',  u'Ebs': {u'DeleteOnTermination': True,   u'Encrypted': False,   u'SnapshotId': 'snap-d8de3adb',   u'VolumeSize': 50,   u'VolumeType': 'gp2'}}]
"""



#myimageId='ami-42870a55'
myimageId=myAmi.id
print myimageId
mysubnetId=    myinstanceType='c4.4xlarge'
mykeyName='spot-coursera'
#make sure ajust this but dont do multiple in a loop as it can fail!!!
mycount=2
#make sure ajust this but dont do multiple in a loop as it can fail!!!
myprice='5.0'
mytype='one-time'
myipAddr=
myallocId=''
mysecurityGroups=['']
#mydisksize=70
mygroupId=
#mygroupId=
myzone='us-east-1a'
myvpcId='vpc-503dba37'
#latestAmi.block_device_mappings[0]['Ebs']['VolumeSize']=mydisksize
#diskSpec=latestAmi.block_device_mappings[0]['Ebs']['VolumeSize']
response2 = client.request_spot_instances(
            DryRun=False,
                SpotPrice=myprice,
                    ClientToken='string',
                        InstanceCount=1,
                            Type='one-time',
                                LaunchSpecification={
                                        'ImageId': myimageId,
                                                'KeyName': mykeyName,
                                                'SubnetId':mysubnetId,
                                                        #'SecurityGroups': mysecurityGroups,
                                                                'InstanceType': myinstanceType,
                                                                        'Placement': {
                                                                                        'AvailabilityZone': myzone,
                                                                                                }

                                                     }
                                         )

#print(response2)
myrequestId=response2['SpotInstanceRequests'][0]['SpotInstanceRequestId']

import time
XX=True
while XX:
    response3 = client.describe_spot_instance_requests(
        #DryRun=True,
        SpotInstanceRequestIds=[
        myrequestId,
    ]
    #Filters=[
     #   {
      #      'Name': 'string',
       #     'Values': [
        #        'string',
         #   ]
        #},
    #]
    )
    #print(response3)
    request_status=response3['SpotInstanceRequests'][0]['Status']['Code']
    if(request_status=='fullfilled'):
        print myrequestId,request_status
        XX=False;
    elif ('pending' in request_status):
        print myrequestId,request_status
        time.sleep(5)
    else:
        XX=False
        print myrequestId,request_status


"""
instances = ec2.instances.filter(Filters=[{'Name': 'instance-state-name', 'Values': ['running']}])
while( len(list(instances))==0):
    instances = ec2.instances.filter(Filters=[{'Name': 'instance-state-name', 'Values': ['running']}])

instances = ec2.instances.filter(Filters=[{'Name': 'instance-state-name', 'Values': ['running']}])
for instance in instances:
    print(instance.id, instance.instance_type);
    response = instance.modify_attribute(Groups=[mygroupId]);
    print(response);

这是错误的:

ClientToken='string',

或者,至少,大多数时候它是错误的,正如你现在应该意识到的那样。

令牌的目的是确保 EC2 不会由于重试、错误或许多其他原因而处理同一个请求两次。

在这里发送什么并不重要(在合理范围内 -- 最多 64 个字符,ASCII,区分大小写),但是您需要针对每个独特的请求发送不同的内容。

A client token is a unique, case-sensitive string of up to 64 ASCII characters. It is included in the response when you describe the instance. A client token is valid for at least 24 hours after the termination of the instance. You should not reuse a client token in another call later on.

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