자습서: 고급 Amazon EC2 스팟 요청 관리 - AWS SDK for Java 1.x

곧 출시될 end-of-support AWS SDK for Java (v1) 버전을 발표했습니다. AWS SDK for Java V2로 마이그레이션하실 것을 권장합니다. 마이그레이션 날짜, 추가 세부 정보 및 방법에 대한 자세한 내용은 링크된 공지 사항을 참조하세요.

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

자습서: 고급 Amazon EC2 스팟 요청 관리

Amazon EC2 스팟 인스턴스를 통해 미사용 Amazon EC2 용량에 입찰하고 입찰가가 현재 스팟 가격을 초과하는 경우 해당 인스턴스를 실행할 수 있습니다. Amazon EC2는 공급 및 수요에 기초하여 스팟 가격을 정기적으로 변경합니다. 스팟 인스턴스에 대한 자세한 내용은 Linux 인스턴스용 Amazon EC2 사용 설명서의 Spot Instances를 참조하세요.

필수 조건

이 자습서를 사용하려면 AWS SDK for Java가 설치되어 있고 기본 설치 사전 요구 사항이 충족되어야 합니다. 자세한 내용은 AWS SDK for Java 설정을 참조하세요.

자격 증명 설정

이 코드 샘플 사용을 시작하려면 AWS 자격 증명을 설정해야 합니다. 작업 방법에 대한 지침은 개발을 위한 AWS 자격 증명 및 리전 설정을 참조하세요.

참고

IAM 사용자 자격 증명을 사용하여 이러한 값을 제공하는 것이 좋습니다. 자세한 내용은 AWS에 가입 및 IAM 사용자 생성을 참조하세요.

이제 설정을 구성했으니 예제의 코드를 사용할 수 있습니다.

보안 그룹 설정

보안 그룹은 인스턴스 그룹과 송수신이 허용되는 트래픽을 제어하는 방화벽 역할을 합니다. 기본적으로 인스턴스는 보안 그룹 없이 시작되므로 TCP 포트로 들어오는 모든 IP 트래픽이 거부됩니다. 따라서 스팟 요청을 제출하기 전에 필요한 네트워크 트래픽을 허용하는 보안 그룹을 설정하겠습니다. 이 자습서의 목적상, 애플리케이션을 실행 중인 IP 주소에서 Secure Shell(SSH) 트래픽을 허용하는 "GettingStarted"라는 새 보안 그룹을 생성하겠습니다. 새 보안 그룹을 설정하려면 보안 그룹을 프로그래밍 방식으로 설정하는 다음 코드 샘플을 포함하거나 실행해야 합니다.

AmazonEC2 클라이언트 객체를 생성한 후에는 "GettingStarted" 이름과 이 보안 그룹에 대한 설명을 사용하여 CreateSecurityGroupRequest 객체를 생성합니다. 그 다음에는 ec2.createSecurityGroup API를 호출하여 그룹을 생성합니다.

그룹에 대한 액세스를 활성화하기 위해 IP 주소 범위가 로컬 컴퓨터의 CIDR 표현으로 설정된 ipPermission 객체를 생성합니다. IP 주소의 "/10" 접미사는 지정된 IP 주소용 서브넷을 나타냅니다. 또한 TCP 프로토콜과 포트 22(SSH)를 사용하여 ipPermission 객체를 구성합니다. 마지막 단계는 보안 그룹의 이름과 ec2 .authorizeSecurityGroupIngress 객체를 사용하여 ipPermission를 호출하는 것입니다.

(다음 코드는 첫 번째 자습서에 사용된 것과 동일한 코드입니다.)

