클라우드 컴퓨팅 기초 — 가상화·VPC·스토리지·프로덕션 패턴까지
이 글의 핵심
클라우드는 원격에 있는 Linux 박스가 아니라 가상화·네트워크·스토리지가 겹겹이 쌓인 공유 인프라입니다. 하이퍼바이저 종류, 테넌트 격리, VPC·서브넷 설계, 블록·파일·오브젝트 스토리지의 성능 특성, 운영 패턴을 차례로 정리합니다.
들어가며
클라우드 서비스를 “API로 켜지는 서버”로만 보면 비용·성능·보안 문제가 생겼을 때 원인을 좁히기 어렵습니다. 퍼블릭 클라우드는 데이터센터의 물리 서버를 여러 고객이 나누어 쓰는 구조 위에 API, 과금, 자동화 계층이 얹힌 것입니다. 같은 vCPU 수를 가진 인스턴스라도 어떤 호스트에 배치되었는지, 네트워크 경로가 어떤지, 어떤 디스크를 붙였는지에 따라 체감 성능이 달라지고, 이 차이는 모두 아래의 내부 구조에서 나옵니다.
이 글은 특정 벤더에 묶이지 않도록 개념 중심으로 설명하되, 운영하면서 실제로 마주치는 용어(VPC, 서브넷, IOPS 등)는 AWS 용어를 기준으로 함께 짚습니다.
가상화와 하이퍼바이저
물리 서버에서 VM까지
가상화는 한 대의 물리 머신 위에 여러 가상 머신(VM)을 올려 CPU, 메모리, 장치를 논리적으로 나누는 기술이고, 이를 관리하는 소프트웨어가 하이퍼바이저입니다. 게스트 OS는 실제 하드웨어 위에서 도는 것처럼 동작하지만, 하이퍼바이저가 특권 명령, 메모리 주소 변환, I/O를 중재합니다.
타입 1(베어메탈) 하이퍼바이저
타입 1 하이퍼바이저는 일반 호스트 OS 없이 물리 하드웨어 위에서 직접 동작합니다. VMware ESXi, Xen, Microsoft Hyper-V가 대표적이고, Linux 커널을 하이퍼바이저로 만드는 KVM도 보통 이 범주로 분류합니다. 퍼블릭 클라우드의 컴퓨트 노드는 모두 이 계열입니다. AWS Nitro는 KVM 기반의 경량 하이퍼바이저에 네트워크·스토리지 가상화를 전용 하드웨어 카드로 넘긴 구조이고, Azure는 Hyper-V 기반입니다.
대규모 환경에서는 VM 배치가 성능에 큰 영향을 줍니다. vCPU를 특정 물리 코어에 고정하는 CPU 피닝, VM의 메모리와 vCPU를 같은 NUMA 노드에 두는 NUMA 인지 배치, TLB 미스를 줄이는 대형 페이지가 대표적인 기법입니다. 클라우드 사업자가 큰 인스턴스 타입의 vCPU 수를 소켓이나 NUMA 노드 경계에 맞춰 정하는 것도 이 때문입니다.
타입 2(호스티드) 하이퍼바이저
타입 2 하이퍼바이저는 Windows, macOS, Linux 같은 호스트 OS 위의 애플리케이션으로 동작합니다. VirtualBox, VMware Workstation, Parallels가 대표적이며, 개발자 PC에서 VM을 띄울 때 주로 씁니다. 게스트의 I/O가 호스트 OS의 스케줄러, 파일시스템, 드라이버를 한 번 더 거치므로, 호스트에서 다른 작업이 몰리면 게스트의 지연 편차가 커지기 쉽습니다. 요즘은 이런 제품도 대부분 CPU의 하드웨어 가상화 기능을 쓰므로 CPU 연산 자체의 오버헤드는 크지 않고, 차이는 주로 I/O 경로와 스케줄링에서 납니다.
전가상화, 반가상화, 하드웨어 보조 가상화
초기 x86은 일부 특권 명령이 사용자 모드에서 실행될 때 트랩을 일으키지 않고 조용히 다르게 동작했기 때문에, 고전적인 “트랩 후 에뮬레이션” 방식만으로는 가상화할 수 없었습니다. VMware는 게스트 커널 코드를 실행 전에 안전한 코드로 바꾸는 바이너리 변환으로 전가상화를 구현했고, Xen은 게스트 OS를 수정해 특권 작업을 하이퍼콜로 요청하게 하는 반가상화(PV)로 이 문제를 피했습니다. 2005~2006년에 Intel VT-x와 AMD-V가 나오면서 CPU가 게스트 실행 모드를 직접 지원하게 되었고, 이후 EPT/NPT(2단계 주소 변환)가 메모리 가상화 비용까지 줄였습니다. 클라우드 문서에서 보이는 HVM과 PV라는 용어가 이 역사에서 나왔습니다. 현재는 CPU와 메모리는 하드웨어 보조 가상화로, 디스크와 네트워크는 virtio나 SR-IOV, ENA 같은 반가상화·전용 장치로 처리하는 조합이 일반적입니다.
컨테이너와의 관계
컨테이너는 호스트 커널을 공유하면서 네임스페이스로 프로세스·파일시스템·네트워크의 보이는 범위를 나누고, cgroups로 CPU·메모리 사용량을 제한합니다. 커널을 새로 부팅하지 않으므로 VM보다 훨씬 가볍게 시작하지만, 모든 컨테이너가 같은 커널을 쓰기 때문에 커널 취약점 하나가 격리를 무너뜨릴 수 있습니다. 그래서 퍼블릭 클라우드는 서로 다른 고객의 컨테이너를 같은 커널에 올리지 않습니다. 관리형 Kubernetes에서도 워커 노드는 고객별 VM이고, AWS Fargate나 Lambda처럼 여러 고객의 컨테이너·함수를 섞어 돌리는 서비스는 Firecracker 같은 경량 VM으로 하나씩 감쌉니다.
멀티테넌시와 리소스 격리
멀티테넌시란
멀티테넌시는 하나의 물리 인프라를 여러 고객(테넌트)이 나누어 쓰는 모델이며, 퍼블릭 클라우드의 경제성은 여기서 나옵니다. 대신 서로의 데이터, 연산, 네트워크가 섞이지 않도록 여러 층의 격리가 필요합니다.
격리의 층위
하드웨어와 하이퍼바이저 층에서는 VM마다 CPU 상태와 메모리를 분리하고, EPT/NPT로 게스트 물리 주소를 호스트 물리 주소로 변환해 다른 VM의 메모리에 접근할 수 없게 합니다. 네트워크 층에서는 VPC, 보안 그룹, 네트워크 ACL, 라우팅으로 패킷 경로를 제어하며, 테넌트의 패킷은 캡슐화되어 물리 네트워크 위에서 섞이지 않습니다. 스토리지 층에서는 볼륨 암호화와 버킷·볼륨 단위 접근 정책으로 데이터를 분리합니다. 관리 층에서는 IAM 역할과 감사 로그로 누가 어떤 API를 호출했는지를 분리하고 추적합니다.
하드웨어 격리도 완벽하지는 않습니다. 2018년의 Spectre와 Meltdown, 그 뒤의 L1TF와 MDS 계열 취약점은 같은 물리 코어를 공유하는 VM 사이에서 CPU 캐시와 버퍼를 통해 정보가 샐 수 있음을 보여 주었습니다. 그래서 주요 클라우드 사업자는 한 물리 코어의 하이퍼스레드 두 개를 서로 다른 고객에게 나눠 주지 않고 코어 단위로 할당하며, 하이퍼바이저에도 이런 부채널을 막는 완화책을 적용합니다.
noisy neighbor와 성능 변동
같은 호스트에 있는 이웃 VM이 공유 자원을 몰아 쓰면 내 VM의 지연이나 IOPS가 흔들릴 수 있는데, 이를 noisy neighbor 문제라고 부릅니다. vCPU를 전용으로 배정받는 인스턴스라도 L3 캐시, 메모리 대역폭, 네트워크 카드는 호스트 전체가 공유합니다. 클라우드는 이를 줄이기 위해 전용 호스트, 성능이 보장되는 인스턴스와 스토리지(프로비저닝 IOPS), 반대로 평소에는 기준 성능만 주고 크레딧이 있을 때만 버스트를 허용하는 저렴한 인스턴스(AWS T 계열 등) 같은 선택지를 둡니다.
버스트형 인스턴스는 특히 오해하기 쉽습니다. 개발 환경에서는 잘 돌다가 부하 테스트나 실제 트래픽에서 CPU 크레딧이 바닥나면 기준 성능(인스턴스 크기에 따라 vCPU의 일부)으로 떨어져 갑자기 느려집니다. 모니터링에서 CPU 사용률이 특정 값에 딱 붙어 있다면 크레딧 잔량 지표부터 확인하는 것이 좋습니다.
애플리케이션 쪽에서는 수평 확장, 큐 기반 비동기 처리, 캐시로 개별 인스턴스의 성능 변동을 흡수합니다. 평균 지연만 보면 이런 변동이 가려지므로 p99 같은 꼬리 지연을 함께 모니터링해야 합니다.
공유와 전용 사이의 선택지
일반 공유 인스턴스는 비용 효율이 가장 좋지만 이웃의 영향을 받을 수 있습니다. 전용 호스트나 전용 인스턴스는 물리 서버를 한 고객만 쓰도록 보장하므로, 규정 준수 요구나 소켓·코어 단위로 과금되는 소프트웨어 라이선스 때문에 선택하는 경우가 많습니다. 베어메탈 인스턴스는 하이퍼바이저 없이 물리 서버를 그대로 쓰므로 자체 하이퍼바이저를 올리거나, 성능 카운터 같은 하드웨어 기능에 직접 접근해야 하는 워크로드에 씁니다.
클라우드 네트워킹: VPC와 서브넷
VPC의 역할
VPC(Virtual Private Cloud)는 퍼블릭 클라우드 안에 만드는 논리적으로 격리된 네트워크입니다. 여기에 서브넷, 라우트 테이블, 인터넷 게이트웨이, NAT 게이트웨이, 그리고 VPN·전용선·프라이빗 링크 같은 사설 연결을 붙여, 온프레미스 네트워크 설계를 클라우드로 옮긴 것과 비슷한 구조를 만듭니다. VPC의 CIDR는 나중에 온프레미스나 다른 VPC와 연결할 가능성을 생각해 겹치지 않게 정해야 합니다. 대역이 겹치면 피어링이나 VPN으로 연결할 때 라우팅이 불가능해져서, 나중에 네트워크를 통째로 옮겨야 하는 일이 생깁니다.
서브넷과 가용 영역
서브넷은 VPC CIDR의 일부 IP 범위를 가진 세그먼트입니다. AWS에서는 서브넷 하나가 가용 영역(AZ) 하나에 속하며, AZ는 전원과 네트워크가 독립된 물리적으로 분리된 데이터센터 묶음입니다. 그래서 가용성을 위해 AZ마다 서브넷을 만들고, 로드밸런서 뒤에 여러 AZ의 인스턴스를 두는 것이 기본 패턴입니다. 한 AZ가 장애를 겪어도 다른 AZ가 트래픽을 받으려면 헬스 체크, 세션 처리, 데이터 복제 설계가 함께 필요합니다.
퍼블릭 서브넷과 프라이빗 서브넷
퍼블릭 서브넷은 라우트 테이블에 인터넷 게이트웨이로 가는 기본 경로가 있어서, 공인 IP를 가진 리소스가 인터넷과 직접 통신할 수 있습니다. 프라이빗 서브넷에는 그 경로가 없으므로 외부에서 직접 들어올 수 없고, 밖으로 나가야 할 때는 퍼블릭 서브넷의 NAT 게이트웨이를 거치거나, 클라우드 서비스에는 VPC 엔드포인트로 연결합니다. DB, 내부 API, 배치 워커는 프라이빗 서브넷에 두고, 로드밸런서처럼 외부 진입점만 퍼블릭 서브넷에 두는 구성이 일반적입니다.
NAT 게이트웨이는 처리한 데이터 양에 따라 과금되므로, 프라이빗 서브넷의 인스턴스가 S3에서 대용량 데이터를 받는 구조라면 NAT를 거치지 않도록 S3용 게이트웨이 엔드포인트를 두는 것이 비용 면에서 중요합니다. 청구서에서 예상하지 못한 NAT 데이터 처리 비용이 크게 나오는 경우 대부분이 이 경로 때문입니다.
보안 그룹과 네트워크 ACL
보안 그룹은 네트워크 인터페이스(ENI)에 붙는 상태 저장(stateful) 방화벽입니다. 허용 규칙만 쓸 수 있고, 허용된 연결의 응답 트래픽은 규칙과 관계없이 자동으로 허용됩니다. 규칙의 출발지로 IP 대역 대신 다른 보안 그룹을 지정할 수 있어서, “웹 서버 그룹에서 오는 5432 포트만 허용”처럼 역할 단위로 규칙을 쓸 수 있다는 점이 가장 큰 장점입니다.
네트워크 ACL은 서브넷 경계에 붙는 상태 비저장(stateless) 필터입니다. 허용과 거부 규칙을 모두 쓸 수 있고 번호 순서대로 평가됩니다. 상태를 기억하지 않으므로 응답 트래픽도 별도로 허용해야 하며, 특히 클라이언트 쪽 임시 포트(ephemeral port) 범위를 허용하지 않아 응답이 막히는 실수가 흔합니다. 실무에서는 대부분 보안 그룹으로 해결하고, 특정 IP 대역을 명시적으로 차단해야 하거나 규정상 서브넷 경계 통제가 필요할 때 NACL을 보조로 씁니다.
DNS와 내부 이름 해석
VPC 안에서는 클라우드가 제공하는 내부 DNS로 인스턴스와 관리형 서비스(RDS 엔드포인트 등)를 이름으로 찾습니다. 관리형 DB처럼 장애 조치 시 뒤의 IP가 바뀌는 서비스는 반드시 IP가 아니라 이 이름으로 접속해야 합니다. 온프레미스와 연결된 하이브리드 환경에서는 양쪽 DNS가 서로의 사설 도메인을 해석할 수 있도록 조건부 포워딩 규칙을 맞추는 것이 흔한 운영 과제입니다.
스토리지 유형과 성능
블록, 파일, 오브젝트
블록 스토리지는 인스턴스에 디스크처럼 붙여 파일시스템을 올리는 볼륨입니다(AWS EBS 등). OS 부팅 볼륨, DB 데이터 디렉터리처럼 작은 랜덤 I/O가 많은 워크로드에 맞고, 성능은 볼륨 유형(SSD 계열, HDD 계열)과 프로비저닝한 IOPS·처리량으로 정해집니다. 일반적으로 한 번에 하나의 인스턴스에만 붙이며, 네트워크를 통해 연결되는 원격 디스크라서 로컬 디스크보다 지연이 깁니다.
파일 스토리지는 NFS나 SMB 같은 파일 프로토콜로 여러 인스턴스가 동시에 마운트해 공유합니다(AWS EFS, FSx 등). 여러 서버가 같은 디렉터리를 봐야 하는 레거시 애플리케이션이나 콘텐츠 저장소에서 씁니다.
오브젝트 스토리지는 버킷과 키로 객체를 저장하고 HTTP(S) API로 접근합니다(AWS S3 등). 용량이 사실상 무제한으로 늘어나고, 버전 관리, 수명 주기 정책에 따른 저비용 계층 이동, 정적 웹 호스팅 같은 기능을 제공합니다. 대신 객체의 일부만 수정할 수 없고 전체를 다시 써야 하며, 파일시스템처럼 이름 변경이나 mmap, 작은 랜덤 쓰기를 기대하면 안 됩니다. 오브젝트 스토리지를 파일시스템처럼 마운트해 주는 FUSE 도구도 있지만, 이런 차이 때문에 DB 데이터 파일 같은 용도에는 맞지 않습니다.
성능을 말할 때의 세 가지 축
IOPS는 초당 입출력 연산 수로, 작은 랜덤 I/O가 많은 DB에서 중요합니다. 처리량(MB/s)은 대용량 순차 읽기·쓰기, ETL, 미디어 처리에서 중요합니다. 두 값은 I/O 크기로 연결되어 있어서, 16KB I/O로 3,000 IOPS를 내면 처리량은 약 47MB/s입니다. 볼륨에 IOPS 한도와 처리량 한도가 따로 있으므로, 어느 쪽 한도에 먼저 닿는지를 워크로드의 I/O 크기로 계산해 봐야 합니다.
지연은 개별 I/O 하나가 끝나는 시간이며, DB 트랜잭션의 커밋 지연처럼 순차적으로 기다리는 작업에서 직접 드러납니다. 인스턴스에 물리적으로 붙은 로컬 NVMe(인스턴스 스토어)는 네트워크 블록 스토리지보다 지연이 훨씬 짧지만, 인스턴스를 중지하거나 호스트가 교체되면 데이터가 사라집니다. 캐시, 임시 파일, 복제로 보호되는 데이터에만 쓰고, 영구 데이터와 섞지 않아야 합니다.
스냅샷, 복제, 백업
블록 볼륨 스냅샷은 첫 스냅샷 이후에는 변경된 블록만 저장하는 증분 방식이며, 다른 리전으로 복사하면 재해 복구의 한 축이 됩니다. 다만 실행 중인 DB 볼륨의 스냅샷은 크래시 시점과 같은 일관성만 보장하므로, DB가 복구 로그로 되살릴 수 있다고 해도 복원 절차를 실제로 테스트해 봐야 합니다. 오브젝트 스토리지는 버전 관리와 교차 리전 복제로 실수로 인한 삭제와 리전 장애에 대비합니다. 어떤 방식을 쓰든 복구 목표 시간(RTO)과 복구 목표 시점(RPO)을 문서로 정해 두고, 백업은 복원 훈련까지 해야 의미가 있습니다.
프로덕션 클라우드 패턴
가용성: 멀티 AZ와 헬스 체크
단일 AZ 배포는 해당 AZ의 전원, 네트워크, 유지 보수 이벤트에 그대로 노출됩니다. 프로덕션에서는 최소 두 개 이상의 AZ에 상태를 갖지 않는 애플리케이션 인스턴스를 두고, 로드밸런서 헬스 체크로 이상 노드를 제외합니다. 로그인 세션을 인스턴스 메모리에 두고 세션 고정(sticky session)에 의존하면 인스턴스나 AZ가 빠질 때 사용자가 로그아웃되므로, 세션을 Redis 같은 외부 저장소로 빼거나 서명된 토큰 방식으로 바꿉니다. 헬스 체크는 DB 연결까지 확인하는 깊은 검사로 만들면 DB 장애 시 모든 인스턴스가 한꺼번에 제외되는 일이 생기므로, 인스턴스 자체의 상태만 보는 얕은 검사와 구분해 설계합니다.
확장: 오토스케일링과 큐
트래픽 증가에 맞춰 인스턴스를 수평으로 늘리는 오토스케일링을 걸더라도, DB나 외부 API가 병목이면 인스턴스만 늘어나고 오히려 DB 연결 수가 폭증할 수 있습니다. 새 인스턴스가 부팅되어 트래픽을 받기까지 몇 분이 걸린다는 점도 고려해야 합니다. 요청을 바로 처리하지 않아도 되는 작업은 SQS나 Kafka 같은 큐로 유입을 평준화하고, 큐 길이를 기준으로 워커 수를 조절하는 패턴이 흔합니다. 큐 기반 처리에서는 같은 메시지가 두 번 전달될 수 있으므로 작업을 멱등하게 만들고, 재시도에는 지수 백오프를 쓰며, 계속 실패하는 메시지는 데드 레터 큐로 보내 전체 처리를 막지 않게 합니다.
보안: 최소 권한과 시크릿 관리
인스턴스나 파드에는 액세스 키 대신 IAM 역할을 붙여 임시 자격 증명을 받게 하고, 키를 코드나 이미지에 넣지 않습니다. DB 비밀번호 같은 시크릿은 시크릿 매니저에 두고 런타임에 가져옵니다. 개발, 스테이징, 프로덕션을 별도 계정으로 분리하면 실수나 침해의 영향 범위가 계정 경계에서 멈춥니다. 감사 로그(AWS CloudTrail 등)는 누가 언제 무엇을 바꿨는지 추적하는 유일한 수단이므로 삭제할 수 없는 위치에 보관합니다.
관측 가능성
클라우드가 제공하는 인프라 지표만으로는 애플리케이션이 왜 느린지 알기 어렵습니다. 요청률·에러율·지연(RED)과 자원 사용률·포화도·에러(USE) 같은 메트릭, 요청 ID를 포함한 구조화 로그, 서비스 사이를 잇는 분산 트레이싱을 애플리케이션에서 직접 내보내야 어느 구간이 느린지 볼 수 있습니다.
인프라를 코드로 관리
Terraform, Pulumi, AWS CDK 같은 도구로 VPC, 서브넷, 보안 그룹을 코드로 관리하면 변경을 리뷰할 수 있고 같은 환경을 다시 만들 수 있습니다. 콘솔에서 직접 바꾼 설정은 코드와 실제 상태가 어긋나는 드리프트를 만들고, 다음 배포에서 되돌려지거나 충돌합니다. 스테이징 환경의 네트워크 구조를 프로덕션과 같게 맞춰 두면 “스테이징에서는 됐는데 프로덕션에서는 보안 그룹 때문에 안 된다” 같은 문제를 미리 잡을 수 있습니다.
비용: 약정, 스팟, 수명 주기
온디맨드 요금은 약정 없이 유연하지만 가장 비쌉니다. 항상 돌아가는 기본 부하는 예약 인스턴스나 Savings Plans 같은 약정 할인으로, 중단되어도 다시 시작할 수 있는 배치 작업이나 CI 러너, 상태 없는 워커는 스팟(선점형) 인스턴스로 처리하면 비용이 크게 줄어듭니다. 스팟 인스턴스는 사업자가 용량이 필요하면 짧은 예고(AWS는 2분) 후 회수하므로, 작업을 체크포인트로 나누고 중단 신호를 처리하도록 만들어야 합니다. 오브젝트 스토리지는 수명 주기 정책으로 오래된 데이터를 저비용 계층으로 옮기거나 삭제합니다.
참고로 읽을 글
같은 블로그의 AWS 입문 가이드(EC2·S3·RDS)는 콘솔 실습 흐름과 연결해 읽기 좋고, Astro + Cloudflare Pages 스택 비교는 엣지·정적 배포 관점을 보완합니다.
자주 묻는 질문 (FAQ)
Q. 같은 인스턴스 타입인데 시간대에 따라 지연이나 IOPS가 흔들리는 이유는 무엇인가요?
퍼블릭 클라우드의 VM은 보통 물리 호스트를 다른 고객과 공유하므로, 같은 호스트의 이웃 VM이 캐시, 메모리 대역폭, 네트워크를 몰아 쓰면 내 VM의 성능도 영향을 받습니다. 버스트형 인스턴스나 버스트형 볼륨을 쓰고 있다면 크레딧이 소진되어 기준 성능으로 떨어졌을 가능성도 먼저 확인해야 합니다. 성능 편차가 치명적인 워크로드라면 전용 호스트나 성능이 보장되는 인스턴스·스토리지 옵션을 검토하고, 평균값이 아니라 p99 같은 꼬리 지연을 모니터링해야 이런 변동을 알아챌 수 있습니다.