본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 19. · 7 Views
EC2 인스턴스 관리 완벽 가이드
AWS EC2 인스턴스의 상태 관리부터 타입 변경, EBS 볼륨 관리까지 실무에서 꼭 필요한 인스턴스 관리 방법을 배웁니다. 초급 개발자도 쉽게 따라할 수 있도록 실무 사례와 함께 설명합니다.
목차
1. 인스턴스 상태 관리
어느 날 김개발 씨는 회사의 AWS 콘솔을 처음 열어보았습니다. 화면에는 여러 개의 EC2 인스턴스가 보였고, 각각 "running", "stopped", "terminated" 같은 상태값이 표시되어 있었습니다.
선배 개발자 박시니어 씨가 다가와 말했습니다. "EC2 인스턴스의 상태를 제대로 관리하지 않으면 불필요한 비용이 발생할 수 있어요."
EC2 인스턴스의 상태 관리는 AWS 리소스를 효율적으로 운영하는 첫걸음입니다. 인스턴스는 pending, running, stopping, stopped, shutting-down, terminated 등 여러 상태를 가질 수 있습니다.
각 상태마다 과금 방식이 다르며, 적절한 상태 관리를 통해 비용을 최적화할 수 있습니다.
다음 코드를 살펴봅시다.
import boto3
# EC2 클라이언트 생성
ec2 = boto3.client('ec2', region_name='ap-northeast-2')
# 인스턴스 상태 확인
response = ec2.describe_instances(
InstanceIds=['i-1234567890abcdef0']
)
# 현재 상태 출력
for reservation in response['Reservations']:
for instance in reservation['Instances']:
instance_id = instance['InstanceId']
state = instance['State']['Name']
print(f"인스턴스 {instance_id}의 현재 상태: {state}")
김개발 씨는 입사 1주일 차 주니어 개발자입니다. 오늘 팀장님으로부터 "개발 서버는 평일 오전 9시부터 오후 6시까지만 켜두고, 나머지 시간에는 꺼두세요"라는 지시를 받았습니다.
비용 절감을 위해서라고 했습니다. 하지만 김개발 씨는 어떻게 인스턴스를 켜고 끄는지, 그리고 각 상태가 무엇을 의미하는지 잘 몰랐습니다.
박시니어 씨가 김개발 씨의 화면을 보며 설명을 시작했습니다. "EC2 인스턴스의 상태를 이해하는 건 정말 중요해요.
상태를 모르면 불필요한 비용이 계속 나갈 수 있거든요." EC2 인스턴스의 상태는 마치 컴퓨터의 전원 상태와 비슷합니다. 우리가 집에서 사용하는 컴퓨터도 켜져 있거나, 꺼져 있거나, 종료 중이거나 하는 상태가 있듯이, EC2 인스턴스도 명확한 상태값을 가집니다.
가장 기본적인 상태는 running입니다. 이 상태일 때 인스턴스는 정상적으로 작동하며, 당연히 과금이 됩니다.
마치 집에서 컴퓨터를 켜두고 사용하는 것과 같습니다. 전기 요금이 나가듯이, AWS 사용료가 시간당 부과됩니다.
다음은 stopped 상태입니다. 이것은 컴퓨터를 완전히 종료한 상태와 같습니다.
중요한 점은 stopped 상태에서는 컴퓨팅 비용이 발생하지 않는다는 것입니다. 하지만 완전히 무료는 아닙니다.
인스턴스에 연결된 EBS 볼륨에 대한 저장 비용은 계속 청구됩니다. pending 상태는 인스턴스가 막 시작되는 중간 단계입니다.
시작 명령을 내렸을 때 바로 running이 되는 것이 아니라, 잠깐 동안 pending 상태를 거칩니다. 보통 몇 초에서 1분 이내에 running으로 전환됩니다.
stopping 상태는 인스턴스를 중지하는 과정입니다. 중지 명령을 내리면 곧바로 stopped가 되는 것이 아니라, 운영체제가 안전하게 종료 절차를 밟는 동안 이 상태를 유지합니다.
마치 윈도우에서 "시스템 종료 중..." 메시지가 뜨는 것과 같습니다. shutting-down과 terminated 상태는 조금 다릅니다.
이것은 인스턴스를 영구적으로 삭제하는 과정입니다. stopped는 언제든 다시 켤 수 있지만, terminated는 완전히 삭제되어 다시 복구할 수 없습니다.
위의 코드를 살펴보겠습니다. boto3는 AWS의 공식 Python SDK입니다.
이를 통해 프로그래밍 방식으로 AWS 리소스를 관리할 수 있습니다. 먼저 ec2.describe_instances() 메서드를 호출합니다.
이것은 특정 인스턴스의 모든 정보를 가져오는 API입니다. InstanceIds 파라미터에 확인하고 싶은 인스턴스 ID를 넘겨주면, 해당 인스턴스의 상세 정보를 받을 수 있습니다.
응답 데이터는 중첩된 구조로 되어 있습니다. Reservations 안에 Instances가 있고, 그 안에 State 정보가 들어있습니다.
State는 다시 Name과 Code를 가지고 있는데, Name이 우리가 흔히 보는 "running", "stopped" 같은 문자열입니다. 실제 현업에서는 이런 상태 확인 코드를 어떻게 활용할까요?
예를 들어 개발팀에서 매일 아침 9시에 개발 서버를 자동으로 시작하고, 저녁 6시에 자동으로 중지하는 스크립트를 만들 수 있습니다. AWS Lambda와 CloudWatch Events를 조합하면 이런 자동화가 가능합니다.
또 다른 실무 사례로는 모니터링 시스템이 있습니다. 운영 중인 서버가 예상치 못하게 stopped 상태가 되면, 즉시 알림을 보내는 시스템을 구축할 수 있습니다.
이렇게 하면 서비스 장애를 빠르게 감지하고 대응할 수 있습니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 인스턴스를 stopped가 아닌 terminated로 만들어버리는 것입니다. terminated는 복구가 불가능하므로, 정말 삭제해도 되는 인스턴스인지 반드시 확인해야 합니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 "아, 그래서 stopped 상태로 두면 컴퓨팅 비용은 안 나가는군요!"라고 말했습니다.
이제 김개발 씨는 퇴근할 때마다 개발 서버를 stopped 상태로 만들어 회사 비용을 절감하는 데 기여할 수 있게 되었습니다. EC2 인스턴스의 상태를 제대로 이해하면 비용 최적화는 물론, 안정적인 서비스 운영이 가능해집니다.
여러분도 오늘 배운 내용을 바탕으로 인스턴스 상태를 주기적으로 확인하는 습관을 들여보세요.
실전 팁
💡 - stopped 상태에서는 컴퓨팅 비용이 발생하지 않지만, EBS 볼륨 저장 비용은 계속 청구됩니다.
- 인스턴스를 영구 삭제하기 전에는 반드시 중요한 데이터를 백업하세요.
- AWS CLI나 boto3를 사용하면 여러 인스턴스의 상태를 일괄적으로 확인하고 관리할 수 있습니다.
2. 시작 중지 종료 차이
김개발 씨는 AWS 콘솔에서 인스턴스를 마우스 오른쪽 버튼으로 클릭했습니다. 메뉴에 "중지", "재부팅", "종료" 세 가지 옵션이 보였습니다.
어느 것을 선택해야 할지 고민하던 중, 실수로 "종료"를 눌러버렸습니다. 그 순간 박시니어 씨가 외쳤습니다.
"잠깐! 그거 누르면 인스턴스가 완전히 삭제돼요!"
EC2 인스턴스의 중지, 재부팅, 종료는 각각 다른 의미를 가집니다. 중지는 인스턴스를 일시적으로 꺼두는 것이고, 재부팅은 운영체제를 다시 시작하는 것이며, 종료는 인스턴스를 영구적으로 삭제하는 것입니다.
이 세 가지를 명확히 구분하지 못하면 중요한 서버를 잃어버릴 수 있습니다.
다음 코드를 살펴봅시다.
import boto3
ec2 = boto3.client('ec2', region_name='ap-northeast-2')
instance_id = 'i-1234567890abcdef0'
# 인스턴스 중지 (Stop) - 다시 시작 가능
ec2.stop_instances(InstanceIds=[instance_id])
print(f"{instance_id} 중지 명령 실행")
# 인스턴스 시작 (Start) - 중지된 인스턴스를 다시 켬
ec2.start_instances(InstanceIds=[instance_id])
print(f"{instance_id} 시작 명령 실행")
# 인스턴스 재부팅 (Reboot) - 운영체제만 재시작
ec2.reboot_instances(InstanceIds=[instance_id])
print(f"{instance_id} 재부팅 명령 실행")
# 인스턴스 종료 (Terminate) - 영구 삭제, 복구 불가!
# ec2.terminate_instances(InstanceIds=[instance_id])
# print(f"{instance_id} 종료(삭제) 명령 실행")
김개발 씨의 손이 "종료" 버튼으로 향하는 순간, 다행히 박시니어 씨가 빠르게 제지했습니다. 식은땀을 흘린 김개발 씨는 "중지와 종료가 뭐가 다른가요?"라고 물었습니다.
이것은 정말 중요한 질문입니다. 많은 초보 개발자들이 "중지"와 "종료"를 혼동합니다.
이것은 마치 스마트폰의 "화면 끄기"와 "공장 초기화"를 헷갈리는 것과 같습니다. 화면을 끄는 것은 언제든 다시 켤 수 있지만, 공장 초기화를 하면 모든 데이터가 사라집니다.
**중지(Stop)**는 인스턴스를 일시적으로 꺼두는 것입니다. 컴퓨터의 전원을 끄는 것과 같습니다.
중요한 점은 인스턴스의 모든 데이터가 EBS 볼륨에 안전하게 보관된다는 것입니다. 언제든 다시 시작할 수 있고, 시작하면 중지하기 전의 상태 그대로 복원됩니다.
중지 상태에서는 인스턴스 사용료가 청구되지 않습니다. 단, EBS 볼륨 저장 비용은 계속 나갑니다.
이것은 마치 집을 비울 때 전기는 끄지만, 집세는 계속 내는 것과 비슷합니다. **재부팅(Reboot)**은 운영체제만 다시 시작하는 것입니다.
윈도우나 리눅스에서 재부팅하는 것과 완전히 동일합니다. 인스턴스는 계속 running 상태를 유지하며, 퍼블릭 IP나 프라이빗 IP도 변경되지 않습니다.
재부팅은 주로 소프트웨어 업데이트 후 설정을 적용하거나, 메모리 누수 문제를 해결하기 위해 사용합니다. 예를 들어 커널 업데이트를 했다면, 새로운 커널을 적용하기 위해 재부팅이 필요합니다.
**종료(Terminate)**는 인스턴스를 영구적으로 삭제하는 것입니다. 이것은 되돌릴 수 없는 작업입니다.
종료된 인스턴스는 완전히 사라지며, 연결된 EBS 볼륨도 함께 삭제됩니다(단, 삭제 방지 옵션을 설정한 볼륨은 제외). 종료는 정말 조심해야 하는 작업입니다.
실수로 운영 서버를 종료하면 서비스가 중단될 뿐만 아니라, 데이터까지 모두 잃을 수 있습니다. 그래서 중요한 인스턴스에는 "종료 방지(Termination Protection)" 옵션을 켜두는 것이 좋습니다.
위의 코드를 살펴보겠습니다. stop_instances() 메서드는 인스턴스를 중지합니다.
이 명령을 실행하면 인스턴스는 stopping 상태를 거쳐 stopped 상태가 됩니다. 보통 30초에서 1분 정도 소요됩니다.
start_instances() 메서드는 중지된 인스턴스를 다시 시작합니다. 중요한 점은 중지 후 다시 시작하면 퍼블릭 IP 주소가 변경될 수 있다는 것입니다.
고정 IP가 필요하다면 Elastic IP를 사용해야 합니다. reboot_instances() 메서드는 인스턴스를 재부팅합니다.
이것은 SSH로 접속해서 sudo reboot 명령을 실행하는 것과 거의 동일합니다. 재부팅 중에는 잠깐 동안 서비스가 중단되지만, IP 주소는 변경되지 않습니다.
terminate_instances() 메서드는 주석 처리되어 있습니다. 이것은 정말 조심해야 하는 명령이기 때문입니다.
실무에서는 이 명령을 실행하기 전에 반드시 확인 절차를 거칩니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 개발 환경에서는 퇴근 시간에 모든 인스턴스를 중지하고, 출근 시간에 다시 시작하는 자동화 스크립트를 만듭니다. 이렇게 하면 매달 수백 달러의 비용을 절감할 수 있습니다.
운영 환경에서는 재부팅을 사용합니다. 예를 들어 매달 둘째 주 일요일 새벽 3시에 보안 패치를 적용하고 자동으로 재부팅하는 일정을 만들 수 있습니다.
서비스 이용자가 적은 시간대를 선택하면 영향을 최소화할 수 있습니다. 초보 개발자들이 흔히 하는 실수는 중지와 종료를 헷갈리는 것입니다.
특히 AWS 콘솔의 영문 버전에서는 Stop과 Terminate를 구분하지 못해 실수하는 경우가 많습니다. 중요한 인스턴스는 반드시 종료 방지 옵션을 활성화해두세요.
김개발 씨는 박시니어 씨의 설명을 듣고 깊은 한숨을 내쉬었습니다. "휴, 다행히 종료를 누르지 않았네요.
앞으로는 정말 조심해야겠어요." 박시니어 씨가 웃으며 말했습니다. "맞아요.
AWS에서는 한 번의 클릭이 큰 사고로 이어질 수 있으니까요." 중지, 재부팅, 종료의 차이를 명확히 이해하면 실수를 방지하고 안전하게 인스턴스를 관리할 수 있습니다. 여러분도 중요한 작업을 할 때는 항상 한 번 더 확인하는 습관을 들이세요.
실전 팁
💡 - 중요한 인스턴스에는 반드시 종료 방지 옵션을 활성화하세요.
- 중지 후 재시작하면 퍼블릭 IP가 변경될 수 있으므로, 고정 IP가 필요하면 Elastic IP를 사용하세요.
- 재부팅은 서비스 이용이 적은 시간대에 수행하는 것이 좋습니다.
3. 인스턴스 타입 변경
서비스를 오픈한 지 3개월이 지났습니다. 김개발 씨는 CloudWatch 모니터링 화면을 보며 고민에 빠졌습니다.
CPU 사용률이 평균 5% 미만인데, 현재 사용 중인 t3.large 인스턴스는 과한 것 같았습니다. 박시니어 씨가 조언했습니다.
"인스턴스 타입을 변경하면 비용을 절감할 수 있어요."
EC2 인스턴스 타입은 CPU, 메모리, 네트워크, 스토리지 성능을 결정합니다. 서비스의 부하에 따라 적절한 타입을 선택해야 하며, 필요시 언제든 타입을 변경할 수 있습니다.
t3.micro부터 r7g.16xlarge까지 다양한 타입이 있으며, 각각의 용도가 다릅니다.
다음 코드를 살펴봅시다.
import boto3
ec2 = boto3.client('ec2', region_name='ap-northeast-2')
instance_id = 'i-1234567890abcdef0'
# 1단계: 인스턴스 중지
print("인스턴스 중지 중...")
ec2.stop_instances(InstanceIds=[instance_id])
# 중지 완료 대기
waiter = ec2.get_waiter('instance_stopped')
waiter.wait(InstanceIds=[instance_id])
print("인스턴스 중지 완료")
# 2단계: 인스턴스 타입 변경
print("인스턴스 타입 변경 중...")
ec2.modify_instance_attribute(
InstanceId=instance_id,
InstanceType={'Value': 't3.small'}
)
print("인스턴스 타입이 t3.small로 변경되었습니다")
# 3단계: 인스턴스 시작
print("인스턴스 시작 중...")
ec2.start_instances(InstanceIds=[instance_id])
print("인스턴스 타입 변경 완료!")
김개발 씨는 매달 나오는 AWS 청구서를 보며 걱정이 많았습니다. 예상보다 비용이 많이 나오는 것 같았습니다.
특히 EC2 인스턴스 비용이 전체의 70%를 차지했습니다. 뭔가 잘못되었다는 생각이 들었습니다.
박시니어 씨가 CloudWatch 메트릭을 함께 살펴보며 말했습니다. "봐요, CPU 사용률이 평균 5%밖에 안 돼요.
메모리도 30%만 사용하고 있고요. 이건 명백히 오버스펙입니다." 인스턴스 타입 선택은 마치 집을 고르는 것과 같습니다.
혼자 사는데 방 10개짜리 대저택을 빌리면 불필요한 비용이 들듯이, 서비스 부하에 비해 너무 큰 인스턴스를 사용하면 돈을 낭비하게 됩니다. 반대로 너무 작은 인스턴스를 사용하면 성능 문제가 발생할 수 있습니다.
EC2 인스턴스 타입은 크게 몇 가지 패밀리로 나뉩니다. T 시리즈는 범용 인스턴스로, 평소에는 낮은 CPU를 사용하다가 필요할 때 버스트 성능을 발휘합니다.
웹 서버, 개발 환경, 소규모 데이터베이스에 적합합니다. M 시리즈는 균형 잡힌 컴퓨팅, 메모리, 네트워크 리소스를 제공합니다.
중소 규모의 데이터베이스, 데이터 처리 작업, 백엔드 서버에 자주 사용됩니다. 가장 범용적인 용도로 사용할 수 있습니다.
C 시리즈는 컴퓨팅 집약적인 워크로드에 최적화되어 있습니다. 고성능 웹 서버, 배치 처리, 머신러닝 추론 등 CPU를 많이 사용하는 작업에 적합합니다.
R 시리즈는 메모리 집약적인 애플리케이션을 위한 타입입니다. 대용량 인메모리 데이터베이스, 빅데이터 분석, 캐시 서버 등에 사용됩니다.
같은 가격 대비 메모리가 다른 타입보다 훨씬 많습니다. 인스턴스 타입을 변경하는 것은 생각보다 간단합니다.
하지만 한 가지 제약이 있습니다. 반드시 인스턴스를 중지한 상태에서만 타입을 변경할 수 있다는 것입니다.
실행 중인 인스턴스의 타입은 변경할 수 없습니다. 위의 코드를 단계별로 살펴보겠습니다.
먼저 stop_instances() 메서드로 인스턴스를 중지합니다. 그런 다음 waiter 객체를 사용해서 중지가 완료될 때까지 기다립니다.
이 부분이 중요합니다. 중지가 완료되지 않은 상태에서 타입을 변경하려고 하면 에러가 발생합니다.
인스턴스가 완전히 중지되면 modify_instance_attribute() 메서드를 호출합니다. InstanceType 파라미터에 변경하고 싶은 타입을 지정합니다.
이 예제에서는 t3.small로 변경했습니다. 타입 변경은 거의 즉시 완료됩니다.
마지막으로 start_instances() 메서드로 인스턴스를 다시 시작합니다. 인스턴스가 부팅되면 새로운 타입의 리소스로 작동하게 됩니다.
전체 과정은 보통 2-3분 정도 소요됩니다. 실제 현업에서는 어떻게 활용할까요?
많은 기업들이 정기적으로 인스턴스 사용률을 모니터링합니다. 예를 들어 분기마다 CloudWatch 메트릭을 분석해서 오버스펙인 인스턴스를 찾아냅니다.
그리고 야간이나 주말처럼 서비스 이용이 적은 시간에 타입을 변경합니다. 또 다른 사례로는 이벤트 대응이 있습니다.
예를 들어 온라인 쇼핑몰에서 블랙프라이데이 같은 대규모 이벤트를 앞두고 있다면, 평소보다 큰 인스턴스 타입으로 미리 변경해둡니다. 이벤트가 끝나면 다시 원래 크기로 되돌립니다.
주의할 점도 있습니다. 인스턴스 타입을 변경할 때는 서비스가 잠시 중단된다는 것을 기억해야 합니다.
따라서 운영 환경에서는 반드시 점검 시간을 공지하고 변경해야 합니다. 또한 모든 타입 간 변경이 가능한 것은 아닙니다.
예를 들어 Nitro 기반 인스턴스에서 Xen 기반 인스턴스로는 변경할 수 없습니다. 김개발 씨는 박시니어 씨의 도움으로 개발 서버를 t3.large에서 t3.small로 변경했습니다.
다음 달 청구서를 확인해보니 EC2 비용이 약 50% 감소했습니다. "와, 이렇게 간단한 작업으로 이만큼 절감할 수 있다니!" 김개발 씨는 감탄했습니다.
인스턴스 타입을 적절히 선택하고 주기적으로 검토하면 비용을 크게 절감할 수 있습니다. 여러분도 현재 사용 중인 인스턴스의 CPU, 메모리 사용률을 확인해보세요.
최적화할 여지가 분명히 있을 것입니다.
실전 팁
💡 - CloudWatch에서 CPU, 메모리, 네트워크 사용률을 주기적으로 모니터링하세요.
- 프로덕션 환경에서 타입 변경 시에는 반드시 점검 시간을 공지하세요.
- AWS Compute Optimizer를 사용하면 자동으로 최적의 인스턴스 타입을 추천받을 수 있습니다.
4. EBS 볼륨 이해
김개발 씨는 인스턴스를 중지했다가 다시 시작했는데, 신기하게도 모든 파일이 그대로 남아있었습니다. "인스턴스를 껐다 켰는데 왜 데이터가 사라지지 않죠?" 박시니어 씨가 웃으며 설명했습니다.
"그건 EBS 볼륨 덕분이에요. EC2 인스턴스의 영구 저장소라고 생각하면 됩니다."
EBS는 Elastic Block Store의 약자로, EC2 인스턴스에 연결되는 블록 수준의 저장 장치입니다. 마치 컴퓨터의 하드디스크나 SSD처럼 작동하며, 인스턴스가 중지되어도 데이터가 보존됩니다.
gp3, io2, st1 등 여러 볼륨 타입이 있으며, 각각 성능과 가격이 다릅니다.
다음 코드를 살펴봅시다.
import boto3
ec2 = boto3.client('ec2', region_name='ap-northeast-2')
# 인스턴스에 연결된 EBS 볼륨 확인
response = ec2.describe_instances(
InstanceIds=['i-1234567890abcdef0']
)
for reservation in response['Reservations']:
for instance in reservation['Instances']:
print(f"인스턴스 ID: {instance['InstanceId']}")
# 블록 디바이스 매핑 정보 출력
for device in instance['BlockDeviceMappings']:
device_name = device['DeviceName']
volume_id = device['Ebs']['VolumeId']
# 볼륨 상세 정보 조회
volume = ec2.describe_volumes(VolumeIds=[volume_id])
vol_info = volume['Volumes'][0]
print(f" 디바이스: {device_name}")
print(f" 볼륨 ID: {volume_id}")
print(f" 크기: {vol_info['Size']}GB")
print(f" 타입: {vol_info['VolumeType']}")
print(f" 상태: {vol_info['State']}")
김개발 씨는 처음에 큰 오해를 하고 있었습니다. EC2 인스턴스를 중지하면 모든 데이터가 사라질 것이라고 생각했습니다.
그래서 퇴근할 때마다 중요한 파일을 S3에 백업했습니다. 하지만 이것은 불필요한 작업이었습니다.
박시니어 씨가 설명했습니다. "EC2 인스턴스는 두 종류의 스토리지를 가질 수 있어요.
하나는 Instance Store이고, 다른 하나는 EBS 볼륨입니다." EBS를 이해하려면 먼저 컴퓨터의 저장 장치를 떠올려보세요. 우리가 사용하는 컴퓨터에는 HDD나 SSD가 장착되어 있습니다.
컴퓨터를 껐다 켜도 파일이 사라지지 않는 이유는 이런 영구 저장 장치가 있기 때문입니다. EBS는 바로 이것과 같은 역할을 합니다.
EBS 볼륨은 네트워크로 연결되는 가상 디스크입니다. 물리적으로는 EC2 인스턴스와 분리되어 있지만, 논리적으로는 연결되어 있습니다.
마치 USB 외장하드를 컴퓨터에 꽂은 것과 비슷합니다. 언제든 뺐다가 다른 인스턴스에 꽂을 수 있습니다.
EBS의 가장 큰 장점은 데이터 영속성입니다. 인스턴스를 중지하거나 재부팅해도 EBS 볼륨의 데이터는 그대로 유지됩니다.
심지어 인스턴스를 종료하더라도, 볼륨 삭제 옵션을 끄면 EBS 볼륨은 살아남습니다. EBS 볼륨에는 여러 타입이 있습니다.
gp3(General Purpose SSD)는 가장 많이 사용되는 타입입니다. 비용 대비 성능이 우수하며, 대부분의 워크로드에 적합합니다.
기본 성능도 충분하고, 필요시 IOPS와 처리량을 독립적으로 조정할 수 있습니다. io2(Provisioned IOPS SSD)는 고성능이 필요한 데이터베이스나 중요한 애플리케이션에 사용됩니다.
IOPS를 매우 높게 설정할 수 있어서, 초당 수만 번의 I/O 작업을 처리할 수 있습니다. 당연히 비용도 gp3보다 훨씬 비쌉니다.
st1(Throughput Optimized HDD)은 대용량 순차 읽기/쓰기에 최적화되어 있습니다. 빅데이터 분석, 로그 처리, 데이터 웨어하우스 등에 적합합니다.
SSD보다 느리지만, GB당 비용이 저렴합니다. 위의 코드를 살펴보겠습니다.
describe_instances() 메서드로 인스턴스 정보를 가져온 후, BlockDeviceMappings 항목을 확인합니다. 이것은 인스턴스에 연결된 모든 블록 디바이스(디스크)의 목록입니다.
각 블록 디바이스는 DeviceName과 VolumeId를 가지고 있습니다. DeviceName은 리눅스에서 보이는 디바이스 이름입니다.
예를 들어 /dev/xvda는 루트 볼륨을 의미합니다. VolumeId를 사용해서 describe_volumes() 메서드를 호출하면 볼륨의 상세 정보를 얻을 수 있습니다.
크기, 타입, IOPS, 암호화 여부 등 모든 정보가 포함되어 있습니다. 실제 현업에서는 EBS 볼륨을 어떻게 활용할까요?
가장 일반적인 사례는 데이터베이스 서버입니다. MySQL이나 PostgreSQL 같은 데이터베이스는 디스크 I/O 성능이 중요합니다.
따라서 데이터베이스 서버에는 io2 타입의 EBS 볼륨을 사용하는 경우가 많습니다. 또 다른 사례는 로그 수집 서버입니다.
로그는 순차적으로 쓰이는 경우가 많으므로, 저렴한 st1 타입을 사용해도 충분합니다. 이렇게 워크로드 특성에 맞춰 적절한 볼륨 타입을 선택하면 비용을 최적화할 수 있습니다.
주의할 점도 있습니다. EBS 볼륨은 같은 가용 영역(AZ) 내에서만 인스턴스에 연결할 수 있습니다.
예를 들어 ap-northeast-2a 영역의 볼륨은 ap-northeast-2c 영역의 인스턴스에 직접 연결할 수 없습니다. 다른 영역으로 옮기려면 스냅샷을 생성하고 복원해야 합니다.
또한 EBS 볼륨은 한 번에 하나의 인스턴스에만 연결할 수 있습니다(다중 연결을 지원하는 io2 제외). 마치 USB 드라이브를 여러 컴퓨터에 동시에 꽂을 수 없는 것과 같습니다.
김개발 씨는 박시니어 씨의 설명을 듣고 안도의 한숨을 내쉬었습니다. "그럼 매일 S3에 백업할 필요가 없었네요?" 박시니어 씨가 고개를 저었습니다.
"아니요, 백업은 여전히 중요해요. EBS 볼륨도 장애가 날 수 있으니까요.
다만 인스턴스를 껐다 켜는 것 때문에 데이터가 사라지지는 않는다는 거죠." EBS 볼륨을 제대로 이해하면 안정적이고 효율적인 스토리지 전략을 수립할 수 있습니다. 여러분도 현재 사용 중인 볼륨의 타입과 성능을 확인해보세요.
최적화할 여지가 있을 것입니다.
실전 팁
💡 - 대부분의 경우 gp3 볼륨이면 충분하며, 비용 대비 성능이 우수합니다.
- 중요한 데이터는 EBS 볼륨 암호화 옵션을 활성화하세요.
- EBS 볼륨은 같은 가용 영역 내에서만 인스턴스에 연결할 수 있습니다.
5. 스토리지 추가 확장
서비스가 성장하면서 로그 파일이 점점 쌓였습니다. 어느 날 김개발 씨는 "디스크 공간 부족" 경고를 받았습니다.
당황한 김개발 씨는 박시니어 씨에게 달려갔습니다. "인스턴스를 새로 만들어야 하나요?" 박시니어 씨가 웃으며 말했습니다.
"아니요, EBS 볼륨 크기를 늘리거나 새 볼륨을 추가하면 됩니다."
EC2 인스턴스의 스토리지가 부족할 때는 두 가지 방법이 있습니다. 기존 EBS 볼륨의 크기를 확장하거나, 새로운 EBS 볼륨을 추가로 연결하는 것입니다.
볼륨 크기 확장은 인스턴스를 중지하지 않고도 가능하며, 추가 볼륨 연결도 실행 중에 할 수 있습니다.
다음 코드를 살펴봅시다.
import boto3
ec2 = boto3.client('ec2', region_name='ap-northeast-2')
# 방법 1: 기존 볼륨 크기 확장
volume_id = 'vol-1234567890abcdef0'
# 볼륨 크기를 100GB로 확장
response = ec2.modify_volume(
VolumeId=volume_id,
Size=100 # 새로운 크기 (GB)
)
print(f"볼륨 {volume_id} 크기 확장 시작")
# 방법 2: 새 볼륨 생성 및 연결
new_volume = ec2.create_volume(
AvailabilityZone='ap-northeast-2a',
Size=50, # 50GB
VolumeType='gp3'
)
new_volume_id = new_volume['VolumeId']
print(f"새 볼륨 생성: {new_volume_id}")
# 볼륨이 available 상태가 될 때까지 대기
waiter = ec2.get_waiter('volume_available')
waiter.wait(VolumeIds=[new_volume_id])
# 인스턴스에 볼륨 연결
ec2.attach_volume(
VolumeId=new_volume_id,
InstanceId='i-1234567890abcdef0',
Device='/dev/sdf'
)
print(f"볼륨 {new_volume_id}를 인스턴스에 연결 완료")
김개발 씨는 처음 스토리지 부족 경고를 받았을 때 정말 당황했습니다. 온프레미스 환경에서는 디스크 공간이 부족하면 새 하드디스크를 구매해서 물리적으로 장착해야 했습니다.
시간도 오래 걸리고 서버도 중지해야 했습니다. 하지만 AWS에서는 상황이 완전히 다릅니다.
박시니어 씨가 설명했습니다. "클라우드의 장점 중 하나가 바로 이거예요.
몇 번의 클릭만으로 스토리지를 늘릴 수 있어요." 스토리지를 늘리는 방법은 크게 두 가지입니다. 첫 번째는 기존 볼륨 확장이고, 두 번째는 새 볼륨 추가입니다.
이것은 마치 컴퓨터의 하드디스크 용량을 늘리는 것과 외장하드를 추가로 연결하는 것의 차이와 같습니다. 기존 볼륨을 확장하는 것이 일반적으로 더 간단합니다.
루트 볼륨처럼 이미 사용 중인 볼륨의 공간이 부족할 때 사용합니다. 놀라운 점은 인스턴스를 중지하지 않고도 볼륨을 확장할 수 있다는 것입니다.
서비스 중단 없이 작업할 수 있습니다. 볼륨 확장 작업은 두 단계로 이루어집니다.
먼저 AWS 콘솔이나 API를 통해 볼륨 크기를 늘립니다. 예를 들어 50GB 볼륨을 100GB로 늘리는 것입니다.
이 작업은 보통 몇 분 내에 완료됩니다. 하지만 여기서 끝이 아닙니다.
볼륨 크기는 늘어났지만, 운영체제는 아직 이것을 인식하지 못합니다. 따라서 운영체제 레벨에서 파일시스템을 확장해야 합니다.
리눅스에서는 growpart와 resize2fs 명령어를 사용합니다. 새 볼륨을 추가하는 방법도 있습니다.
이것은 별도의 저장 공간이 필요할 때 유용합니다. 예를 들어 데이터베이스 데이터는 별도 볼륨에, 로그 파일은 또 다른 볼륨에 저장하는 식입니다.
이렇게 하면 관리가 더 쉬워집니다. 위의 코드를 살펴보겠습니다.
modify_volume() 메서드는 기존 볼륨의 크기를 변경합니다. Size 파라미터에 새로운 크기를 GB 단위로 지정합니다.
중요한 점은 크기를 줄일 수는 없다는 것입니다. 50GB를 100GB로 늘릴 수는 있지만, 100GB를 50GB로 줄일 수는 없습니다.
create_volume() 메서드는 새로운 EBS 볼륨을 생성합니다. AvailabilityZone은 반드시 인스턴스와 같은 영역이어야 합니다.
그렇지 않으면 연결할 수 없습니다. 볼륨이 생성되면 waiter를 사용해서 available 상태가 될 때까지 기다립니다.
마지막으로 attach_volume() 메서드로 볼륨을 인스턴스에 연결합니다. Device 파라미터는 리눅스에서 보이는 디바이스 이름입니다.
/dev/sdf로 지정하면, 실제로는 /dev/xvdf로 보일 수 있습니다. 이것은 가상화 계층의 특성입니다.
실제 현업에서는 어떻게 활용할까요? 많은 회사에서 모니터링 시스템을 구축합니다.
CloudWatch 알람을 설정해서 디스크 사용률이 80%를 넘으면 자동으로 알림을 받습니다. 그러면 담당자가 볼륨을 확장하거나 불필요한 파일을 정리합니다.
더 나아가 자동화도 가능합니다. Lambda 함수를 만들어서 디스크 사용률이 일정 수준을 넘으면 자동으로 볼륨을 확장하는 시스템을 구축할 수 있습니다.
이렇게 하면 사람이 개입하지 않아도 스토리지 문제를 해결할 수 있습니다. 주의할 점도 있습니다.
볼륨 확장 후에는 반드시 운영체제에서 파일시스템을 확장해야 합니다. 이 단계를 빼먹으면 볼륨 크기는 늘어났지만 실제 사용 가능한 공간은 그대로입니다.
리눅스에서는 lsblk 명령어로 디스크 크기를 확인하고, df -h 명령어로 파일시스템 크기를 확인할 수 있습니다. 또한 볼륨 확장에는 시간이 걸립니다.
작은 볼륨은 몇 분이면 되지만, 수 테라바이트 크기의 볼륨은 몇 시간이 걸릴 수 있습니다. 확장 중에도 볼륨을 사용할 수 있지만, 성능이 일시적으로 저하될 수 있습니다.
김개발 씨는 박시니어 씨의 도움으로 루트 볼륨을 50GB에서 100GB로 확장했습니다. 그리고 로그 저장용으로 50GB짜리 새 볼륨도 추가했습니다.
"생각보다 정말 간단하네요!" 김개발 씨가 감탄했습니다. 스토리지 확장 방법을 알아두면 디스크 공간 부족 문제를 빠르게 해결할 수 있습니다.
여러분도 디스크 사용률을 주기적으로 모니터링하고, 필요시 적절히 확장하세요.
실전 팁
💡 - 볼륨 확장 후에는 반드시 운영체제에서 파일시스템을 확장해야 실제 공간을 사용할 수 있습니다.
- CloudWatch 알람을 설정해서 디스크 사용률이 80%를 넘으면 알림을 받도록 하세요.
- 볼륨 크기는 늘릴 수 있지만 줄일 수는 없으므로, 적절한 크기로 늘리세요.
6. 스냅샷 생성
중요한 데이터베이스 마이그레이션 작업을 앞두고 김개발 씨는 불안했습니다. "작업 중에 실수하면 어떡하죠?" 박시니어 씨가 안심시켰습니다.
"걱정 마세요. 작업 전에 EBS 스냅샷을 만들어두면 언제든 복구할 수 있어요." 스냅샷은 클라우드 환경의 백업 전략에서 핵심적인 역할을 합니다.
EBS 스냅샷은 특정 시점의 볼륨 상태를 저장하는 백업 기능입니다. S3에 저장되며, 증분 백업 방식으로 작동해서 저장 공간과 비용을 절약할 수 있습니다.
스냅샷으로부터 새로운 볼륨을 생성하거나, 다른 리전으로 복사할 수도 있습니다.
다음 코드를 살펴봅시다.
import boto3
from datetime import datetime
ec2 = boto3.client('ec2', region_name='ap-northeast-2')
# 스냅샷 생성
volume_id = 'vol-1234567890abcdef0'
timestamp = datetime.now().strftime('%Y-%m-%d-%H-%M')
snapshot = ec2.create_snapshot(
VolumeId=volume_id,
Description=f'Backup of {volume_id} at {timestamp}'
)
snapshot_id = snapshot['SnapshotId']
print(f"스냅샷 생성 시작: {snapshot_id}")
# 스냅샷 완료 대기 (선택사항)
waiter = ec2.get_waiter('snapshot_completed')
waiter.wait(SnapshotIds=[snapshot_id])
print(f"스냅샷 완료: {snapshot_id}")
# 스냅샷으로부터 새 볼륨 생성
new_volume = ec2.create_volume(
SnapshotId=snapshot_id,
AvailabilityZone='ap-northeast-2a',
VolumeType='gp3'
)
print(f"스냅샷으로부터 새 볼륨 생성: {new_volume['VolumeId']}")
# 오래된 스냅샷 삭제 (30일 이상)
snapshots = ec2.describe_snapshots(OwnerIds=['self'])
for snap in snapshots['Snapshots']:
# 생성일 확인 후 삭제 로직 추가 가능
pass
김개발 씨의 회사에서 큰 프로젝트가 시작되었습니다. 데이터베이스를 MySQL 5.7에서 8.0으로 업그레이드하는 작업이었습니다.
이런 작업은 항상 위험이 따릅니다. 업그레이드 과정에서 데이터가 손상되거나 호환성 문제가 발생할 수 있습니다.
박시니어 씨가 팀 미팅에서 말했습니다. "작업 전에 반드시 스냅샷을 만들어두세요.
만약의 사태에 대비한 보험입니다." EBS 스냅샷은 마치 시간 여행 기계와 같습니다. 특정 시점의 볼륨 상태를 완벽하게 보존해두었다가, 필요할 때 그 시점으로 되돌아갈 수 있습니다.
게임에서 세이브 포인트를 만드는 것과 비슷합니다. 스냅샷의 가장 큰 장점은 증분 백업 방식입니다.
첫 번째 스냅샷은 볼륨 전체를 백업하지만, 이후 스냅샷은 변경된 블록만 저장합니다. 예를 들어 100GB 볼륨의 첫 스냅샷은 100GB를 저장하지만, 두 번째 스냅샷이 5GB만 변경되었다면 5GB만 추가로 저장됩니다.
이런 방식 덕분에 저장 공간과 비용이 크게 절약됩니다. 매일 스냅샷을 만들어도 부담이 적습니다.
많은 기업에서 일일 자동 백업 정책을 운영하는 이유입니다. 스냅샷은 S3에 저장됩니다.
하지만 S3 콘솔에서 직접 볼 수는 없습니다. AWS가 내부적으로 관리하는 S3 버킷에 저장되기 때문입니다.
이렇게 저장된 스냅샷은 매우 안정적입니다. S3의 내구성은 99.999999999%(일레븐 나인)이기 때문입니다.
스냅샷으로 할 수 있는 일은 많습니다. 가장 기본적인 용도는 백업과 복구입니다.
문제가 발생했을 때 스냅샷으로부터 새 볼륨을 만들어서 데이터를 복구할 수 있습니다. 또 다른 용도는 복제입니다.
운영 환경의 스냅샷을 만들어서 개발 환경에 복원하면, 실제 데이터로 테스트할 수 있습니다. 물론 개인정보는 적절히 마스킹해야 합니다.
리전 간 복사도 가능합니다. 서울 리전의 스냅샷을 도쿄 리전으로 복사해서, 재해 복구용 백업을 만들 수 있습니다.
이것은 진정한 의미의 지리적 이중화입니다. 위의 코드를 살펴보겠습니다.
create_snapshot() 메서드로 스냅샷을 생성합니다. Description 파라미터에 백업 목적과 시간을 명시하면 나중에 관리하기 편합니다.
타임스탬프를 포함시키는 것이 좋습니다. 스냅샷 생성은 비동기로 진행됩니다.
명령을 내리면 즉시 snapshot_id가 반환되지만, 실제 백업 작업은 백그라운드에서 계속됩니다. 큰 볼륨일수록 시간이 오래 걸립니다.
waiter를 사용하면 완료될 때까지 기다릴 수 있습니다. 스냅샷으로부터 새 볼륨을 만드는 것도 간단합니다.
create_volume() 메서드에 SnapshotId를 지정하면 됩니다. 이렇게 만든 볼륨은 스냅샷 시점의 데이터를 그대로 담고 있습니다.
실제 현업에서는 스냅샷을 어떻게 활용할까요? 가장 일반적인 패턴은 자동화된 백업 정책입니다.
AWS Backup 서비스나 Lambda 함수를 사용해서 매일 새벽 2시에 자동으로 스냅샷을 생성하도록 설정합니다. 그리고 라이프사이클 정책을 적용합니다.
예를 들어 일일 백업은 7일 보관, 주간 백업은 4주 보관, 월간 백업은 1년 보관하는 식입니다. 오래된 스냅샷은 자동으로 삭제되어 비용을 절감할 수 있습니다.
또 다른 실무 사례는 블루-그린 배포입니다. 새 버전을 배포하기 전에 현재 상태의 스냅샷을 만들어둡니다.
배포 후 문제가 발생하면 스냅샷으로 빠르게 롤백할 수 있습니다. 주의할 점도 있습니다.
스냅샷은 볼륨의 블록 단위 백업이므로, 파일 단위로 복구할 수는 없습니다. 특정 파일 하나만 복구하려면 스냅샷으로 볼륨을 만들어서 인스턴스에 연결한 후, 파일을 복사해야 합니다.
또한 스냅샷은 생성 시점의 상태만 보존합니다. 데이터베이스처럼 메모리에 캐시된 데이터가 있는 경우, 일관성 있는 스냅샷을 만들려면 애플리케이션을 잠시 중지하거나 flush 명령을 실행해야 합니다.
김개발 씨는 데이터베이스 마이그레이션 전에 스냅샷을 만들었습니다. 작업은 순조롭게 진행되었지만, 애플리케이션 호환성 문제가 발견되었습니다.
다행히 스냅샷이 있었기 때문에 30분 만에 이전 상태로 복구할 수 있었습니다. "스냅샷이 정말 큰 도움이 됐어요." 김개발 씨가 안도의 한숨을 내쉬었습니다.
EBS 스냅샷을 제대로 활용하면 데이터 손실 위험을 크게 줄일 수 있습니다. 여러분도 중요한 작업 전에는 반드시 스냅샷을 만드는 습관을 들이세요.
백업은 필요할 때는 없지만, 없을 때 필요한 법입니다.
실전 팁
💡 - 중요한 작업 전에는 항상 스냅샷을 만들어두세요.
- 스냅샷 설명에 날짜와 목적을 명시하면 관리가 쉬워집니다.
- 자동화된 백업 정책과 라이프사이클 정책을 설정해서 비용을 최적화하세요.
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
Helm 마이크로서비스 패키징 완벽 가이드
Kubernetes 환경에서 마이크로서비스를 효율적으로 패키징하고 배포하는 Helm의 핵심 기능을 실무 중심으로 학습합니다. Chart 생성부터 릴리스 관리까지 체계적으로 다룹니다.
보안 아키텍처 구성 완벽 가이드
프로젝트의 보안을 처음부터 설계하는 방법을 배웁니다. AWS 환경에서 VPC부터 WAF, 암호화, 접근 제어까지 실무에서 바로 적용할 수 있는 보안 아키텍처를 단계별로 구성해봅니다.
AWS Organizations 완벽 가이드
여러 AWS 계정을 체계적으로 관리하고 통합 결제와 보안 정책을 적용하는 방법을 실무 스토리로 쉽게 배워봅니다. 초보 개발자도 바로 이해할 수 있는 친절한 설명과 실전 예제를 제공합니다.
AWS KMS 암호화 완벽 가이드
AWS KMS(Key Management Service)를 활용한 클라우드 데이터 암호화 방법을 초급 개발자를 위해 쉽게 설명합니다. CMK 생성부터 S3, EBS 암호화, 봉투 암호화까지 실무에 필요한 모든 내용을 담았습니다.
AWS Secrets Manager 완벽 가이드
AWS에서 데이터베이스 비밀번호, API 키 등 민감한 정보를 안전하게 관리하는 Secrets Manager의 핵심 개념과 실무 활용법을 배워봅니다. 초급 개발자도 쉽게 따라할 수 있도록 실전 예제와 함께 설명합니다.