// Create the AmazonEC2Client object so we can call various APIs. AmazonEC2 ec2 = AmazonEC2ClientBuilder.standard() .withCredentials(credentials) .build(); // Create a new security group. try { CreateSecurityGroupRequest securityGroupRequest = new CreateSecurityGroupRequest("GettingStartedGroup", "Getting Started Security Group"); ec2.createSecurityGroup(securityGroupRequest); } catch (AmazonServiceException ase) { // Likely this means that the group is already created, so ignore. System.out.println(ase.getMessage()); } String ipAddr = "0.0.0.0/0"; // Get the IP of the current host, so that we can limit the Security Group // by default to the ip range associated with your subnet. try { // Get IP Address InetAddress addr = InetAddress.getLocalHost(); ipAddr = addr.getHostAddress()+"/10"; } catch (UnknownHostException e) { // Fail here... } // Create a range that you would like to populate. ArrayList<String> ipRanges = new ArrayList<String>(); ipRanges.add(ipAddr); // Open up port 22 for TCP traffic to the associated IP from // above (e.g. ssh traffic). ArrayList<IpPermission> ipPermissions = new ArrayList<IpPermission> (); IpPermission ipPermission = new IpPermission(); ipPermission.setIpProtocol("tcp"); ipPermission.setFromPort(new Integer(22)); ipPermission.setToPort(new Integer(22)); ipPermission.setIpRanges(ipRanges); ipPermissions.add(ipPermission); try { // Authorize the ports to the used. AuthorizeSecurityGroupIngressRequest ingressRequest = new AuthorizeSecurityGroupIngressRequest( "GettingStartedGroup",ipPermissions); ec2.authorizeSecurityGroupIngress(ingressRequest); } catch (AmazonServiceException ase) { // Ignore because this likely means the zone has already // been authorized. System.out.println(ase.getMessage()); }

advanced.CreateSecurityGroupApp.java 코드 샘플에서 이 코드 샘플의 전체 내용을 볼 수 있습니다. 이 애플리케이션을 한 번만 실행하면 새 보안 그룹이 생성됩니다.

참고

또한 AWS Toolkit for Eclipse를 사용하여 보안 그룹을 생성할 수도 있습니다. 자세한 내용은 AWS Toolkit for Eclipse 사용 설명서의 AWS Cost Explorer에서 보안 그룹 관리를 참조하세요.

세부 스팟 인스턴스 요청 생성 옵션

자습서: Amazon EC2 스팟 인스턴스에서 설명한 대로 인스턴스 유형, Amazon 머신 이미지(AMI) 및 최대 입찰 가격을 사용하여 요청을 작성해야 합니다.

RequestSpotInstanceRequest 객체 생성부터 시작하겠습니다. 요청 객체에는 원하는 인스턴스 수와 입찰 가격이 필요합니다. 뿐만 아니라, 요청에 대한 LaunchSpecification을 설정해야 하며, 여기에는 사용할 인스턴스 유형, AMI ID 및 보안 그룹이 포함됩니다. 요청을 작성한 후에는 requestSpotInstances 객체에 대해 AmazonEC2Client 메서드를 호출합니다. 다음 예는 스팟 인스턴스를 요청하는 방법을 보여줍니다.

(다음 코드는 첫 번째 자습서에 사용된 것과 동일한 코드입니다.)

// Create the AmazonEC2 client so we can call various APIs. AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient(); // Initializes a Spot Instance Request RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest(); // Request 1 x t1.micro instance with a bid price of $0.03. requestRequest.setSpotPrice("0.03"); requestRequest.setInstanceCount(Integer.valueOf(1)); // Set up the specifications of the launch. This includes the // instance type (e.g. t1.micro) and the latest Amazon Linux // AMI id available. Note, you should always use the latest // Amazon Linux AMI id or another of your choosing. LaunchSpecification launchSpecification = new LaunchSpecification(); launchSpecification.setImageId("ami-a9d09ed1"); launchSpecification.setInstanceType(InstanceType.T1Micro); // Add the security group to the request. ArrayList<String> securityGroups = new ArrayList<String>(); securityGroups.add("GettingStartedGroup"); launchSpecification.setSecurityGroups(securityGroups); // Add the launch specification. requestRequest.setLaunchSpecification(launchSpecification); // Call the RequestSpotInstance API. RequestSpotInstancesResult requestResult = ec2.requestSpotInstances(requestRequest);

영구 요청 vs. 일회성 요청

