본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 23. · 3 Views
AWS Auto Scaling 완벽 가이드
트래픽 급증에 대비하는 자동 확장 시스템을 단계별로 구축합니다. AMI 생성부터 Auto Scaling Group 설정, 테스트까지 초급 개발자를 위해 실무 중심으로 설명합니다.
목차
- Auto Scaling Group의 개념과 장점
- AMI 생성 실습
- 시작 템플릿 만들기
- Auto Scaling 정책 설정
- Auto Scaling 동작 테스트
- Auto Scaling의 한계와 주의사항
1. Auto Scaling Group의 개념과 장점
이제 막 서비스를 론칭한 김개발 씨의 회사에 갑자기 사용자가 몰리기 시작했습니다. 서버가 느려지고, 몇몇 사용자는 접속조차 할 수 없게 되었습니다.
박시니어 씨가 다가와 "Auto Scaling을 설정했어야 했는데요"라고 말합니다.
Auto Scaling Group은 트래픽에 따라 서버 인스턴스를 자동으로 늘리거나 줄이는 AWS 서비스입니다. 마치 식당에서 손님이 많을 때 아르바이트생을 더 부르고, 한가할 때는 퇴근시키는 것과 같습니다.
비용 효율성과 안정성을 동시에 확보할 수 있습니다.
다음 코드를 살펴봅시다.
// Auto Scaling Group 기본 구성 예시 (AWS CLI)
aws autoscaling create-auto-scaling-group \
--auto-scaling-group-name my-asg \
--launch-template LaunchTemplateName=my-template \
--min-size 2 \
--max-size 10 \
--desired-capacity 2 \
--vpc-zone-identifier "subnet-1234,subnet-5678" \
--health-check-type ELB \
--health-check-grace-period 300 \
--target-group-arns "arn:aws:elasticloadbalancing:..." \
--tags "Key=Environment,Value=Production"
// 최소 2대, 최대 10대 사이에서 자동으로 조정됩니다
김개발 씨는 스타트업에 입사한 지 6개월 차 개발자입니다. 회사의 첫 서비스가 어느 유명 유튜버에게 소개되면서 하루 만에 사용자가 100배로 늘어났습니다.
문제는 서버가 단 2대밖에 없다는 것이었습니다. 새벽 2시, 알람이 울렸습니다.
서버 응답 시간이 10초를 넘었고, 에러율이 30퍼센트에 달했습니다. 김개발 씨는 급히 AWS 콘솔에 접속해 수동으로 서버를 추가했지만, 설정하는 동안에도 사용자들의 불만이 쏟아졌습니다.
다음 날 아침, 박시니어 씨가 사무실로 들어오며 말했습니다. "고생했어요.
하지만 앞으로는 이런 일이 없을 거예요. Auto Scaling을 설정할 거니까요." 그렇다면 Auto Scaling이란 정확히 무엇일까요?
쉽게 비유하자면, Auto Scaling은 마치 백화점의 계산대 운영과 같습니다. 평일 오전에는 계산대 2개만 열어두다가, 주말 저녁 피크 타임에는 10개까지 늘립니다.
손님이 줄면 다시 줄이고요. 이처럼 Auto Scaling도 트래픽에 따라 서버 인스턴스 수를 자동으로 조절합니다.
Auto Scaling이 없던 시절에는 어땠을까요? 개발자들은 트래픽을 예측해 미리 충분한 서버를 준비해야 했습니다.
문제는 예측이 빗나가기 일쑤였다는 점입니다. 너무 적게 준비하면 서비스가 다운되고, 너무 많이 준비하면 비용이 낭비됩니다.
더 큰 문제는 새벽 시간대 급증하는 트래픽이었습니다. 담당자가 잠들어 있으면 대응할 방법이 없었습니다.
바로 이런 문제를 해결하기 위해 Auto Scaling Group이 등장했습니다. Auto Scaling을 사용하면 트래픽에 따른 자동 대응이 가능해집니다.
CPU 사용률이 70퍼센트를 넘으면 자동으로 서버가 추가되고, 30퍼센트 아래로 내려가면 줄어듭니다. 또한 비용 최적화도 얻을 수 있습니다.
필요한 만큼만 서버를 운영하므로 불필요한 지출이 사라집니다. 무엇보다 개발자가 잠들어 있어도 시스템이 알아서 대응한다는 큰 이점이 있습니다.
위의 코드를 한 줄씩 살펴보겠습니다. 먼저 --min-size 2와 --max-size 10을 보면 최소 2대, 최대 10대 사이에서 운영된다는 것을 알 수 있습니다.
이 부분이 핵심입니다. 다음으로 --desired-capacity 2에서는 평상시 유지할 서버 수를 지정합니다.
--health-check-type ELB는 로드 밸런서를 통해 서버 상태를 확인한다는 의미입니다. 마지막으로 서버가 완전히 구동되기까지 300초의 여유 시간을 둡니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 온라인 쇼핑몰을 운영한다고 가정해봅시다.
평일 낮에는 서버 3대로 충분하지만, 저녁 8시부터 10시 사이에는 주문이 폭주합니다. Auto Scaling을 활용하면 이 시간대에 자동으로 서버가 15대까지 늘어났다가, 밤 12시 이후에는 다시 3대로 줄어듭니다.
쿠팡, 배달의민족 같은 대형 서비스들이 이런 패턴을 적극적으로 사용하고 있습니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 최소 인스턴스 수를 0으로 설정하는 것입니다. 이렇게 하면 트래픽이 없을 때 모든 서버가 종료되고, 갑작스러운 트래픽 발생 시 서버를 시작하는 데만 몇 분이 걸려 초기 사용자들이 에러를 겪게 됩니다.
따라서 최소 1-2대는 항상 유지하는 것이 올바른 방법입니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
박시니어 씨의 도움으로 Auto Scaling을 설정한 후, 김개발 씨는 편안한 밤을 보낼 수 있게 되었습니다. 새벽에 트래픽이 몰려도 시스템이 알아서 대응했고, 아침에 일어나 확인해보니 서버가 자동으로 8대까지 늘어났다가 다시 2대로 줄어든 로그를 볼 수 있었습니다.
Auto Scaling Group을 제대로 이해하면 안정적이고 비용 효율적인 서비스 운영이 가능합니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - 최소 인스턴스 수는 가용 영역 수만큼 설정하는 것이 안전합니다 (예: 2개 AZ면 최소 2대)
- Health Check Grace Period는 서버 부팅 시간보다 길게 설정해야 합니다
- 스케일 아웃은 빠르게, 스케일 인은 천천히 하도록 정책을 설정하는 것이 좋습니다
2. AMI 생성 실습
Auto Scaling을 설정하려면 먼저 복제할 서버의 이미지가 필요합니다. 김개발 씨는 박시니어 씨에게 "어떤 서버를 복제하나요?"라고 물었습니다.
"바로 우리가 만든 완벽한 서버를 통째로 복사하는 거죠"라는 답이 돌아왔습니다.
AMI(Amazon Machine Image)는 서버의 완전한 스냅샷입니다. 운영체제, 설치된 프로그램, 설정 파일까지 모두 포함됩니다.
마치 게임의 세이브 파일처럼, 언제든 똑같은 상태의 서버를 만들 수 있습니다. Auto Scaling은 이 AMI를 기반으로 서버를 자동 생성합니다.
다음 코드를 살펴봅시다.
// 1. 현재 실행 중인 EC2 인스턴스에서 AMI 생성
aws ec2 create-image \
--instance-id i-1234567890abcdef0 \
--name "my-web-server-v1.0" \
--description "Node.js 18, Nginx, PM2가 설치된 웹서버" \
--no-reboot
// 2. AMI 생성 상태 확인
aws ec2 describe-images \
--image-ids ami-0abcdef1234567890 \
--query 'Images[0].State'
// 3. AMI가 준비되면 "available" 상태로 변경됩니다
// 이제 이 AMI로 동일한 서버를 무한대로 복제할 수 있습니다
김개발 씨는 며칠에 걸쳐 완벽한 웹서버를 구축했습니다. Node.js를 설치하고, Nginx를 설정하고, PM2로 프로세스 관리를 구성했습니다.
환경 변수도 설정하고, 보안 그룹도 완벽하게 설정했습니다. 이제 이 서버를 여러 대 만들어야 하는데, 처음부터 다시 설정하려니 막막했습니다.
박시니어 씨가 모니터를 보며 말했습니다. "좋은 소식이 있어요.
이 서버를 통째로 복사할 수 있답니다." 그렇다면 AMI란 정확히 무엇일까요? 쉽게 비유하자면, AMI는 마치 빵 굽는 틀과 같습니다.
한 번 완벽한 틀을 만들어두면, 그 틀로 똑같은 빵을 계속 찍어낼 수 있습니다. 밀가루 양도 같고, 굽는 시간도 같고, 맛도 똑같습니다.
이처럼 AMI도 서버의 모든 것을 담은 템플릿입니다. AMI가 없던 시절에는 어땠을까요?
개발자들은 새 서버를 만들 때마다 모든 설정을 처음부터 다시 해야 했습니다. 운영체제를 설치하고, 필요한 프로그램을 하나씩 설치하고, 설정 파일을 복사하고, 환경 변수를 입력했습니다.
한 대 설정하는 데 30분이 걸린다면, 10대를 만들려면 5시간이 필요했습니다. 더 큰 문제는 사람이 하는 일이라 실수가 발생한다는 점이었습니다.
한 서버에만 설정을 빠뜨리면 버그의 원인이 되었습니다. 바로 이런 문제를 해결하기 위해 AMI가 등장했습니다.
AMI를 사용하면 서버 복제가 몇 분 만에 가능해집니다. 버튼 하나로 똑같은 서버가 생성됩니다.
또한 일관성 보장도 얻을 수 있습니다. 모든 서버가 정확히 같은 설정을 가지므로 예상치 못한 버그가 줄어듭니다.
무엇보다 Auto Scaling의 기반이 된다는 큰 이점이 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 create-image 명령어로 AMI 생성을 시작합니다. --instance-id에는 복제할 원본 서버의 ID를 지정합니다.
이 부분이 핵심입니다. 다음으로 --name에서는 AMI의 이름을 지정하는데, 버전을 포함하는 것이 좋습니다.
--no-reboot 옵션은 서버를 재부팅하지 않고 이미지를 만들라는 의미입니다. 마지막으로 describe-images 명령어로 AMI 생성 상태를 확인할 수 있습니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 배포 파이프라인을 구축한다고 가정해봅시다.
개발 서버에서 코드를 테스트하고, 모든 것이 정상이면 해당 서버로 AMI를 생성합니다. 그리고 그 AMI를 Auto Scaling Group에 적용하면, 새로 생성되는 모든 서버가 테스트를 통과한 코드를 가지게 됩니다.
넷플릭스 같은 기업은 하루에도 수십 개의 AMI를 생성하며 무중단 배포를 실현합니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 AMI에 민감한 정보를 포함시키는 것입니다. 데이터베이스 비밀번호나 API 키를 하드코딩하면, 그 AMI로 생성된 모든 서버가 같은 키를 사용하게 되어 보안 위험이 발생합니다.
따라서 민감한 정보는 AWS Secrets Manager나 Parameter Store에 저장하고, 서버 시작 시 불러오는 방식으로 사용해야 합니다. 또 다른 주의점은 AMI의 크기입니다.
불필요한 로그 파일이나 캐시 데이터를 정리하지 않으면 AMI가 수십 GB로 커질 수 있습니다. 이렇게 되면 새 서버를 시작하는 시간도 길어지고, 스토리지 비용도 증가합니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 도움으로 첫 AMI를 만든 김개발 씨는 신기한 듯 말했습니다.
"와, 이제 이 서버를 몇 대든 만들 수 있네요!" 박시니어 씨가 웃으며 답했습니다. "그것뿐만 아니에요.
나중에 문제가 생겨도 이 AMI로 언제든 복구할 수 있답니다." AMI를 제대로 이해하면 서버 관리가 훨씬 수월해집니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - AMI 이름에는 버전과 날짜를 포함하세요 (예: web-server-v1.2-20250123)
- 정기적으로 AMI를 업데이트하여 보안 패치를 반영하세요
- 사용하지 않는 오래된 AMI는 삭제하여 비용을 절감하세요
3. 시작 템플릿 만들기
AMI를 만들었지만, 김개발 씨는 여전히 궁금했습니다. "서버를 만들 때마다 인스턴스 타입, 보안 그룹, 키페어를 다 설정해야 하나요?" 박시니어 씨가 고개를 저었습니다.
"아니요, 시작 템플릿을 만들면 모든 설정을 저장해둘 수 있어요."
시작 템플릿(Launch Template)은 EC2 인스턴스를 만들 때 필요한 모든 설정을 담은 청사진입니다. AMI, 인스턴스 타입, 보안 그룹, 사용자 데이터 스크립트까지 포함됩니다.
Auto Scaling Group은 이 템플릿을 사용해 일관된 서버를 자동으로 생성합니다.
다음 코드를 살펴봅시다.
// launch-template.json 파일 내용
{
"ImageId": "ami-0abcdef1234567890",
"InstanceType": "t3.medium",
"KeyName": "my-keypair",
"SecurityGroupIds": ["sg-0123456789abcdef0"],
"UserData": "IyEvYmluL2Jhc2gKY2QgL2hvbWUvdWJ1bnR1L2FwcApnaXQgcHVsbApucG0gaW5zdGFsbApwbTIgcmVzdGFydCBhbGw=",
"TagSpecifications": [{
"ResourceType": "instance",
"Tags": [{"Key": "Name", "Value": "auto-scaled-server"}]
}],
"MetadataOptions": {
"HttpTokens": "required"
}
}
// AWS CLI로 시작 템플릿 생성
aws ec2 create-launch-template \
--launch-template-name my-web-template \
--version-description "v1.0-production" \
--launch-template-data file://launch-template.json
김개발 씨는 테스트를 위해 수동으로 EC2 인스턴스를 몇 대 만들어봤습니다. 매번 AMI를 선택하고, 인스턴스 타입을 고르고, 보안 그룹을 설정하고, 키페어를 선택했습니다.
한 대 만드는 데 5분 정도 걸렸는데, 설정 항목이 많아 실수하기도 쉬웠습니다. 박시니어 씨가 화면을 보더니 말했습니다.
"매번 그렇게 하면 힘들어요. 시작 템플릿을 만들어두면 클릭 한 번으로 끝납니다." 그렇다면 시작 템플릿이란 정확히 무엇일까요?
쉽게 비유하자면, 시작 템플릿은 마치 자동차 공장의 설계도와 같습니다. 어떤 엔진을 쓸지, 어떤 색상으로 칠할지, 어떤 옵션을 추가할지 모두 정해져 있습니다.
공장 직원은 설계도만 보고 똑같은 차를 계속 생산합니다. 이처럼 시작 템플릿도 서버 생성의 모든 사양을 담고 있습니다.
시작 템플릿이 없던 시절에는 어땠을까요? 개발자들은 Auto Scaling을 설정할 때마다 모든 옵션을 다시 입력해야 했습니다.
인스턴스 타입을 t2.micro로 할지 t3.medium으로 할지, 보안 그룹은 어떤 것을 쓸지, 사용자 데이터 스크립트는 무엇을 넣을지 일일이 선택했습니다. 팀원마다 다른 설정을 사용하면 서버 간 불일치가 발생했습니다.
더 큰 문제는 설정을 변경하려면 Auto Scaling Group을 삭제하고 다시 만들어야 한다는 점이었습니다. 바로 이런 문제를 해결하기 위해 시작 템플릿이 등장했습니다.
시작 템플릿을 사용하면 설정의 재사용이 가능해집니다. 한 번 만들어두면 여러 Auto Scaling Group에서 사용할 수 있습니다.
또한 버전 관리도 얻을 수 있습니다. 템플릿을 수정하면 새 버전이 생성되고, 이전 버전으로 롤백도 가능합니다.
무엇보다 팀 전체가 같은 표준을 사용한다는 큰 이점이 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 ImageId에는 앞서 만든 AMI의 ID를 지정합니다. InstanceType은 서버의 성능을 결정하는데, t3.medium은 2개의 vCPU와 4GB 메모리를 제공합니다.
이 부분이 핵심입니다. 다음으로 UserData에는 서버 시작 시 실행할 스크립트를 Base64로 인코딩해서 넣습니다.
위 예시는 git pull로 최신 코드를 받고 PM2를 재시작하는 스크립트입니다. MetadataOptions의 HttpTokens: required는 IMDSv2를 강제하여 보안을 강화합니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 개발, 스테이징, 프로덕션 환경을 각각 운영한다고 가정해봅시다.
각 환경마다 시작 템플릿을 만들어둡니다. 개발 환경은 t3.small로 비용을 절감하고, 프로덕션은 c5.xlarge로 성능을 최대화합니다.
환경 변수도 UserData 스크립트로 각각 설정합니다. 이렇게 하면 환경별로 최적화된 서버를 자동으로 생성할 수 있습니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 UserData 스크립트를 너무 복잡하게 만드는 것입니다.
스크립트가 길어지면 실행 시간이 오래 걸리고, 에러 발생 시 디버깅이 어려워집니다. 따라서 핵심 설정만 UserData에 넣고, 나머지는 AMI에 미리 포함시키는 것이 올바른 방법입니다.
또 다른 주의점은 보안 그룹 설정입니다. 개발할 때 편하려고 모든 포트를 열어두는 경우가 있는데, 이는 큰 보안 위험입니다.
필요한 포트만 열고, 소스 IP도 제한해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
시작 템플릿을 만든 김개발 씨는 감탄했습니다. "이제 매번 설정할 필요가 없네요!" 박시니어 씨가 고개를 끄덕였습니다.
"그렇죠. 그리고 템플릿 버전을 관리하면 언제든 이전 설정으로 돌아갈 수도 있어요." 시작 템플릿을 제대로 이해하면 서버 관리가 표준화되고 실수가 줄어듭니다.
여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - UserData 스크립트는 짧고 간단하게 유지하세요 (5-10줄 이내)
- 템플릿 이름에 용도를 명확히 표시하세요 (예: web-server-prod, api-server-dev)
- 최신 버전을 기본값으로 설정하되, 중요한 변경 전에는 새 버전을 테스트하세요
4. Auto Scaling 정책 설정
시작 템플릿까지 만들었지만, 김개발 씨는 궁금했습니다. "서버가 언제 늘어나고 줄어드는 거죠?" 박시니어 씨가 화면을 가리키며 설명했습니다.
"바로 스케일링 정책이 그걸 결정합니다. CPU가 70퍼센트를 넘으면 서버를 추가하고, 30퍼센트 아래로 내려가면 제거하는 식이죠."
스케일링 정책(Scaling Policy)은 언제, 얼마나 서버를 늘리거나 줄일지 결정하는 규칙입니다. 대표적으로 CPU 사용률, 네트워크 트래픽, 요청 수 등을 기준으로 합니다.
목표 추적, 단계별, 예약된 스케일링 등 다양한 방식이 있습니다.
다음 코드를 살펴봅시다.
// 1. 목표 추적 스케일링 정책 (가장 많이 사용)
aws autoscaling put-scaling-policy \
--auto-scaling-group-name my-asg \
--policy-name target-tracking-cpu \
--policy-type TargetTrackingScaling \
--target-tracking-configuration '{
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ASGAverageCPUUtilization"
},
"TargetValue": 70.0
}'
// 2. 단계별 스케일링 정책 (세밀한 제어)
aws autoscaling put-scaling-policy \
--auto-scaling-group-name my-asg \
--policy-name step-scaling-out \
--policy-type StepScaling \
--adjustment-type PercentChangeInCapacity \
--metric-aggregation-type Average \
--step-adjustments '[
{"MetricIntervalLowerBound": 0, "MetricIntervalUpperBound": 20, "ScalingAdjustment": 10},
{"MetricIntervalLowerBound": 20, "ScalingAdjustment": 30}
]'
// CPU 70% 유지를 목표로 자동 조정됩니다
김개발 씨의 서비스는 하루 중 시간대별로 트래픽 패턴이 뚜렷했습니다. 오전 10시부터 사용자가 몰리기 시작해 오후 8시에 피크를 찍고, 자정 이후에는 한산했습니다.
문제는 피크 시간대에 CPU 사용률이 95퍼센트까지 치솟아 서버가 느려진다는 것이었습니다. 박시니어 씨가 모니터링 그래프를 보며 말했습니다.
"CPU가 이렇게 높으면 안 돼요. 스케일링 정책을 설정해서 70퍼센트만 넘어도 서버를 추가하도록 해봅시다." 그렇다면 스케일링 정책이란 정확히 무엇일까요?
쉽게 비유하자면, 스케일링 정책은 마치 에어컨의 자동 온도 조절과 같습니다. 실내 온도가 28도를 넘으면 에어컨이 강하게 작동하고, 26도 이하로 내려가면 약하게 작동합니다.
설정한 목표 온도를 유지하려고 계속 조절하는 것이죠. 이처럼 스케일링 정책도 설정한 목표 지표를 유지하려고 서버 수를 조절합니다.
스케일링 정책이 없던 시절에는 어땠을까요? 개발자들은 서버를 늘릴지 줄일지 수동으로 판단해야 했습니다.
모니터링 화면을 계속 지켜보다가 CPU가 높아지면 서버를 추가하고, 낮아지면 제거했습니다. 문제는 사람의 판단은 느리다는 점이었습니다.
CPU가 90퍼센트를 넘어 이미 사용자들이 느린 응답을 경험한 후에야 대응할 수 있었습니다. 더 큰 문제는 야간이나 주말에는 담당자가 없어 대응 자체가 불가능하다는 점이었습니다.
바로 이런 문제를 해결하기 위해 자동 스케일링 정책이 등장했습니다. 스케일링 정책을 사용하면 즉각적인 대응이 가능해집니다.
CPU가 목표치를 초과하면 1-2분 내에 새 서버가 추가됩니다. 또한 비용 최적화도 얻을 수 있습니다.
트래픽이 줄면 불필요한 서버를 자동으로 제거하여 비용을 절감합니다. 무엇보다 24시간 무인 운영이 가능하다는 큰 이점이 있습니다.
위의 코드를 한 줄씩 살펴보겠습니다. 먼저 TargetTrackingScaling 정책은 가장 간단하고 많이 사용되는 방식입니다.
TargetValue: 70.0은 평균 CPU 사용률을 70퍼센트로 유지하겠다는 의미입니다. 이 부분이 핵심입니다.
AWS가 자동으로 계산해서 서버를 추가하거나 제거합니다. 다음으로 StepScaling 정책은 더 세밀한 제어가 가능합니다.
CPU가 목표치를 20퍼센트 초과하면 10퍼센트 증가, 40퍼센트 이상 초과하면 30퍼센트 증가하는 식으로 단계별 대응이 가능합니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 뉴스 서비스를 운영한다고 가정해봅시다. 평소에는 트래픽이 적지만, 속보가 나가면 순간적으로 10배 이상 몰립니다.
이런 경우 목표 추적 정책만으로는 부족할 수 있습니다. 단계별 스케일링을 추가해서 CPU가 80퍼센트를 넘으면 즉시 50퍼센트의 서버를 추가하도록 설정합니다.
또한 예약된 스케일링으로 뉴스가 주로 나가는 시간대에 미리 서버를 늘려두는 것도 효과적입니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 목표값을 너무 낮게 설정하는 것입니다. CPU 목표를 30퍼센트로 설정하면 불필요하게 많은 서버가 생성되어 비용이 급증합니다.
일반적으로 웹서버는 70-80퍼센트, API 서버는 60-70퍼센트가 적절합니다. 따라서 서비스 특성에 맞는 목표값을 설정하는 것이 올바른 방법입니다.
또 다른 주의점은 스케일 인 속도입니다. 서버를 추가하는 것은 빠르게 하되, 제거하는 것은 천천히 해야 합니다.
트래픽이 일시적으로 줄었다가 다시 늘어날 수 있기 때문입니다. AWS는 기본적으로 스케일 인을 보수적으로 수행하므로, 특별한 이유가 없다면 기본값을 사용하는 것이 좋습니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 스케일링 정책을 설정한 후, 김개발 씨는 모니터링 그래프를 지켜봤습니다.
저녁 8시, 트래픽이 몰리면서 CPU가 70퍼센트를 넘자 자동으로 서버가 2대 추가되었습니다. CPU는 다시 60퍼센트대로 안정되었습니다.
밤 12시, 트래픽이 줄자 서버가 하나씩 제거되었습니다. 김개발 씨는 신기한 듯 말했습니다.
"정말 제가 아무것도 안 해도 알아서 조절되네요!" 스케일링 정책을 제대로 이해하면 안정적이고 비용 효율적인 서비스 운영이 가능합니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - 목표 추적 정책은 CPU 70-80%, 메모리 70-80%가 일반적입니다
- 스케일 아웃은 빠르게(1-2분), 스케일 인은 천천히(5-10분) 설정하세요
- 여러 지표를 조합하면 더 안정적입니다 (CPU + ALB 요청 수)
5. Auto Scaling 동작 테스트
모든 설정을 마친 김개발 씨는 불안했습니다. "정말 잘 작동할까요?" 박시니어 씨가 웃으며 답했습니다.
"직접 부하를 줘보면 알 수 있어요. stress 명령어로 CPU를 높여보죠."
Auto Scaling이 제대로 작동하는지 확인하려면 부하 테스트가 필수입니다. CPU 부하 도구나 트래픽 생성 도구로 의도적으로 부하를 주고, CloudWatch 메트릭과 Auto Scaling 활동 로그를 관찰합니다.
실제 트래픽 급증 전에 미리 검증하는 과정입니다.
다음 코드를 살펴봅시다.
// 1. EC2 인스턴스에 접속해서 부하 생성 도구 설치
sudo apt-get update
sudo apt-get install stress -y
// 2. CPU 부하 생성 (4개 코어를 80% 사용)
stress --cpu 4 --timeout 600s
// 3. 다른 터미널에서 Auto Scaling 활동 모니터링
aws autoscaling describe-scaling-activities \
--auto-scaling-group-name my-asg \
--max-records 10 \
--query 'Activities[*].[StartTime,Description,StatusCode]' \
--output table
// 4. CloudWatch 메트릭 확인
aws cloudwatch get-metric-statistics \
--namespace AWS/EC2 \
--metric-name CPUUtilization \
--dimensions Name=AutoScalingGroupName,Value=my-asg \
--start-time 2025-12-23T10:00:00Z \
--end-time 2025-12-23T11:00:00Z \
--period 60 \
--statistics Average
// CPU 사용률이 70%를 넘으면 1-2분 내에 서버가 추가됩니다
김개발 씨는 모든 설정을 마쳤지만, 정말로 작동할지 확신이 서지 않았습니다. 설정 화면에는 모두 녹색 체크 표시가 있었지만, 실제로 트래픽이 몰렸을 때 제대로 대응할 수 있을까요?
그냥 믿고 기다려야 할까요? 박시니어 씨가 고개를 저었습니다.
"아니요, 직접 테스트해봐야 해요. 실제 장애 상황에서 처음 확인하면 늦습니다." 그렇다면 부하 테스트는 어떻게 하는 것일까요?
쉽게 비유하자면, 부하 테스트는 마치 소방 훈련과 같습니다. 실제 화재가 나기 전에 미리 대피 경로를 확인하고, 소화기 사용법을 연습합니다.
비상벨을 눌러보고, 사람들이 얼마나 빨리 대피하는지 확인합니다. 이처럼 부하 테스트도 실제 트래픽 급증 전에 시스템의 대응 능력을 확인하는 과정입니다.
부하 테스트를 하지 않으면 어떻게 될까요? 많은 스타트업이 이런 실수를 합니다.
Auto Scaling을 설정해두고 안심합니다. 그러다가 실제로 트래픽이 몰렸을 때 문제를 발견합니다.
스케일링 정책의 목표값이 너무 높아서 서버 추가가 너무 늦게 일어나거나, 시작 템플릿의 UserData 스크립트에 오타가 있어서 새 서버가 제대로 시작되지 않거나, 보안 그룹 설정이 잘못되어 로드 밸런서와 통신이 안 되는 등의 문제가 발견됩니다. 이미 사용자들이 에러를 겪은 후입니다.
바로 이런 문제를 방지하기 위해 사전 부하 테스트가 필수입니다. 부하 테스트를 하면 문제를 미리 발견할 수 있습니다.
서버 추가 시간이 예상보다 길다면 AMI 크기를 줄이거나 UserData 스크립트를 간소화할 수 있습니다. 또한 최적의 설정값을 찾을 수 있습니다.
여러 목표값을 테스트해보고, 성능과 비용의 균형점을 찾습니다. 무엇보다 팀의 자신감이 생긴다는 큰 이점이 있습니다.
위의 코드를 한 줄씩 살펴보겠습니다. 먼저 stress 명령어로 CPU 부하를 생성합니다.
--cpu 4는 4개의 워커 프로세스를 실행해 CPU를 사용하라는 의미입니다. --timeout 600s는 10분간 실행하라는 뜻입니다.
이 부분이 핵심입니다. 다음으로 describe-scaling-activities 명령어로 Auto Scaling이 어떤 활동을 하는지 실시간으로 확인할 수 있습니다.
"Launching a new EC2 instance"라는 메시지가 보이면 서버가 추가되고 있는 것입니다. 마지막으로 CloudWatch 메트릭으로 CPU 사용률 변화를 그래프로 볼 수 있습니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 대규모 마케팅 이벤트를 앞두고 있다고 가정해봅시다.
예상 트래픽의 2배를 부하 테스트로 시뮬레이션합니다. Apache Bench나 K6 같은 도구로 수천 개의 동시 요청을 보냅니다.
Auto Scaling이 얼마나 빨리 반응하는지, 최대 몇 대까지 늘어나는지, 응답 시간은 유지되는지 확인합니다. 문제가 발견되면 이벤트 전에 수정할 수 있습니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 프로덕션 환경에서 부하 테스트를 하는 것입니다.
실제 사용자가 있는 서비스에 과도한 부하를 주면 진짜 장애가 발생할 수 있습니다. 따라서 별도의 테스트 환경을 만들거나, 새벽 시간대 같은 한산한 시간에 제한적으로 테스트하는 것이 올바른 방법입니다.
또 다른 주의점은 비용입니다. 부하 테스트 중에는 서버가 많이 생성되므로 비용이 발생합니다.
테스트 후에는 반드시 서버를 정리하고, 불필요한 리소스를 삭제해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
박시니어 씨와 함께 부하 테스트를 진행한 김개발 씨는 흥미진진하게 화면을 지켜봤습니다. CPU가 75퍼센트를 넘자 1분 후 "Launching new instance" 메시지가 나타났습니다.
2분 뒤 새 서버가 로드 밸런서에 등록되었고, CPU는 다시 65퍼센트로 떨어졌습니다. "와, 정말 작동하네요!" 김개발 씨가 감탄하자, 박시니어 씨가 웃으며 말했습니다.
"이제 안심하고 잘 수 있겠네요." 부하 테스트를 제대로 수행하면 시스템에 대한 신뢰를 얻고, 잠재적 문제를 사전에 발견할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - 부하 테스트는 반드시 별도의 테스트 환경에서 먼저 수행하세요
- 여러 시나리오를 테스트하세요 (점진적 증가, 급격한 급증, 지속적 고부하)
- 테스트 후에는 Auto Scaling Group을 원래 Desired Capacity로 되돌리세요
6. Auto Scaling의 한계와 주의사항
성공적으로 Auto Scaling을 구축한 김개발 씨는 모든 것이 해결된 줄 알았습니다. 하지만 박시니어 씨가 조심스럽게 말했습니다.
"Auto Scaling이 만능은 아니에요. 알아야 할 한계와 주의사항이 있답니다."
Auto Scaling은 강력한 도구지만 완벽하지 않습니다. 서버 시작 시간, 데이터베이스 병목, 세션 관리, 비용 폭증 등의 문제가 있을 수 있습니다.
이런 한계를 이해하고 보완책을 마련해야 진정한 안정성을 확보할 수 있습니다.
다음 코드를 살펴봅시다.
// 1. 서버 시작 시간 최소화를 위한 Warm Pool 설정
aws autoscaling put-warm-pool \
--auto-scaling-group-name my-asg \
--pool-state Stopped \
--min-size 2
// 2. 비용 폭증 방지를 위한 최대 인스턴스 제한
aws autoscaling update-auto-scaling-group \
--auto-scaling-group-name my-asg \
--max-size 20 \
--tags Key=CostCenter,Value=Engineering
// 3. 세션 문제 해결을 위한 Redis 연결 설정
const Redis = require('ioredis');
const redis = new Redis({
host: process.env.REDIS_HOST,
port: 6379,
maxRetriesPerRequest: 3
});
// 세션을 로컬 메모리 대신 Redis에 저장
app.use(session({
store: new RedisStore({ client: redis }),
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false
}));
// 서버가 추가/제거되어도 세션이 유지됩니다
김개발 씨의 Auto Scaling 시스템은 일주일간 완벽하게 작동했습니다. 트래픽이 늘면 서버가 추가되고, 줄면 제거되었습니다.
모든 것이 순조로워 보였습니다. 그러던 어느 날 저녁, 갑작스러운 트래픽 급증이 발생했습니다.
Auto Scaling은 즉시 반응해 서버를 추가했습니다. 하지만 새 서버가 완전히 준비되기까지 3분이 걸렸습니다.
그 사이에 기존 서버들은 과부하로 응답이 느려졌고, 일부 사용자는 로그인 세션이 끊어지는 문제를 겪었습니다. 더 큰 문제는 데이터베이스였습니다.
서버는 20대로 늘어났지만, 데이터베이스는 단 1대뿐이었습니다. 데이터베이스가 병목이 되어 전체 시스템이 느려졌습니다.
박시니어 씨가 상황을 진정시킨 후 설명했습니다. "Auto Scaling은 만능이 아니에요.
알아야 할 한계가 있습니다." 그렇다면 Auto Scaling의 한계는 무엇일까요? 첫 번째는 서버 시작 시간입니다.
새 서버가 부팅되고 애플리케이션이 준비되기까지 최소 1-2분, 길게는 5분 이상 걸릴 수 있습니다. 마치 식당에 손님이 갑자기 몰렸을 때 새 아르바이트생을 급히 부르는 것과 같습니다.
아르바이트생이 도착하고, 유니폼을 입고, 오늘의 메뉴를 익히기까지 시간이 필요합니다. 그 사이 기존 직원들은 과부하로 힘들어합니다.
두 번째는 세션 관리 문제입니다. 서버를 여러 대 사용하면 사용자의 세션 정보를 어디에 저장할지가 중요해집니다.
A 서버에 로그인한 사용자가 다음 요청에서 B 서버로 연결되면 로그인 정보가 없어 로그아웃되는 것처럼 보입니다. 이를 해결하려면 세션을 Redis나 DynamoDB 같은 외부 저장소에 저장해야 합니다.
세 번째는 데이터베이스 병목입니다. 서버는 Auto Scaling으로 무한히 늘릴 수 있지만, 데이터베이스는 그렇지 않습니다.
서버가 100대로 늘어나도 데이터베이스가 감당할 수 없으면 전체 시스템이 느려집니다. 데이터베이스 읽기 복제본을 추가하거나, 캐싱을 적극 활용하는 보완책이 필요합니다.
네 번째는 비용 폭증 위험입니다. Auto Scaling이 잘못 설정되면 서버가 무한정 늘어나 비용이 폭증할 수 있습니다.
실제로 한 스타트업은 잘못된 설정으로 하룻밤 사이에 서버 1000대가 생성되어 수천만 원의 청구서를 받은 사례도 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 Warm Pool은 미리 서버를 준비해두는 기능입니다. 중지 상태의 서버 2대를 항상 대기시켜두면, 트래픽 급증 시 부팅 시간 없이 바로 시작할 수 있습니다.
이 부분이 핵심입니다. 다음으로 --max-size 20으로 최대 인스턴스 수를 제한하면 비용 폭증을 방지할 수 있습니다.
마지막으로 세션을 Redis에 저장하는 코드는 여러 서버 간 세션 공유 문제를 해결합니다. 실제 현업에서는 어떻게 대응할까요?
예를 들어 대규모 이커머스 플랫폼을 운영한다고 가정해봅시다. 서버 시작 시간을 줄이기 위해 AMI를 최적화하고, 필수 데이터를 미리 캐싱해둡니다.
세션은 ElastiCache Redis에 저장하고, 정적 파일은 CloudFront CDN으로 서빙합니다. 데이터베이스는 Aurora의 Auto Scaling 읽기 복제본을 사용하고, 자주 조회되는 데이터는 Redis로 캐싱합니다.
비용 폭증을 방지하기 위해 CloudWatch 알람으로 서버 수가 50대를 넘으면 즉시 알림을 받도록 설정합니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 Auto Scaling만 믿고 다른 최적화를 소홀히 하는 것입니다. 비효율적인 코드는 아무리 서버를 늘려도 느립니다.
쿼리 최적화, 인덱스 추가, N+1 쿼리 제거 같은 기본적인 최적화가 먼저입니다. Auto Scaling은 최적화된 코드를 확장하는 도구이지, 나쁜 코드를 감춰주는 만능 해결책이 아닙니다.
또 다른 주의점은 스케일 다운의 위험입니다. 서버를 줄일 때 진행 중인 요청이 끊어질 수 있습니다.
이를 방지하려면 Connection Draining(연결 해제 지연)을 설정해야 합니다. 서버를 종료하기 전에 30-60초 동안 새 요청을 받지 않고, 기존 요청만 처리한 후 안전하게 종료하는 것입니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 Redis를 추가하고, 데이터베이스 읽기 복제본을 설정하고, Warm Pool을 구성했습니다.
다음 트래픽 급증 때는 훨씬 안정적으로 대응할 수 있었습니다. 김개발 씨가 말했습니다.
"Auto Scaling은 시작일 뿐이었네요. 전체 시스템을 함께 최적화해야 한다는 걸 배웠어요." Auto Scaling의 한계를 이해하고 보완책을 마련하면 진정으로 안정적이고 확장 가능한 시스템을 구축할 수 있습니다.
여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - 세션은 반드시 외부 저장소(Redis, DynamoDB)에 저장하세요
- 데이터베이스 병목을 미리 확인하고 읽기 복제본이나 캐싱을 준비하세요
- 비용 알람을 설정해 예상치 못한 비용 폭증을 방지하세요
- Connection Draining을 30-60초로 설정해 안전한 스케일 다운을 보장하세요
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
VPC 네트워크의 기초 - CIDR과 서브넷 설계 완벽 가이드
초급 개발자를 위한 VPC와 서브넷 설계 입문서입니다. 도서관 비유로 CIDR 개념을 쉽게 이해하고, 실무에서 자주 사용하는 서브넷 분할 전략을 단계별로 배워봅니다. 점프 투 자바 스타일로 술술 읽히는 네트워크 입문 가이드입니다.
AWS 리소스 정리와 비용 관리 완벽 가이드
AWS 사용 후 리소스를 안전하게 정리하고 예상치 못한 과금을 방지하는 방법을 배웁니다. 프리티어 관리부터 비용 모니터링까지 실무에서 꼭 필요한 내용을 다룹니다.
AWS Certificate Manager로 HTTPS 인증서 발급 완벽 가이드
AWS Certificate Manager를 사용하여 무료로 SSL/TLS 인증서를 발급받고, 로드 밸런서에 적용하여 안전한 HTTPS 웹 서비스를 구축하는 방법을 초급자도 쉽게 따라 할 수 있도록 단계별로 안내합니다.
Route 53으로 도메인 연결 완벽 가이드
AWS Route 53을 사용하여 도메인을 등록하고 실제 서비스에 연결하는 전 과정을 실무 스토리와 함께 쉽게 배워봅니다. DNS의 기본 개념부터 레코드 설정, ELB 연결까지 초급 개발자도 쉽게 따라할 수 있도록 구성했습니다.
AWS RDS 관리형 데이터베이스 완벽 가이드
직접 데이터베이스를 설치하고 관리하는 것이 부담스러운 초급 개발자를 위한 RDS 가이드입니다. 데이터베이스 엔진 선택부터 인스턴스 생성, 보안 설정, 백업까지 실무에 필요한 모든 내용을 다룹니다.