2016-09-03 8 views
1

AWS 스팟 인스턴스를 사용하여 신경망을 학습하고 싶습니다. 지점 인스턴스가 종료 될 때 모델이 손실되지 않도록 EBS 볼륨의 스냅 샷을 만들고 새 볼륨을 만들어 예약 된 인스턴스에 연결할 계획입니다. EBS 볼륨을 Python & boto3을 사용하여 마운트하거나 마운트하는 방법은 무엇입니까?python - boto3을 사용하여 EBS 볼륨 탑재

이들은 리눅스에서 make the volume available에 사용되는 단계이지만, 프로세스를 자동화하여 매번 인스턴스로 SSH 할 필요가 없습니다. 볼륨을 연결하는 데 사용하는 코드는 다음과 같습니다. -

import boto3 
ec2 = boto3.resource('ec2') 

spot = ec2.Instance('i-9a8f5082') 
res = ec2.Instance('i-86e65a13') 

snapshot = ec2.create_snapshot(VolumeId="vol-5315f7db", Description="testing spot instances") 
volume = ec2.create_volume(SnapshotId=snapshot.id, AvailabilityZone='us-west-2a') 
res.attach_volume(VolumeId="vol-5315f7db", Device='/dev/sdy') 
snapshot.delete() 

답변

0

인스턴스에서 mount 명령을 실행해야합니다. 그것을위한 2 가지 방법. 하나는 @mootmoot와 같이 ssh 연결을 사용하는 전송 명령입니다. 다른 하나는 @Mark B와 같이 AWS SSM 서비스를 사용하는 전송 명령입니다. 여기에 자세한 SSM 솔루션 샘플, 당신은 당신을 위해 불필요한 부분을 무시할 수 있습니다 :

보내기 bash는 명령을 인스턴스에 AWS SSM을 사용 :

# Amazon EC2 Systems Manager requires 
# 1. An IAM role for EC2 instances that will process commands. There should be a system manager role and the instance should use this role ! (Did it while creation instance) 
# 2. And a separate role for users executing commands. Aws IAM user that has access and secret keys should have ssm permission. (i.e. AmazonSSMFullAccess) 
# http://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-configuring-access-policies.html 
def execute_commands_on_linux_instances(commands, instance_ids): 
    client = boto3.client('ssm', **conn_args) # Need your credentials here 

    all_ssm_enabled_instances, ssm_enabled_instances, not_worked_instances = [],[],[] 
    not_worked_instances = instance_ids.copy() 
    all_ssm_enabled_instances = list() 
    outputs = list({}) 
    not_executed = list() 

    # Select only the Instances that have an active ssm agent. 
    if len(client.describe_instance_information()['InstanceInformationList']) > 0: 
     resp = client.describe_instance_information(MaxResults=20)['InstanceInformationList'] 
     for ins in resp: 
      all_ssm_enabled_instances.append(ins['InstanceId']) 
     ssm_enabled_instances = list(set(all_ssm_enabled_instances).intersection(instance_ids)) 
     not_worked_instances = list(set(instance_ids).difference(all_ssm_enabled_instances)) 


     # Now, send the command ! 
     resp = client.send_command(
     DocumentName="AWS-RunShellScript", 
     Parameters={'commands': [commands]}, 
     InstanceIds=ssm_enabled_instances, 
     ) 

     # get the command id generated by the send_command 
     com_id = resp['Command']['CommandId'] 

     # Wait until all the commands status are out of Pending and InProgress 
     list_comm = client.list_commands(CommandId=com_id) 
     while True: 
      list_comm = client.list_commands(CommandId=com_id) 
      if (list_comm['Commands'][0]['Status'] == 'Pending'or list_comm['Commands'][0]['Status'] == 'InProgress'): 
       continue 
      else: 
       # Commands on all Instances were executed 
       break 

     # Get the responses the instances gave to this command. (stdoutput and stderror) 
     # Althoug the command could arrive to instance, if it couldn't be executed by the instance (response -1) it will ignore. 
     for i in ssm_enabled_instances: 
      resp2 = client.get_command_invocation(CommandId=com_id, InstanceId=i) 
      if resp2['ResponseCode'] == -1: 
       not_executed.append(i) 
      else: 
       outputs.append({'ins_id': i, 'stdout': resp2['StandardOutputContent'], 
          'stderr': resp2['StandardErrorContent']}) 

     # Remove the instance that couldn't execute the command ever, add it to not_worked_instances 
     ssm_enabled_instances = list(set(ssm_enabled_instances).difference(not_executed)) 
     not_worked_instances.extend(not_executed) 

     return ssm_enabled_instances, not_worked_instances, outputs 
    else: 
     print("There is no any available instance that has a worked SSM service!") 
     return ssm_enabled_instances, not_worked_instances, outputs 