스팟 요청을 작성할 때 여러 선택적 매개 변수를 지정할 수 있습니다. 첫 번째는 일회성 요청인지 영구 요청인지 여부를 지정합니다. 기본적으로 요청은 일회성 요청입니다. 일회성 요청은 한 번만 이행될 수 있으며, 요청한 인스턴스가 종료된 후에는 요청이 종결됩니다. 영구 요청은 동일 요청에 대해 실행 중인 스팟 인스턴스가 없을 때마다 이행해야 할 요청으로 간주됩니다. 이 요청 유형을 지정하려면 스팟 요청에 대해 이 유형을 설정하기만 하면 됩니다. 다음 코드를 사용하여 설정할 수 있습니다.

// Retrieves the credentials from an AWSCredentials.properties file. AWSCredentials credentials = null; try { credentials = new PropertiesCredentials( GettingStartedApp.class.getResourceAsStream("AwsCredentials.properties")); } catch (IOException e1) { System.out.println( "Credentials were not properly entered into AwsCredentials.properties."); System.out.println(e1.getMessage()); System.exit(-1); } // Create the AmazonEC2 client so we can call various APIs. AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient(); // Initializes a Spot Instance Request RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest(); // Request 1 x t1.micro instance with a bid price of $0.03. requestRequest.setSpotPrice("0.03"); requestRequest.setInstanceCount(Integer.valueOf(1)); // Set the type of the bid to persistent. requestRequest.setType("persistent"); // Set up the specifications of the launch. This includes the // instance type (e.g. t1.micro) and the latest Amazon Linux // AMI id available. Note, you should always use the latest // Amazon Linux AMI id or another of your choosing. LaunchSpecification launchSpecification = new LaunchSpecification(); launchSpecification.setImageId("ami-a9d09ed1"); launchSpecification.setInstanceType(InstanceType.T1Micro); // Add the security group to the request. ArrayList<String> securityGroups = new ArrayList<String>(); securityGroups.add("GettingStartedGroup"); launchSpecification.setSecurityGroups(securityGroups); // Add the launch specification. requestRequest.setLaunchSpecification(launchSpecification); // Call the RequestSpotInstance API. RequestSpotInstancesResult requestResult = ec2.requestSpotInstances(requestRequest);

요청 기간 제한

필요에 따라 요청이 유효 상태로 유지될 시간 길이를 지정할 수도 있습니다. 이 기간의 시작 및 종료 시간을 둘 다 지정할 수 있습니다. 기본적으로 스팟 요청은 생성된 시점부터 이행되거나 요청자가 취소할 때까지 이행해야 할 요청으로 간주됩니다. 하지만 필요한 경우 유효 기간을 제한할 수도 있습니다. 이 기간을 지정하는 방법의 예는 다음 코드에 나와 있습니다.

// Create the AmazonEC2 client so we can call various APIs. AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient(); // Initializes a Spot Instance Request RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest(); // Request 1 x t1.micro instance with a bid price of $0.03. requestRequest.setSpotPrice("0.03"); requestRequest.setInstanceCount(Integer.valueOf(1)); // Set the valid start time to be two minutes from now. Calendar cal = Calendar.getInstance(); cal.add(Calendar.MINUTE, 2); requestRequest.setValidFrom(cal.getTime()); // Set the valid end time to be two minutes and two hours from now. cal.add(Calendar.HOUR, 2); requestRequest.setValidUntil(cal.getTime()); // Set up the specifications of the launch. This includes // the instance type (e.g. t1.micro) // and the latest Amazon Linux AMI id available. // Note, you should always use the latest Amazon // Linux AMI id or another of your choosing. LaunchSpecification launchSpecification = new LaunchSpecification(); launchSpecification.setImageId("ami-a9d09ed1"); launchSpecification.setInstanceType("t1.micro"); // Add the security group to the request. ArrayList<String> securityGroups = new ArrayList<String>(); securityGroups.add("GettingStartedGroup"); launchSpecification.setSecurityGroups(securityGroups); // Add the launch specification. requestRequest.setLaunchSpecification(launchSpecification); // Call the RequestSpotInstance API. RequestSpotInstancesResult requestResult = ec2.requestSpotInstances(requestRequest);

