Heesung Yang
AWS CLI [EC2] - 생성하기
EC2 란?
AWS를 처음 사용할 때 가장 쉽게 접할 수 있는 서비스가 EC2
다. 일반 서버를 다루는 것과 비슷하다.
물리적인 하드웨어 구입 없이, AWS 상에 가상의 서버를 만드는 서비스가 EC2
다.
일단, 명령어 예시부터 보고 가자.
~$ aws ec2 run-instances \
--image-id ami-06e83aceba2cb0907 \
--instance-type t3a.nano \
--block-device-mappings 'DeviceName=/dev/sda1,Ebs={DeleteOnTermination=true,VolumeSize=30,VolumeType=gp3}' \
--key-name my-key-1 \
--tag-specifications \
'ResourceType=instance,Tags=[{Key=Name,Value=my-test-ec2-1}]' \
'ResourceType=volume,Tags=[{Key=Name,Value=my-test-ec2-1}]'
옵션이 상당히 많다. 너무 겁먹지 말자. 실제 물리적인 컴퓨터를 구매해서 OS를 설치하고 SSH 접속까지 완료하는 과정과 비교하면 좀 더 쉽게 이해할 수 있다.
대략 아래와 같은 순서가 될 것이다.
- 사용할 OS 결정
- OSX을 쓸 거면 Mac을 구입하고 Windows를 쓸 거면 Windows가 포함된 랩탑을 구매하는 것과 비슷하다.
- 사용할 Machine Spec 결정
- CPU, 메모리, 디스크 용량 등
- Machine 구입 및 부팅
- ssh 접속
EC2
도 동일하다. 위 항목을 잘 기억하고 하나하나 진행해보자.
사용할 OS 결정
~$ aws ec2 run-instances \
--image-id ami-06e83aceba2cb0907 \
--instance-type t3a.nano \
--block-device-mappings 'DeviceName=/dev/sda1,Ebs={DeleteOnTermination=true,VolumeSize=30,VolumeType=gp3}' \
--key-name my-key-1 \
--tag-specifications \
'ResourceType=instance,Tags=[{Key=Name,Value=my-test-ec2-1}]' \
'ResourceType=volume,Tags=[{Key=Name,Value=my-test-ec2-1}]'
위 명령어 예시 옵션의 --image-id
에 대한 값을 찾는 과정이다.
AWS에서 사용할 수 있는 OS는 AMI(Amazon Machine Image) 형태로 제공된다.
AMI란, OS + 자신만의 application 설치 및 서버 설정 등
이 포함된 것이라고 이해하면 된다.
물론 OS만 설치된 AMI도 있다.
여기서는 CentOS 7을 사용하겠다. (OS만 설치된 AMI)
아래 명령어로 AMI 검색이 가능하지만, 솔직히 추천하지 않는다. 알아보기 어렵다. 차라리 https://aws.amazon.com/marketplace 에서 AMI 찾아 본 후 AMI ID를 확인하는 편을 추천한다.
CLI로 검색하기
~$ aws ec2 describe-images --filters 'Name=description,Values=*CentOS Linux 7*' --query 'Images[*].[ImageId,Description]' --output table
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| DescribeImages |
+-----------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ami-01449fc66c70c5787| AWS-VMImport service: Linux - CentOS Linux 7 (Core) - 3.10.0-1062.4.3.el7.x86_64 |
| ami-021015b95e7bdfbbe| CentOS Linux 7 x86_64 HVM EBS ENA 1901_01 by Banzai Cloud |
| ami-0214cba1bd453d731| AWS-VMImport service: Linux - CentOS Linux 7 (Core) - 3.10.0-1062.4.3.el7.x86_64 |
| ami-02e115f53f532b515| AWS-VMImport service: Linux - CentOS Linux 7 (Core) - 3.10.0-1062.4.3.el7.x86_64 |
| ami-02f1bca131a9e4b5b| AWS-VMImport service: Linux - CentOS Linux 7 (Core) - 3.10.0-1062.4.3.el7.x86_64 |
| ami-03fb719d0aa5bd708| Ontoportal Appliance version 3.0.2 runing on CentOS Linux 7 x86_64 HVM EBS 20200807 |
| ami-046d669bfeaa106e7| Ontoportal Appliance version 3.0.5 runing on CentOS Linux 7 x86_64 HVM EBS 20210826 |
| ami-049d6d9eadf675b17| AWS-VMImport service: Linux - CentOS Linux 7 (Core) - 3.10.0-1062.4.3.el7.x86_64 |
| ami-04eff034ca5126817| CentOS 7 LVM Minimal Install Golden AMI Template (CentOS Linux 7.9 LVM) (CentOS Linux 7 LVM) (CentOS Linux LVM) (CentOS 7.9 LVM) (CentOS LVM) (centoslinux7 lvm) (centos7 lvm) |
| ami-054259e08868dab06| CentOS 7 Minimal Install Golden AMI Template (CentOS Linux 7.9) (CentOS 7.9) (centos7) |
| ami-069c47c6f4465913d| CentOS 7 Minimal Install Golden AMI Template (CentOS Linux 7.9) (CentOS 7.9) (centos7) |
| ami-06cf2a72dadf92410| CentOS Linux 7 x86_64 HVM EBS ENA 1901_01 |
| ami-06e83aceba2cb0907| CentOS Linux 7 x86_64 HVM EBS ENA 2002_01 |
| ami-0708dd1de57b297a9| CentOS 7 Minimal Install Golden AMI Template (CentOS Linux 7.9) (CentOS 7.9) (centos7) |
| ami-082a9dcda6ea953f4| Ontoportal Appliance version 3.0.4 runing on CentOS Linux 7 x86_64 HVM EBS 20210708 |
| ami-0863040845c41f065| AWS-VMImport service: Linux - CentOS Linux 7 (Core) - 3.10.0-1062.4.3.el7.x86_64 |
| ami-08874d501077c2ff9| AWS-VMImport service: Linux - CentOS Linux 7 (Core) - 3.10.0-1062.4.3.el7.x86_64 |
| ami-088f496c95a767281| AWS-VMImport service: Linux - CentOS Linux 7 (Core) - 3.10.0-1062.4.3.el7.x86_64 |
| ami-09835c9087e4c0ea9| CentOS 7 Minimal Install Golden AMI Template (CentOS Linux 7.9) (CentOS 7.9) (centos7) |
| ami-0a36b8229ac6b03da| AWS-VMImport service: Linux - CentOS Linux 7 (Core) - 3.10.0-1062.4.3.el7.x86_64 |
| ami-0a80d0baa4e8c508b| Ontoportal Appliance version 3.0.3 runing on CentOS Linux 7 x86_64 HVM EBS 20201211 |
| ami-0a942096c3b61bf14| CentOS 7 Minimal Install Golden AMI Template (CentOS Linux 7.9) (CentOS 7.9) (centos7) |
| ami-0af4f8ade20044f62| AWS-VMImport service: Linux - CentOS Linux 7 (Core) - 3.10.0-1062.4.3.el7.x86_64 |
| ami-0b730778606329e4c| AWS-VMImport service: Linux - CentOS Linux 7 (Core) - 3.10.0-1062.4.3.el7.x86_64 |
| ami-0be614e732b058722| AWS-VMImport service: Linux - CentOS Linux 7 (Core) - 3.10.0-1062.4.3.el7.x86_64 |
| ami-0daaed13d41ea083a| CentOS 7 Latest Minimal Install Golden AMI Template (CentOS Linux 7.9) (CentOS 7.9) (centos7) |
| ami-0ef66197dfb521bf4| CentOS 7 Minimal Install Golden AMI Template (CentOS Linux 7.9) (CentOS 7.9) (centos7) |
| ami-0fa2bb48672e42b7d| AWS-VMImport service: Linux - CentOS Linux 7 (Core) - 3.10.0-1062.4.3.el7.x86_64 |
| ami-46963e28 | CentOS Linux 7 x86_64 HVM EBS ENA 1804_2 |
| ami-53a1073d | CentOS Linux 7 x86_64 HVM EBS 1708_11.01 |
| ami-56a40238 | CentOS Linux 7 x86_64 HVM EBS 1708_11.01 |
| ami-6bf42905 | Racemi CentOS Linux 7 x86_64 HVM EBS 20150928 |
| ami-885e8fe6 | Asgard-1.5.1 kinc ami v2 for CentOS Linux 7 |
| ami-97cb19f9 | CentOS Linux 7 x86_64 HVM EBS 1703_01 |
| ami-995cf3f7 | CentOS Linux 7 x86_64 HVM EBS ENA 1803_01 |
| ami-bf9c36d1 | CentOS Linux 7 x86_64 HVM EBS ENA 1805_01 |
| ami-c9f12ca7 | CentOS Linux 7 x86_64 HVM EBS 1704_01 |
| ami-f3a70f9d | CentOS Linux 7 x86_64 HVM EBS ENA 1804_1 |
+-----------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
AWS Market Place 에서 검색하기
AWS Management Console에 로그인 후 https://aws.amazon.com/marketplace에 접속하여 진행해야 한다.
AMI 검색 결과에 대해 알아둘 점
필자가 선택한 CentOS 7 (x86_64) - with Updates HVM 이미지를 예로 들어보겠다.
같은 AMI라도 Region에 따라 AMI ID가 달라진다
-
즉, 같은 AMI라 하더라도 서울 Region과 미국 오하이오 Region의 AMI ID가 각각 다르다.
ami-06e83aceba2cb0907
: 서울ami-01e36b7901e884a10
: 오하이오
-
아래는 같은 AMI의 AMI ID를 각 Region별로 찾는 방법이다.
-
검색 기준으로 삼을 AMI ID를 정한 후, 해당 AMI의 상세 정보 조회
~$ aws ec2 describe-images --image-ids ami-06e83aceba2cb0907 --region ap-northeast-2
{ "Images": [ { "Architecture": "x86_64", "CreationDate": "2020-03-09T21:54:51.000Z", "ImageId": "ami-06e83aceba2cb0907", "ImageLocation": "aws-marketplace/CentOS Linux 7 x86_64 HVM EBS ENA 2002_01-b7ee8a69-ee97-4a49-9e68-afaee216db2e-ami-0042af67f8e4dcc20.4", "ImageType": "machine", "Public": true, "OwnerId": "679593333241", "PlatformDetails": "Linux/UNIX", "UsageOperation": "RunInstances", "ProductCodes": [ { "ProductCodeId": "aw0evgkw8e5c1q413zgy5pjce", "ProductCodeType": "marketplace" } ], "State": "available", "BlockDeviceMappings": [ { "DeviceName": "/dev/sda1", "Ebs": { "DeleteOnTermination": false, "SnapshotId": "snap-0a58cffe5397c48d7", "VolumeSize": 8, "VolumeType": "gp2", "Encrypted": false } } ], "Description": "CentOS Linux 7 x86_64 HVM EBS ENA 2002_01", "EnaSupport": true, "Hypervisor": "xen", "ImageOwnerAlias": "aws-marketplace", "Name": "CentOS Linux 7 x86_64 HVM EBS ENA 2002_01-b7ee8a69-ee97-4a49-9e68-afaee216db2e-ami-0042af67f8e4dcc20.4", "RootDeviceName": "/dev/sda1", "RootDeviceType": "ebs", "SriovNetSupport": "simple", "VirtualizationType": "hvm" } ] }
-
미국 오하이오 Region에서 동일한 AMI ID로 검색 시 결과 없음
~$ aws ec2 describe-images --image-ids ami-06e83aceba2cb0907 --region us-east-2 An error occurred (InvalidAMIID.NotFound) when calling the DescribeImages operation: The image id '[ami-06e83aceba2cb0907]' does not exist
-
서울 Region에 존재하는 ami-06e83aceba2cb0907 의 Description 정보를 이용하여 미국 오하이오 Region에서 필터링 후 검색
aws ec2 describe-images \ --filters 'Name=description,Values=*CentOS Linux 7 x86_64 HVM EBS ENA 2002_01' \ --query 'Images[*].[ImageId,Description,Name]' \ --output table \ --region us-east-2
------------------------------------------------------------------------ | DescribeImages | +------------------------+---------------------------------------------+ | ami-01e36b7901e884a10 | CentOS Linux 7 x86_64 HVM EBS ENA 2002_01 | +------------------------+---------------------------------------------+
-
같은 AMI라도 aws cli와 AWS Market Place에서 표시되는 AMI 이름이 다르다
AWS Market Place에서 보여지는 이름은 CentOS 7 (x86_64) - with Updates HVM
이다.
반면, 위 스크린샷에 표현된 AMI ID의 상세 정보를 cli로 출력해보면 어디에서도 위 문구를 찾을 수 없다.
aws ec2 describe-images --image-ids ami-06e83aceba2cb0907
{
"Images": [
{
"Architecture": "x86_64",
"CreationDate": "2020-03-09T21:54:51.000Z",
"ImageId": "ami-06e83aceba2cb0907",
"ImageLocation": "aws-marketplace/CentOS Linux 7 x86_64 HVM EBS ENA 2002_01-b7ee8a69-ee97-4a49-9e68-afaee216db2e-ami-0042af67f8e4dcc20.4",
"ImageType": "machine",
"Public": true,
"OwnerId": "679593333241",
"PlatformDetails": "Linux/UNIX",
"UsageOperation": "RunInstances",
"ProductCodes": [
{
"ProductCodeId": "aw0evgkw8e5c1q413zgy5pjce",
"ProductCodeType": "marketplace"
}
],
"State": "available",
"BlockDeviceMappings": [
{
"DeviceName": "/dev/sda1",
"Ebs": {
"DeleteOnTermination": false,
"SnapshotId": "snap-0a58cffe5397c48d7",
"VolumeSize": 8,
"VolumeType": "gp2",
"Encrypted": false
}
}
],
"Description": "CentOS Linux 7 x86_64 HVM EBS ENA 2002_01",
"EnaSupport": true,
"Hypervisor": "xen",
"ImageOwnerAlias": "aws-marketplace",
"Name": "CentOS Linux 7 x86_64 HVM EBS ENA 2002_01-b7ee8a69-ee97-4a49-9e68-afaee216db2e-ami-0042af67f8e4dcc20.4",
"RootDeviceName": "/dev/sda1",
"RootDeviceType": "ebs",
"SriovNetSupport": "simple",
"VirtualizationType": "hvm"
}
]
}
사용할 Machine Spec 결정
~$ aws ec2 run-instances \
--image-id ami-06e83aceba2cb0907 \
--instance-type t3a.nano \
--block-device-mappings 'DeviceName=/dev/sda1,Ebs={DeleteOnTermination=true,VolumeSize=30,VolumeType=gp3}' \
--key-name my-key-1 \
--tag-specifications \
'ResourceType=instance,Tags=[{Key=Name,Value=my-test-ec2-1}]' \
'ResourceType=volume,Tags=[{Key=Name,Value=my-test-ec2-1}]'
위 명령어 예시 옵션의 --instance-type
와 --block-device-mappings
에 대한 값을 찾는 과정이다.
CPU/Memory/GPU/Network
AWS에서 생성할 수 있는 서버 사양(인스턴스 타입)을 아래 명령어로 확인해보자. (매우 많은 정보가 출력되기 때문에, 꼭 필요한 내용만 출력되도록 –query 옵션을 사용했다.)
~$ aws ec2 describe-instance-types \
--query 'sort_by(InstanceTypes, &InstanceType)[].[InstanceType,VCpuInfo.DefaultVCpus,MemoryInfo.SizeInMiB,NetworkInfo.NetworkPerformance,GpuInfo.Gpus[0].Name,GpuInfo.Gpus[0].Manufacturer,GpuInfo.Gpus[0].Count,GpuInfo.Gpus[0].MemoryInfo.SizeInMiB]' \
--output table
명령어 실행 결과는 다음 순서대로 표시된다.
- 인스턴스 타입
- CPU 코어 갯수
- 메모리(MiB)
- 네트워크 대역폭
- GPU 모델
- GPU 제조사
- GPU 갯수
- GPU 메모리
-------------------------------------------------------------------------------------
| c4.2xlarge | 8 | 15360 | High | None | None | None | None |
| c4.4xlarge | 16 | 30720 | High | None | None | None | None |
| c4.8xlarge | 36 | 61440 | 10 Gigabit | None | None | None | None |
| c4.large | 2 | 3840 | Moderate | None | None | None | None |
...
| g3s.xlarge | 4 | 31232 | Up to 10 Gigabit | M60 | NVIDIA | 1 | 8192 |
| g4dn.12xlarge| 48 | 196608 | 50 Gigabit | T4 | NVIDIA | 4 | 16384 |
물론 AWS 공식 사이트에서 확인할 수도 있다. (https://aws.amazon.com/ko/ec2/instance-types/)
사양에 비례해서 사용 요금이 올라가므로 자신의 사용 목적에 맞는 타입을 고르는 것이 중요하다. 인스턴스를 생성해서 사용하다가 서버 부하가 심해서 사양을 좀 높이고 싶다면, 버튼 몇 번으로 인스턴스 타입을 변경할 수 있다.
다만,
- 인스턴스를 중지하고 다시 시작해야 한다. (다운타임 발생)
- 같은 계열의 인스턴스 타입으로만 변경 가능하다. GPU없는 인스턴스를 사용하다가 GPU 인스턴스 타입으로 변경이 불가능하다는 얘기다.
- t3.small -> t3.2xlarge : 변경 가능
- t3.small -> g4dn.xlarge : 변경 불가능
여기서는 t3a.micro
타입을 사용하겠다.
# 타입 CPU 메모리 네트워크 GPU 관련
| t3a.micro | 2 | 1024 | Up to 5 Gigabit | None | None | None | None |
Disk
--block-device-mappings \
'DeviceName=/dev/sda1,Ebs={DeleteOnTermination=true,VolumeSize=30,VolumeType=gp3}'
위 옵션에 대한 내용이다. 디스크는 별도로 설정해줘야 하는데, 사용할 디스크 타입과 용량을 지정하면 된다.
- 디스크 디바이스 이름(
DeviceName
) : 기본으로/dev/sda1
사용하자. - 디스크 용량 설정(
VolumeSize
): 단위는 GB다. 필요한 만큼 설정하자. - 디스크 타입(
VolumeType
)- 디스크 성능에 대한 특별한 요구사항이 없다면 범용 SSD 타입인
gp3
를 사용하자. - 타입별 요금 확인은 https://aws.amazon.com/ko/ebs/pricing/
- 디스크에 대한 특별한 요구사항이 있다면 아래 페이지를 참고하자. (일정 성능을 보장해야 한다던가, 자주 접근할 일 없는 많은 데이터를 저장해야 한다던가)
- 디스크 성능에 대한 특별한 요구사항이 없다면 범용 SSD 타입인
- AWS에서 디스크는 EC2와 별개로 관리 된다.
- 때문에 A라는 EC2를 만들때 사용했던 디스크는 A EC2를 삭제하더라도 그대로 남아 있다.
- 이렇게 남아 있는 디스크는 새로운 EC2 생성 시 재활용할 수도 있다.
- 이 점을 이용하여 EC2 타입 변경 시 활용 가능하다.
- 그러나 관리를 제대로 안하면, 속된 말로
미아
디스크가 발생한다. (어느 EC2에도 붙어있지 않은 디스크) - 이 디스크들은 차지하고 있는 용량만큼 계속 비용이 발생하기 때문에 잘 관리해야 한다.
- 위와 같이 관리자 실수로 디스크를 삭제하지 않는 경우를 방지하기 위해 EC2 생성 시 옵션을 추가할 수 있는데 그게 바로 DeleteOnTermination 이다.
- 위 옵션을
true
로 설정하면 해당 디스크가 붙어있는 EC2가 삭제되면 디스크도 같이 삭제된다.
ssh 접속 설정
~$ aws ec2 run-instances \
--image-id ami-06e83aceba2cb0907 \
--instance-type t3a.nano \
--block-device-mappings 'DeviceName=/dev/sda1,Ebs={DeleteOnTermination=true,VolumeSize=30,VolumeType=gp3}' \
--key-name my-key-1 \
--tag-specifications \
'ResourceType=instance,Tags=[{Key=Name,Value=my-test-ec2-1}]' \
'ResourceType=volume,Tags=[{Key=Name,Value=my-test-ec2-1}]'
위 명령어 예시의 --key-namee
옵션에 대한 설정 방법이다.
보통 ssh 접속 시 ID/Password를 이용하여 접속하는데, AWS에서 제공하는 CentOS AMI에서는 ID/Password 접속 방식을 허용하지 않는다.(default, 접속 후 변경 가능) 대신 ssh private key 파일을 이용해서 접속할 수 있다. (TODO:ssh private key 에 대한 설명은 추 후 포스팅 하겠다.)
이 key 파일을 AWS 에서는 key pair
라는 이름으로 관리한다.
ec2 인스턴스를 만들때마다 key pair
를 새로 생성하면 관리하는 것도 일이기 때문에 1개만 만들어서 재사용하는 편을 권한다.
Key pair 생성
적절한 key 이름으로 key pair
를 생성하자. 여기서는 my-key-1
이라는 이름을 사용했다.
~$ aws ec2 create-key-pair --key-name my-key-1
{
"KeyFingerprint": "77:b5:c0:02:bb:40:77:8a:e7:75:f6:be:85:1a:74:c2:74:46:c8:75",
"KeyMaterial": "-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEApw2YpCbWP+1me8T7JjgExxt/F/K0Xnt1+zdUzxjRdO013xhw\nIlDd+V7fp/NNSEJxWKGvFzJV4cI+MIXXLUcaSSMGP8Pd9AgO7ONhUG8HVpGp/Sco\nI3UzKMOala/kXlWXdhsR2Abxc9ObNlzb57/AJnTQ5+H/nbFvwSuTK8s0/ZeNfIa4\nDqm6ZLx4szlUYh+NTexMY9tj9HGvJu0oK2HbqajaFA3cJsAHXsBEaaEpmP3t57jS\nAPtrVyWWx7TXUjn/PAHiczn1QjXhPSI60NP7Lz2MG9dRde6QVlVFiCNsIdg4OWJh\nZYunuvnScK/gRgw0Qm9frtjMJU8W2iTO+MjWowIDAQABAoIBADnlK2aQkyY6p47z\nmLsJJRbAP87T7ZDlJuF2rqzLhCQK5eW4uXwbHKMFL2wslTca19+IwX6/kiYYxKba\na9WkU8bPHaZRwoWFmW6d6ycOI7Pr7cbvoCiRwLY6/EMuX24WKdTj0s5Usa+bwaoY\nipoJyZVKXPBQUd+cFAgViv7dgTL1lxiMkZF5QcQFxw+tm9/Qk/9QHmd12Vp4Scuj\ndFSX0pFptvp2B0+iL6wklAs/9QLFnLZEzAlNcZ0rU5M3Kx8rUq7GIfy9x6KzjH7r\nzUxEowYgR4LaCOwqV2GsUbcR/UeDMh3vp3Dnf5/gvTB+3St3yTnJA7kRJYLKFBb2\nNMpGf+ECgYEA8ddC5wJCMjZTYp9g6BrFBYsdXnSEB9GwD+h7R5WPnMIVvLLhDRHu\n3RH7lW2hVAIkSq+YM0ni0OsuI/OZLEFqFeRSuNR2J88FNpIzal6BCcAv4Nl0aufF\nPpolm8RUiam7j09z+/whmW3QSjWebD85Dvm1d4VButrAIwSys59xgdMCgYEAsNVo\nT59HodHhTXhAe4vXxtLp005dZz7WLXDP/btRhFTvS+eVIvboxlJbHdN61Sn8r2eV\njdGZq1UtWYe3MawfYrJ2rLRIshEsuxh8ASuwWsDgxONmF8YbqfFA+JzqPFEKgZws\nta2X/aZYnziZZcD0s/32Ybs8iB95RK5GgHe5hfECgYB/aNgfWkpDp+lQWQU14vyP\nihYD8ECq2eb2ypVARmQtwvauvlLgjuUX5OR1ehd3adVy34XA55kuVeiuGiVFcoUQ\nWYTXSV+iY2ess2ORE47J802GGSpDNC3vaEiOAuZCzIA65TIGvHN7IKaOoib/gmNu\nJ1JaUIMrjRmSmWQIS+UB7wKBgHElCyovAvliPiOAdtnWH4lC+IPQl2jxRr8qeJqj\n2UOvyLErizwk+cmzdkN+RhDQXbKpt4JXg1iiFnM7qBarSCWxhMd6Ty1IWfOYdfeV\nybA3y1mPGorJone5OtYYKLPRMsS9dcoFOcP9RKUT5Oq7bJciPxxHXjLG2KP+UnPu\npxExAoGAJH9hb32fwZMfuVY2ip164hB4/M8kKjbNHihk3eK392qXh0mhp4KUAACF\nwfeQprZc7GB+4/iShWLuXOMhRliXDY95ajcNbe/rXcd212LnhzWT5cnH/PKuIoJJ\nq11XQLYzWLrHQL6a3KJk5OgexOC4e1zS9SMwzWhjTn0uHhf78cw=\n-----END RSA PRIVATE KEY-----",
"KeyName": "my-key-1",
"KeyPairId": "key-0a03c7b0023c36336"
}
key pair
를 생성하면 위와 같은 결과가 나오는데, KeyMaterial
의 값을 복사하여 텍스트 파일로 저장해야 한다.
이 파일은 ec2 생성 시에는 필요없고, ec2에 접속할 때 필요하다. 보통 파일 확장자는 pem
을 사용하므로 아래 파일명을 추천한다.
my-key-1.pem
Key pair 조회
팀 내에서 누군가, 혹은 자신이 이전에 만들어 놓은 key pair 목록을 조회할 수 있다.
단, key pair
이름만 확인 가능하기 때문에 ec2 생성시 참조할 수만 있고 실제로 해당 key pair를 사용하여 접속하려면 key 파일을 공유 받아야 한다.
~$ aws ec2 describe-key-pairs --output json
{
"KeyPairs": [
{
"KeyPairId": "key-0a03c7b0023c36336",
"KeyFingerprint": "77:b5:c0:02:bb:40:77:8a:e7:75:f6:be:85:1a:74:c2:74:46:c8:75",
"KeyName": "my-key-1",
"Tags": []
}
]
}
Machine 구입 및 부팅
~$ aws ec2 run-instances \
--image-id ami-06e83aceba2cb0907 \
--instance-type t3a.nano \
--block-device-mappings 'DeviceName=/dev/sda1,Ebs={DeleteOnTermination=true,VolumeSize=30,VolumeType=gp3}' \
--key-name my-key-1 \
--tag-specifications \
'ResourceType=instance,Tags=[{Key=Name,Value=my-test-ec2-1}]' \
'ResourceType=volume,Tags=[{Key=Name,Value=my-test-ec2-1}]'
마지막으로 우리가 생성할 EC2에 이름을 붙여주자. (Tag를 붙이자.)
Tag 안붙이면 기억하기도/알아보기도 어려운 InstanceId 를 사용해야 한다. 위 명령어의 마지막 3줄이 Tag를 붙이는 내용이다.
혹시 EC2 생성 시 Disk도 별도로 생성되고 관리된다고 위에서 말한 것을 기억하는가?(여기)
ResourceType instance
는 EC2에 Tag를 붙이는 설정이고 ResourceType volume
은 같이 생성된 Disk에 Tag를 붙이는 설정이다.
정상적으로 EC2가 생성되면 아래와 같은 응답을 볼 수 있다. 방금 생성한 EC2의 상세 정보다.
{
"Reservations": [
{
"Groups": [],
"Instances": [
{
"AmiLaunchIndex": 0,
"ImageId": "ami-06e83aceba2cb0907",
"InstanceId": "i-11111111111111111",
"InstanceType": "t3a.nano",
"KeyName": "my-key-1",
"LaunchTime": "2021-10-11T14:33:16+00:00",
"Monitoring": {
"State": "disabled"
},
"Placement": {
"AvailabilityZone": "ap-northeast-2c",
"GroupName": "",
"Tenancy": "default"
},
"PrivateDnsName": "ip-172-31-36-48.ap-northeast-2.compute.internal",
"PrivateIpAddress": "172.31.36.48",
"ProductCodes": [
{
"ProductCodeId": "aw0evgkw8e5c1q413zgy5pjce",
"ProductCodeType": "marketplace"
}
],
"PublicDnsName": "ec2-3-35-9-186.ap-northeast-2.compute.amazonaws.com",
"PublicIpAddress": "3.35.9.186",
"State": {
"Code": 16,
"Name": "running"
},
"StateTransitionReason": "",
"SubnetId": "subnet-11111111",
"VpcId": "vpc-11111111",
"Architecture": "x86_64",
"BlockDeviceMappings": [
{
"DeviceName": "/dev/sda1",
"Ebs": {
"AttachTime": "2021-10-11T14:33:17+00:00",
"DeleteOnTermination": true,
"Status": "attached",
"VolumeId": "vol-11111111111111111"
}
}
],
"ClientToken": "11111111-1111-1111-1111-111111111111",
"EbsOptimized": false,
"EnaSupport": true,
"Hypervisor": "xen",
"NetworkInterfaces": [
{
"Association": {
"IpOwnerId": "amazon",
"PublicDnsName": "ec2-3-35-9-186.ap-northeast-2.compute.amazonaws.com",
"PublicIp": "3.35.9.186"
},
"Attachment": {
"AttachTime": "2021-10-11T14:33:16+00:00",
"AttachmentId": "eni-attach-0d6ec68abde7b0739",
"DeleteOnTermination": true,
"DeviceIndex": 0,
"Status": "attached",
"NetworkCardIndex": 0
},
"Description": "",
"Groups": [
{
"GroupName": "default",
"GroupId": "sg-11111111"
}
],
"Ipv6Addresses": [],
"MacAddress": "0a:2c:b4:1c:2c:e2",
"NetworkInterfaceId": "eni-11111111111111111",
"OwnerId": "111111111111",
"PrivateDnsName": "ip-172-31-36-48.ap-northeast-2.compute.internal",
"PrivateIpAddress": "172.31.36.48",
"PrivateIpAddresses": [
{
"Association": {
"IpOwnerId": "amazon",
"PublicDnsName": "ec2-3-35-9-186.ap-northeast-2.compute.amazonaws.com",
"PublicIp": "3.35.9.186"
},
"Primary": true,
"PrivateDnsName": "ip-172-31-36-48.ap-northeast-2.compute.internal",
"PrivateIpAddress": "172.31.36.48"
}
],
"SourceDestCheck": true,
"Status": "in-use",
"SubnetId": "subnet-11111111",
"VpcId": "vpc-11111111",
"InterfaceType": "interface"
}
],
"RootDeviceName": "/dev/sda1",
"RootDeviceType": "ebs",
"SecurityGroups": [
{
"GroupName": "default",
"GroupId": "sg-11111111"
}
],
"SourceDestCheck": true,
"Tags": [
{
"Key": "Name",
"Value": "my-test-ec2-1"
}
],
"VirtualizationType": "hvm",
"CpuOptions": {
"CoreCount": 1,
"ThreadsPerCore": 2
},
"CapacityReservationSpecification": {
"CapacityReservationPreference": "open"
},
"HibernationOptions": {
"Configured": false
},
"MetadataOptions": {
"State": "applied",
"HttpTokens": "optional",
"HttpPutResponseHopLimit": 1,
"HttpEndpoint": "enabled"
},
"EnclaveOptions": {
"Enabled": false
}
}
],
"OwnerId": "111111111111",
"ReservationId": "r-11111111111111111"
}
]
}
이 정보를 적어둘 필요는 없다. 언제든 다시 조회 가능하다. (여기 참조)
여기서 지금 우리에게 필요한 값이 몇 가지 있다. 우선 EC2의 Public IP가 필요하다. IP를 알아야 접속을 할 수 있기 때문이다.
"PublicIpAddress": "3.35.16.146"
이제 해당 IP로 접속해보자.
- IP : 3.35.9.186
- 계정명 : centos
- CentOS AMI의 기본 계정은
centos
이다. - AMI마다 기본 계정이 다르기 때문에 다른 AMI를 사용한다면 AMI 상세 설명 페이지를 잘 살펴보자.
- CentOS AMI의 기본 계정은
- key 파일 : my-key-1.pem
- 위에서도 언급했지만, CentOS AMI는 ID/Password 접속을 허용하지 않기 때문에 EC2 생성 시 사용했던 key pair파일을 이용하여 접속해야 한다.
- 혹시 처음 보는 느낌이 든다면 이 부분을 다시 읽어보자.
~$ ssh -i my-key-1.pem centos@3.35.9.186
접속이 안된다. 왜일까?
Security Group
우리가 생성한 EC2는 Public IP를 갖고 있다. Public IP, 즉 전 세계 어디서든 인터넷만 되면 접속할 수 있다는 얘기다. 악의적인 목적을 가진 누군가가 서버에 접속할 수는 없지만(key pair파일이 없기때문에), 접속하지 않고도 서버를 비정상적으로 만들수는 있다. (ex: DDos 공격 ) 때문에 AWS에서도 기본적으로 모든 접속이 차단되어 있다. 이 설정을 조금 수정해야 접속할 수 있다.
EC2 생성 응답을 다시 한번 살펴보자. SecurityGroups
부분이 우리가 필요한 정보다.
{ "SecurityGroups": [
{
"GroupName": "default",
"GroupId": "sg-11111111"
}
]}
AWS에서는 Security Group이라는 방화벽 설정이 존재한다. EC2 생성 시 Security Group을 설정하지 않으면 default
Security Group이 적용된다.
default
Security Group은 아무런 설정도 되어 있지 않기 때문에 모든 네트워크 트래픽이 차단된다. 아래 명령어로 확인해보자.
~$ aws ec2 describe-security-groups --group-ids sg-11111111
{
"SecurityGroups": [
{
"Description": "default VPC security group",
"GroupName": "default",
"IpPermissions": [
{
"IpProtocol": "-1",
"IpRanges": [],
"Ipv6Ranges": [],
"PrefixListIds": [],
"UserIdGroupPairs": [
{
"GroupId": "sg-11111111",
"UserId": "111111111111"
}
]
}
],
"OwnerId": "111111111111",
"GroupId": "sg-11111111",
"IpPermissionsEgress": [
{
"IpProtocol": "-1",
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"Ipv6Ranges": [],
"PrefixListIds": [],
"UserIdGroupPairs": []
}
],
"Tags": [
{
"Key": "Name",
"Value": "default"
}
],
"VpcId": "vpc-11111111"
}
]
}
자, 여기서 선택지는 2가지다.
default
Security Group에 22번 포트(ssh 접속 시 사용하는) open- 새 Security Group 생성 후 EC2에 attach
1.
방법은 권장하지 않는다.
이유는 위에도 설명했듯이 Security Group을 설정하지 않고 EC2를 생성하면 default
Security Group이 자동으로 적용되기 때문이다.
즉, 잘못하다간 의도치 않게 모든 EC2의 22번 포트를 open하게 된다. (의도치 않게
가 포인트다.)
좀 더 강력한 보안을 유지하기 위해 아래 2가지를 명심하자.
- 명확하게 권한을 설정한다. 묵시적인 설정은 하지 않는다.
- 필요한 권한만 설정한다.
EC2는 여러 개의 Security Group을 적용할 수 있기 때문에 ssh 접속을 위한 Security Group을 생성한 후 EC2에 attach하자.
Security Group을 생성하기 위해서는 EC2의 VPC
ID를 알아야 한다.
VPC
란 Virtual Private Cloud의 약자로 네트워크에서 나만의 영역을 정의한다고 이해하자. 일단 지금은 이정도만 알고 넘어가자.
VPC ID 또한 EC2 상세 정보에 포함되어 있다. 가장 하단에 VpcId
부분이 우리가 필요한 정보다.
aws ec2 create-security-group \
--group-name ssh-from-anywhere \
--description "ssh-from-anywhere" \
--vpc-id vpc-11111111
{
"GroupId": "sg-22222222222222222"
}
생성된 Security Group의 22번 포트를 open 하자.
~$ aws ec2 authorize-security-group-ingress \
--group-id sg-22222222222222222 \
--protocol tcp --port 22 --cidr 0.0.0.0/0
그리고 해당 Security Group을 EC2에 attach 하자. 단, 주의할 점은 아래 명령어 실행 시 Security Group을 추가하는게 아니라 기존 Security Group 설정을 덮어써버리므로 기존에 적용되어 있던 Security Group ID도 같이 명시해줘야 한다.
~$ aws ec2 modify-instance-attribute \
--instance-id i-11111111111111111 \
--groups sg-11111111 sg-22222222222222222
그리고 다시 접속 시도를 하면 정상적으로 접속되는 것을 확인할 수 있다.
~$ ssh -i my-key-1.pem centos@3.35.9.186
마치며
CLI는 명령어가 매우 많고 복잡하기 때문에 절대 외우려 해서는 안된다. 대신, 반복적인 작업을 좀 더 간편하게 (혹은 자동으로) 하기 위해 활용하는 것을 추천한다.
이 글에서는 매우 기본적인 EC2 생성 옵션에 대해서만 다뤘는데, EC2 생성 옵션은 상당히 많은 편이다. 그 옵션을 모두 알 필요는 없다. 필요할 때 찾아서 사용할 수만 있으면 된다. 그러기 위해서는 큰 그림과 개념(EC2에 대한)에 대한 이해가 먼저다.
AWS 서비스는 결국 기존에 우리가 물리적인 서버를 구입해서 해왔던 대부분의 일을 AWS에서 처리해주고, 꼭 필요한 부분만 사용자에게 오픈하는 컨셉이라고 생각하면 좀 더 이해하기 쉽다.
EC2는 AWS 서비스 중 상당히 많은 부분을 사용자에게 오픈한 편이고, Lambda
와 같은 서비스는 EC2 생성과 관리 또한 AWS에서 알아서 하기 때문에 사용자는 프로그램 소스 코드만 AWS에 업로드 하는 방식의 서비스인 식이다.
AWS CLI EC2 Cheat sheet
EC2 목록 확인
~$ aws ec2 describe-instances --output table \
--query 'Reservations[].Instances[].[Tags[?Key==`Name`].Value|[0],InstanceId,InstanceType,State.Name,VpcId,PrivateIpAddress,PublicIpAddress,Placement.AvailabilityZone,KeyName]'
--------------------------------------------------------------------------------------------------------------------------------------------
| DescribeInstances |
+--------+----------------------+--------------+----------+---------------+----------------+--------------+-------------------+------------+
| None | i-11111111111111111 | t3a.nano | running | vpc-11111111 | 172.31.37.68 | 3.35.16.146 | ap-northeast-2c | my-key-1 |
+--------+----------------------+--------------+----------+---------------+----------------+--------------+-------------------+------------+
EC2 상세 정보 확인
~$ aws ec2 describe-instances --instance-ids i-11111111111111111
EC2 생성
~$ aws ec2 run-instances \
--image-id ami-06e83aceba2cb0907 \
--instance-type t3a.nano \
--block-device-mappings 'DeviceName=/dev/sda1,Ebs={DeleteOnTermination=true,VolumeSize=30,VolumeType=gp3}' \
--key-name my-key-1 \
--tag-specifications \
'ResourceType=instance,Tags=[{Key=Name,Value=my-test-ec2-1}]' \
'ResourceType=volume,Tags=[{Key=Name,Value=my-test-ec2-1}]'
EC2 Tag 생성
이미 생성되어 있는 EC2에 Tag를 추가하는 방법
~$ aws ec2 create-tags \
--resources i-11111111111111111 \
--tags Key=Name,Value=my-test-resource Key=Stage,Value=Production
Key Pair 생성
~$ aws ec2 create-key-pair --key-name ${KEY_NAME}
Security Group 생성 및 포트 설정
~$ aws ec2 create-security-group \
--group-name ssh-from-anywhere \
--description "ssh-from-anywhere" \
--vpc-id vpc-11111111
~$ aws ec2 authorize-security-group-ingress \
--group-id sg-22222222222222222 \
--protocol tcp --port 22 --cidr 0.0.0.0/0
EC2 Security Group Update
~$ aws ec2 create-tags \
--resources ami-1a2b3c4d i-1234567890abcdef0 \
--tags Key=webserver,Value= Key=stack,Value=Production
Security Group 삭제
~$ aws ec2 delete-security-group --group-id ${SECURITY_GROUP_ID}
Previous post
AWS CLI - 설치 및 기본 설정 방법Next post
컴퓨터는 이미지를 어떻게 저장하고 표현할까?