이 필요했다 역할을 요구하고있다 요구 IAM 인스턴스 프로파일과 인스턴스 만들기 정책. 이 인스턴스 생성의 결과로, 인스턴스는 SSM 에이전트를 실행 한 :

def create_ec2_instance(node_type): 
    # define userdata to be run at instance launch 

    userdata = """#cloud-config 

    runcmd: 
    - cd /tmp 
    - sudo yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm 
    """ 

    ec2_r = boto3.resource('ec2', **conn_args) 

    rolename = "amazonec2ssmrole" 
    i_pro_name = "ins_pro_for_ssm" 

    # Create an iam instance profile and add required role to this instance profile. 
    # Create a role and attach a policy to it if not exist. 
    # Instances will have this role to build ssm (ec2 systems manager) connection. 
    iam = boto3.resource('iam', **conn_args) 

    try: 
     response= iam.meta.client.get_instance_profile(InstanceProfileName=i_pro_name) 
    except: 
     iam.create_instance_profile(InstanceProfileName=i_pro_name) 
    try: 
     response = iam.meta.client.get_role(RoleName=rolename) 
    except: 
     iam.create_role(
        AssumeRolePolicyDocument='{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":["ec2.amazonaws.com"]},"Action":["sts:AssumeRole"]}]}', 
        RoleName=rolename) 
     role = iam.Role(rolename) 
     role.attach_policy(PolicyArn='arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM') 
     iam.meta.client.add_role_to_instance_profile(InstanceProfileName=i_pro_name, RoleName=rolename) 

    iam_ins_profile = {'Name': i_pro_name} 

    if node_type == "Medium": 
     instance = ec2_r.create_instances(
      ImageId='ami-aa5ebdd2', 
      MinCount=1, 
      MaxCount=1, 
      UserData=userdata, 
      InstanceType='t2.medium', 
      KeyName=key_pair_name, 
      IamInstanceProfile=iam_ins_profile, 
      BlockDeviceMappings=[{"DeviceName": "/dev/xvda", "Ebs": {"VolumeSize": 20}}]) 
    elif node_type == "Micro": 
     instance = ec2_r.create_instances(
      ImageId='ami-aa5ebdd2', 
      MinCount=1, 
      MaxCount=1, 
      UserData=userdata, 
      InstanceType='t2.micro', 
      KeyName=key_pair_name, 
      IamInstanceProfile=iam_ins_profile, 
      BlockDeviceMappings=[{"DeviceName": "/dev/xvda", "Ebs": {"VolumeSize": 10}}]) 
    else: 
     print("Node Type Error") 
     return -1 

    # Wait for the instance state, default --> one wait is 15 seconds, 40 attempts 
    print('Waiting for instance {0} to switch to running state'.format(instance[0].id)) 
    waiter = ec2_r.meta.client.get_waiter('instance_running') 
    waiter.wait(InstanceIds=[instance[0].id]) 
    instance[0].reload() 
    print('Instance is running, public IP: {0}'.format(instance[0].public_ip_address)) 

    return instance[0].id 

는 SSM 권한을주는 것을 잊지 마십시오. (즉, AmazonSSMFullAccess)를 액세스 및 비밀 키를 가진 Aws IAM 사용자에게 전달합니다. 다음

그런데

, conn_args 정의 할 수

conn_args = { 
     'aws_access_key_id': Your_Access_Key, 
     'aws_secret_access_key': Your_Secret_Key, 
     'region_name': 'us-west-2' 
    } 
1

운영 체제에서 이러한 단계를 수행해야합니다. 이러한 단계는 AWS API (Boto3)를 통해 수행 할 수 없습니다. 최선의 방법은 이러한 단계를 스크립팅 한 다음 Boto3을 통해 스크립트를 시작하는 것입니다. AWS SSM 서비스를 사용하는 것이 좋습니다.

1

원격으로 ssh 스크립트를 보내고 실행하면 어떤 문제가 있습니까? 대신 특정 정적 ID와 연결 보편적 인 태그 이름에 의해 자원을 물었다에 당신이 그 자원에 태그를 부착하는 경우 즉

ssh -i your.pem [email protected]_name_or_ip 'sudo bash -s' < mount_script.sh 

, 우분투 사용하는 가정, 나중에 boto3 사용할 수 있습니다.

관련 문제