Amazon EC2 스팟 인스턴스 요청 그룹화

여러 가지 방식으로 스팟 인스턴스 요청을 그룹화할 수 있습니다. 시작 그룹, 가용 영역 그룹 및 배치 그룹을 사용할 때의 이점에 대해 살펴보겠습니다.

스팟 인스턴스가 모두 함께 시작 및 종료되도록 하려는 경우 시작 그룹을 활용하면 됩니다. 시작 그룹은 입찰 세트를 함께 그룹화하는 레이블입니다. 시작 그룹에 있는 모든 인스턴스가 함께 시작되고 종료됩니다. 시작 그룹에 포함된 인스턴스가 이미 이행된 경우 동일한 시작 그룹과 함께 시작된 새 인스턴스도 이행될지는 장담할 수 없습니다. 시작 그룹을 설정하는 방법의 예는 다음 코드 예제에 나와 있습니다.

// Create the AmazonEC2 client so we can call various APIs. AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient(); // Initializes a Spot Instance Request RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest(); // Request 5 x t1.micro instance with a bid price of $0.03. requestRequest.setSpotPrice("0.03"); requestRequest.setInstanceCount(Integer.valueOf(5)); // Set the launch group. requestRequest.setLaunchGroup("ADVANCED-DEMO-LAUNCH-GROUP"); // Set up the specifications of the launch. This includes // the instance type (e.g. t1.micro) and the latest Amazon Linux // AMI id available. Note, you should always use the latest // Amazon Linux AMI id or another of your choosing. LaunchSpecification launchSpecification = new LaunchSpecification(); launchSpecification.setImageId("ami-a9d09ed1"); launchSpecification.setInstanceType(InstanceType.T1Micro); // Add the security group to the request. ArrayList<String> securityGroups = new ArrayList<String>(); securityGroups.add("GettingStartedGroup"); launchSpecification.setSecurityGroups(securityGroups); // Add the launch specification. requestRequest.setLaunchSpecification(launchSpecification); // Call the RequestSpotInstance API. RequestSpotInstancesResult requestResult = ec2.requestSpotInstances(requestRequest);

인스턴스를 구분하지 않고 요청 안에 포함된 모든 인스턴스를 동일한 가용 영역에서 시작되도록 하려는 경우 가용 영역 그룹을 활용할 수 있습니다. 가용 영역 그룹은 동일한 가용 영역 안에서 인스턴스 세트를 함께 그룹화하는 레이블입니다. 가용 영역 그룹을 공유하고 동시에 이행되는 모든 인스턴스는 동일한 가용 영역에서 시작됩니다. 다음 예는 가용 영역 그룹을 설정하는 방법을 보여줍니다.

// Create the AmazonEC2 client so we can call various APIs. AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient(); // Initializes a Spot Instance Request RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest(); // Request 5 x t1.micro instance with a bid price of $0.03. requestRequest.setSpotPrice("0.03"); requestRequest.setInstanceCount(Integer.valueOf(5)); // Set the availability zone group. requestRequest.setAvailabilityZoneGroup("ADVANCED-DEMO-AZ-GROUP"); // Set up the specifications of the launch. This includes the instance // type (e.g. t1.micro) and the latest Amazon Linux AMI id available. // Note, you should always use the latest Amazon Linux AMI id or another // of your choosing. LaunchSpecification launchSpecification = new LaunchSpecification(); launchSpecification.setImageId("ami-a9d09ed1"); launchSpecification.setInstanceType(InstanceType.T1Micro); // Add the security group to the request. ArrayList<String> securityGroups = new ArrayList<String>(); securityGroups.add("GettingStartedGroup"); launchSpecification.setSecurityGroups(securityGroups); // Add the launch specification. requestRequest.setLaunchSpecification(launchSpecification); // Call the RequestSpotInstance API. RequestSpotInstancesResult requestResult = ec2.requestSpotInstances(requestRequest);

스팟 인스턴스에 사용할 가용 영역을 지정할 수 있습니다. 다음 코드 예제는 가용 영역을 설정하는 방법을 보여줍니다.

// Create the AmazonEC2 client so we can call various APIs. AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient(); // Initializes a Spot Instance Request RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest(); // Request 1 x t1.micro instance with a bid price of $0.03. requestRequest.setSpotPrice("0.03"); requestRequest.setInstanceCount(Integer.valueOf(1)); // Set up the specifications of the launch. This includes the instance // type (e.g. t1.micro) and the latest Amazon Linux AMI id available. // Note, you should always use the latest Amazon Linux AMI id or another // of your choosing. LaunchSpecification launchSpecification = new LaunchSpecification(); launchSpecification.setImageId("ami-a9d09ed1"); launchSpecification.setInstanceType(InstanceType.T1Micro); // Add the security group to the request. ArrayList<String> securityGroups = new ArrayList<String>(); securityGroups.add("GettingStartedGroup"); launchSpecification.setSecurityGroups(securityGroups); // Set up the availability zone to use. Note we could retrieve the // availability zones using the ec2.describeAvailabilityZones() API. For // this demo we will just use us-east-1a. SpotPlacement placement = new SpotPlacement("us-east-1b"); launchSpecification.setPlacement(placement); // Add the launch specification. requestRequest.setLaunchSpecification(launchSpecification); // Call the RequestSpotInstance API. RequestSpotInstancesResult requestResult = ec2.requestSpotInstances(requestRequest);

마지막으로 클러스터 컴퓨팅 인스턴스나 클러스터 GPU 인스턴스 같은 HPC(고성능 컴퓨팅) 스팟 인스턴스를 사용하려는 경우 배치 그룹을 지정할 수 있습니다. 배치 그룹은 인스턴스 간에 있어 낮은 지연 시간과 높은 대역폭 연결성을 제공합니다. 다음 예는 배치 그룹을 설정하는 방법을 보여줍니다.

// Create the AmazonEC2 client so we can call various APIs. AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient(); // Initializes a Spot Instance Request RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest(); // Request 1 x t1.micro instance with a bid price of $0.03. requestRequest.setSpotPrice("0.03"); requestRequest.setInstanceCount(Integer.valueOf(1)); // Set up the specifications of the launch. This includes the instance // type (e.g. t1.micro) and the latest Amazon Linux AMI id available. // Note, you should always use the latest Amazon Linux AMI id or another // of your choosing. LaunchSpecification launchSpecification = new LaunchSpecification(); launchSpecification.setImageId("ami-a9d09ed1"); launchSpecification.setInstanceType(InstanceType.T1Micro); // Add the security group to the request. ArrayList<String> securityGroups = new ArrayList<String>(); securityGroups.add("GettingStartedGroup"); launchSpecification.setSecurityGroups(securityGroups); // Set up the placement group to use with whatever name you desire. // For this demo we will just use "ADVANCED-DEMO-PLACEMENT-GROUP". SpotPlacement placement = new SpotPlacement(); placement.setGroupName("ADVANCED-DEMO-PLACEMENT-GROUP"); launchSpecification.setPlacement(placement); // Add the launch specification. requestRequest.setLaunchSpecification(launchSpecification); // Call the RequestSpotInstance API. RequestSpotInstancesResult requestResult = ec2.requestSpotInstances(requestRequest);

이 단원에 표시된 모든 매개 변수는 선택적 매개 변수입니다. 또한 입찰이 일회성인지 지속적인지를 제외하고 대부분의 매개 변수가 입찰 이행 가능성을 줄일 수 있다는 점을 인식하는 것도 중요합니다. 그러므로 꼭 필요한 경우에만 이러한 옵션을 활용해야 합니다. 앞에 제시된 코드 예제는 모두 하나의 긴 코드 샘플로 결합되어 있으며 com.amazonaws.codesamples.advanced.InlineGettingStartedCodeSampleApp.java 클래스에서 확인할 수 있습니다.

중단 또는 종료 후 루트 파티션을 지속하는 방법

스팟 인스턴스 중단을 관리하는 가장 쉬운 방법 중 하나는 데이터가 정기적으로 Amazon Elastic Block Store(Amazon Amazon EBS) 볼륨으로 체크포인트되도록 하는 것입니다. 정기적으로 검사하여 중단이 있는 경우 마지막 체크포인트 이후에 생성된 데이터만 손실됩니다(그 사이에 다른 비 idempotent 작업이 수행되지 않는다고 가정할 때). 이 프로세스를 보다 쉽게 처리하기 위해 루트 파티션이 중단 또는 종료 시 삭제되지 않도록 스팟 요청을 구성할 수 있습니다. 다음 예제에는 이 시나리오를 활성화하는 방법을 보여주는 새 코드를 삽입했습니다.

추가된 코드에서는 BlockDeviceMapping 객체를 생성하고 관련 Amazon Elastic Block Store(Amazon EBS)를 스팟 인스턴스가 종료되는 경우 삭제되지 않도록 not로 구성된 Amazon EBS 객체로 설정합니다. 그런 다음 이 BlockDeviceMapping을 시작 사양에 포함할 매핑 ArrayList에 추가합니다.

// Retrieves the credentials from an AWSCredentials.properties file. AWSCredentials credentials = null; try { credentials = new PropertiesCredentials( GettingStartedApp.class.getResourceAsStream("AwsCredentials.properties")); } catch (IOException e1) { System.out.println( "Credentials were not properly entered into AwsCredentials.properties."); System.out.println(e1.getMessage()); System.exit(-1); } // Create the AmazonEC2 client so we can call various APIs. AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient(); // Initializes a Spot Instance Request RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest(); // Request 1 x t1.micro instance with a bid price of $0.03. requestRequest.setSpotPrice("0.03"); requestRequest.setInstanceCount(Integer.valueOf(1)); // Set up the specifications of the launch. This includes the instance // type (e.g. t1.micro) and the latest Amazon Linux AMI id available. // Note, you should always use the latest Amazon Linux AMI id or another // of your choosing. LaunchSpecification launchSpecification = new LaunchSpecification(); launchSpecification.setImageId("ami-a9d09ed1"); launchSpecification.setInstanceType(InstanceType.T1Micro); // Add the security group to the request. ArrayList<String> securityGroups = new ArrayList<String>(); securityGroups.add("GettingStartedGroup"); launchSpecification.setSecurityGroups(securityGroups); // Create the block device mapping to describe the root partition. BlockDeviceMapping blockDeviceMapping = new BlockDeviceMapping(); blockDeviceMapping.setDeviceName("/dev/sda1"); // Set the delete on termination flag to false. EbsBlockDevice ebs = new EbsBlockDevice(); ebs.setDeleteOnTermination(Boolean.FALSE); blockDeviceMapping.setEbs(ebs); // Add the block device mapping to the block list. ArrayList<BlockDeviceMapping> blockList = new ArrayList<BlockDeviceMapping>(); blockList.add(blockDeviceMapping); // Set the block device mapping configuration in the launch specifications. launchSpecification.setBlockDeviceMappings(blockList); // Add the launch specification. requestRequest.setLaunchSpecification(launchSpecification); // Call the RequestSpotInstance API. RequestSpotInstancesResult requestResult = ec2.requestSpotInstances(requestRequest);

시작 시 인스턴스에 이 볼륨을 다시 연결하려 한다고 가정할 때, 블록 디바이스 매핑 설정도 사용할 수 있습니다. 또는 루트가 아닌 파티션을 연결한 경우 스팟 인스턴스가 재개된 후 연결하려는 Amazon Amazon EBS 볼륨을 지정할 수 있습니다. 이렇게 하려면 EbsBlockDevice 객체에서 스냅샷 ID를 지정하고 BlockDeviceMapping 객체에서 대체 장치 이름을 지정하면 됩니다. 블록 디바이스 매핑을 활용하면 인스턴스를 좀 더 쉽게 부트스트래핑할 수 있습니다.

루트 파티션을 사용하여 중요 데이터를 검사하는 것은 인스턴스 중단 가능성을 관리하는 좋은 방법입니다. 중단 가능성 관리에 대한 그 밖의 방법은 Managing Interruption 비디오를 참조하십시오.

스팟 요청 및 인스턴스에 태그를 지정하는 방법

Amazon EC2 리소스에 태그를 추가하면 클라우드 인프라 관리를 간소화할 수 있습니다. 메타데이터 형태의 태그를 사용해 사용자 친화적인 이름을 만들고, 검색 능력을 강화하며, 여러 사용자 간의 조정을 개선할 수 있습니다. 태그를 사용하여 프로세스의 부분과 스크립트를 자동화할 수도 있습니다. Amazon EC2 리소스 태깅에 대해 더 읽어보려면 Linux 인스턴스용 Amazon EC2 사용 설명서의 태그 사용을 참조하세요.

요청 태그 지정

스팟 요청에 태그를 추가하려면 요청된 이후에 태그를 지정해야 합니다. requestSpotInstances()의 반환 값이 태그 지정용 스팟 요청 ID를 가져오는 데 사용할 수 있는 RequestSpotInstancesResult 객체를 제공합니다.

// Call the RequestSpotInstance API. RequestSpotInstancesResult requestResult = ec2.requestSpotInstances(requestRequest); List<SpotInstanceRequest> requestResponses = requestResult.getSpotInstanceRequests(); // A list of request IDs to tag ArrayList<String> spotInstanceRequestIds = new ArrayList<String>(); // Add the request ids to the hashset, so we can determine when they hit the // active state. for (SpotInstanceRequest requestResponse : requestResponses) { System.out.println("Created Spot Request: "+requestResponse.getSpotInstanceRequestId()); spotInstanceRequestIds.add(requestResponse.getSpotInstanceRequestId()); }

ID를 얻고 나면 이 ID를 CreateTagsRequest에 추가하고 Amazon EC2 클라이언트의 createTags() 메서드를 호출하여 요청에 태그를 지정할 수 있습니다.

// The list of tags to create ArrayList<Tag> requestTags = new ArrayList<Tag>(); requestTags.add(new Tag("keyname1","value1")); // Create the tag request CreateTagsRequest createTagsRequest_requests = new CreateTagsRequest(); createTagsRequest_requests.setResources(spotInstanceRequestIds); createTagsRequest_requests.setTags(requestTags); // Tag the spot request try { ec2.createTags(createTagsRequest_requests); } catch (AmazonServiceException e) { System.out.println("Error terminating instances"); System.out.println("Caught Exception: " + e.getMessage()); System.out.println("Reponse Status Code: " + e.getStatusCode()); System.out.println("Error Code: " + e.getErrorCode()); System.out.println("Request ID: " + e.getRequestId()); }

인스턴스 태그 지정

스팟 요청 자체와 마찬가지로, 인스턴스에도 생성된 후에만 태그를 지정할 수 있습니다. 즉, 태그 지정은 스팟 요청이 충족되고 나서만(더 이상 열림 상태가 아닌 경우)만 발생합니다.

DescribeSpotInstanceRequestsRequest 객체를 사용하여 Amazon EC2 클라이언트의 describeSpotInstanceRequests() 메서드를 호출하여 요청 상태를 확인할 수 있습니다. 반환된 DescribeSpotInstanceRequestsResult 객체에는 스팟 요청의 상태를 쿼리하고 더 이상 열린 상태가 아닌 경우 해당 인스턴스 ID를 가져오는 데 사용할 수 있는 SpotInstanceRequest 객체 목록이 포함되어 있습니다.

스팟 요청이 더 이상 열려 있지 않으면 getInstanceId() 메서드를 호출하여 SpotInstanceRequest 객체에서 인스턴스 ID를 가져올 수 있습니다.

boolean anyOpen; // tracks whether any requests are still open // a list of instances to tag. ArrayList<String> instanceIds = new ArrayList<String>(); do { DescribeSpotInstanceRequestsRequest describeRequest = new DescribeSpotInstanceRequestsRequest(); describeRequest.setSpotInstanceRequestIds(spotInstanceRequestIds); anyOpen=false; // assume no requests are still open try { // Get the requests to monitor DescribeSpotInstanceRequestsResult describeResult = ec2.describeSpotInstanceRequests(describeRequest); List<SpotInstanceRequest> describeResponses = describeResult.getSpotInstanceRequests(); // are any requests open? for (SpotInstanceRequest describeResponse : describeResponses) { if (describeResponse.getState().equals("open")) { anyOpen = true; break; } // get the corresponding instance ID of the spot request instanceIds.add(describeResponse.getInstanceId()); } } catch (AmazonServiceException e) { // Don't break the loop due to an exception (it may be a temporary issue) anyOpen = true; } try { Thread.sleep(60*1000); // sleep 60s. } catch (Exception e) { // Do nothing if the thread woke up early. } } while (anyOpen);

이제 반환된 인스턴스에 태그를 지정할 수 있습니다.

// Create a list of tags to create ArrayList<Tag> instanceTags = new ArrayList<Tag>(); instanceTags.add(new Tag("keyname1","value1")); // Create the tag request CreateTagsRequest createTagsRequest_instances = new CreateTagsRequest(); createTagsRequest_instances.setResources(instanceIds); createTagsRequest_instances.setTags(instanceTags); // Tag the instance try { ec2.createTags(createTagsRequest_instances); } catch (AmazonServiceException e) { // Write out any exceptions that may have occurred. System.out.println("Error terminating instances"); System.out.println("Caught Exception: " + e.getMessage()); System.out.println("Reponse Status Code: " + e.getStatusCode()); System.out.println("Error Code: " + e.getErrorCode()); System.out.println("Request ID: " + e.getRequestId()); }

스팟 요청 취소 및 인스턴스 종료

스팟 요청 취소

스팟 인스턴스 요청을 취소하려면 CancelSpotInstanceRequestsRequest 객체를 사용하여 Amazon EC2 클라이언트에서 cancelSpotInstanceRequests를 호출하세요.

try { CancelSpotInstanceRequestsRequest cancelRequest = new CancelSpotInstanceRequestsRequest(spotInstanceRequestIds); ec2.cancelSpotInstanceRequests(cancelRequest); } catch (AmazonServiceException e) { System.out.println("Error cancelling instances"); System.out.println("Caught Exception: " + e.getMessage()); System.out.println("Reponse Status Code: " + e.getStatusCode()); System.out.println("Error Code: " + e.getErrorCode()); System.out.println("Request ID: " + e.getRequestId()); }

스팟 인스턴스 종료

ID를 Amazon EC2 client의 terminateInstances() 메서드에 전달하여 실행 중인 스팟 인스턴스를 종료할 수 있습니다.

try { TerminateInstancesRequest terminateRequest = new TerminateInstancesRequest(instanceIds); ec2.terminateInstances(terminateRequest); } catch (AmazonServiceException e) { System.out.println("Error terminating instances"); System.out.println("Caught Exception: " + e.getMessage()); System.out.println("Reponse Status Code: " + e.getStatusCode()); System.out.println("Error Code: " + e.getErrorCode()); System.out.println("Request ID: " + e.getRequestId()); }

모두 종합

지금까지의 작업을 모두 종합하여, 이 자습서에 표시된 단계를 사용하기 쉬운 단일 클래스로 결합하는 보다 객체 지향적인 방법을 제공하려고 합니다. 이러한 작업을 수행하는 Requests 클래스를 인스턴스화하겠습니다. 또한 상위 수준의 함수 호출을 수행하는 기본 메서드가 있는 GettingStartedApp 클래스도 생성합니다.

이 예제의 전체 소스 코드는 GitHub에서 확인하거나 다운로드할 수 있습니다.

축하합니다! AWS SDK for Java를 사용한 스팟 인스턴스 소프트웨어 개발 관련 고급 요청 기능 자습서를 완료했습니다.