하드웨어 기초 #7 가상화와 컨테이너 — 물리 서버 한 대가 여러 대가 되는 원리
#6까지 한 대의 서버를 이루는 네 자원을 모두 봤습니다. 그런데 클라우드는 물리 서버 한 대를 수십 대처럼 나눠 팝니다. EC2 인스턴스 하나가 통째 물리 서버일 리는 없습니다. 이 나눔을 가능하게 하는 것이 가상화이고, 그 위에서 더 가볍게 나누는 방식이 컨테이너입니다. 이번 글은 그 원리를 정리합니다.
하드웨어 기초 시리즈에서 이번 글의 위치입니다.
- #1 컴퓨터를 움직이는 네 가지 자원 — CPU / 메모리 / 스토리지 / 네트워크
- #2 CPU — 코어 / 스레드 / 클럭 / 캐시, 그리고 vCPU의 정체
- #3 메모리 — RAM과 계층 구조, 스왑이 시작되면 벌어지는 일
- #4 스토리지 ① 장치 — HDD / SSD / NVMe와 IOPS / 처리량 / 지연시간
- #5 스토리지 ② 구성과 연결 — RAID와 DAS / NAS / SAN
- #6 네트워크 — 대역폭과 지연시간, NIC에서 데이터센터까지
- #7 가상화와 컨테이너 — 물리 서버 한 대가 여러 대가 되는 원리 ← 이번 글
- #8 클라우드 — 소유에서 임대로, 온프레미스부터 IaaS / PaaS / SaaS까지
- #9 클라우드 인스턴스 사양 읽는 법 — 워크로드에 맞춰 고르기
왜 한 대를 나누는가 #
물리 서버 한 대는 대개 평소에 자원이 남습니다. 한 서비스가 CPU와 메모리를 항상 가득 쓰는 일은 드뭅니다. 서비스마다 서버를 한 대씩 사면 남는 자원만큼 비용이 낭비됩니다.
가상화는 이 남는 자원을 끌어모아, 한 대를 여러 개의 독립된 환경으로 나눕니다. 각 환경은 자기만의 서버처럼 보이고 서로 격리됩니다. 활용도가 올라가고, 환경을 분 단위로 만들고 지울 수 있게 됩니다. 클라우드가 “필요한 만큼 빌려 쓴다"를 가능하게 한 토대가 바로 이것입니다.
가상화 — 하이퍼바이저가 하드웨어를 나눈다 #
물리 서버 위에 **하이퍼바이저(Hypervisor)**라는 층을 두고, 그 위에 여러 개의 **가상 머신(VM)**을 올립니다. 하이퍼바이저는 물리 자원을 쪼개 각 VM에 나눠주고, VM들이 서로 침범하지 못하게 격리합니다.
각 VM은 자기만의 운영체제를 통째로 가집니다. VM 입장에서는 진짜 하드웨어 위에서 도는 것처럼 보이고, 그 안에 리눅스든 윈도우든 따로 설치합니다. EC2 인스턴스 하나가 바로 이 VM 하나에 해당합니다.
┌──────────┐ ┌──────────┐ ┌──────────┐
│ 앱 A │ │ 앱 B │ │ 앱 C │
│ OS │ │ OS │ │ OS │ ← VM마다 OS 한 벌
└──────────┘ └──────────┘ └──────────┘
하이퍼바이저
물리 서버 (CPU,메모리,스토리지,네트워크)VM은 격리가 강합니다. 한 VM 안에서 무슨 일이 나도 다른 VM과 물리 서버에는 영향이 거의 없습니다. 대신 OS를 통째로 올리므로 메모리와 디스크를 많이 쓰고, 켜는 데 시간이 걸립니다.
컨테이너 — OS 커널을 공유한다 #
컨테이너는 다른 길을 택합니다. OS를 VM마다 따로 두지 않고, 호스트의 OS 커널을 여러 컨테이너가 공유합니다. 컨테이너는 그 위에서 프로세스 단위로 격리될 뿐, 자기 OS를 통째로 갖지 않습니다.
┌──────┐ ┌──────┐ ┌──────┐
│ 앱 A │ │ 앱 B │ │ 앱 C │ ← OS 없이 앱과 의존성만
└──────┘ └──────┘ └──────┘
컨테이너 런타임
공유 OS 커널
물리 서버 또는 VMOS 한 벌을 공유하므로 컨테이너는 가볍습니다. 메모리를 덜 쓰고, 켜는 데 몇 초가 아니라 순식간입니다. 같은 서버에 VM보다 훨씬 많이 올릴 수 있습니다. 이 가벼움이 도커와 쿠버네티스가 자리잡은 이유입니다. 대신 커널을 공유하므로 격리는 VM보다 약합니다.
| 항목 | 가상 머신(VM) | 컨테이너 |
|---|---|---|
| OS | VM마다 한 벌 | 호스트 커널 공유 |
| 무게 | 무거움(GB 단위) | 가벼움(MB 단위) |
| 시작 시간 | 수십 초 | 수 초 이내 |
| 격리 | 강함 | 상대적으로 약함 |
| 한 서버에 올리는 수 | 수 개~수십 개 | 수십~수백 개 |
실무에서는 둘을 겹쳐 씁니다. 클라우드가 물리 서버를 VM(인스턴스)으로 나눠 빌려주고, 사용자는 그 인스턴스 안에서 다시 컨테이너를 여럿 돌립니다.
자원은 어떻게 나뉘고 한도가 걸리나 #
나눈 환경들이 자원을 두고 싸우지 않으려면 각자의 몫에 한도가 있어야 합니다. 리눅스는 cgroups라는 기능으로 프로세스 그룹마다 CPU,메모리,입출력의 한도를 겁니다. 컨테이너의 자원 제한이 이 위에서 동작합니다.
- CPU — #2의 vCPU가 여기서 나뉩니다. 인스턴스에 할당된 vCPU를 그 안의 컨테이너들이 한도 안에서 나눠 씁니다.
- 메모리 — #3에서 짚었듯 컨테이너에 메모리 한도를 걸지 않으면 하나가 호스트 메모리를 삼켜 다른 컨테이너까지 위협합니다. 한도를 넘으면 그 컨테이너의 프로세스가 종료됩니다.
오버커밋과 노이지 네이버 #
가상화의 활용도에는 그늘이 있습니다. 클라우드 사업자는 물리 자원보다 더 많은 양을 VM들에 약속하기도 합니다. 모든 VM이 동시에 자원을 가득 쓰지는 않는다는 전제 위에서입니다. 이것을 **오버커밋(overcommit)**이라고 합니다.
평소에는 문제가 없지만, 같은 물리 서버에 올라간 다른 VM이 갑자기 자원을 몰아 쓰면 내 VM의 성능이 출렁입니다. 이 현상을 **노이지 네이버(noisy neighbor)**라고 합니다. “어제는 멀쩡하던 인스턴스가 오늘은 느리다"의 한 원인입니다.
성능이 흔들리면 안 되는 워크로드는 자원을 독점하는 인스턴스 타입을 고르거나, 한 물리 서버를 통째로 빌리는 전용 옵션을 씁니다. 이런 선택은 #9의 인스턴스 타입 결정과 이어집니다.
자주 만나는 함정 #
“컨테이너는 가벼운 VM이다” #
비슷해 보이지만 다릅니다. VM은 OS를 통째로 가지고 격리가 강하며, 컨테이너는 커널을 공유해 가볍지만 격리가 약합니다. 격리 수준이 중요한 워크로드는 이 차이를 따져야 합니다.
“컨테이너에 한도를 안 걸었다” #
한도가 없으면 한 컨테이너가 호스트 자원을 독점해 다른 컨테이너를 굶깁니다. 운영에서는 CPU와 메모리 한도를 명시하는 것이 안전합니다.
“인스턴스 성능이 들쭉날쭉한데 원인을 모르겠다” #
오버커밋 환경의 노이지 네이버일 수 있습니다. 일관된 성능이 필요하면 자원을 독점하는 타입이나 전용 인스턴스를 검토합니다.
“VM 위에 컨테이너는 낭비다” #
오히려 표준입니다. 클라우드 인스턴스(VM)의 강한 격리 위에, 그 안에서 컨테이너의 가벼운 배포를 함께 얻는 구성입니다.
정리 #
이번 글에서 잡은 그림입니다.
- 가상화는 남는 자원을 끌어모아 한 대의 물리 서버를 여러 독립 환경으로 나눕니다.
- 하이퍼바이저가 하드웨어를 나누고, 각 VM은 자기 OS를 통째로 가집니다. EC2 인스턴스가 그 VM입니다.
- 컨테이너는 호스트 커널을 공유해 가볍지만 격리는 VM보다 약합니다. 도커와 쿠버네티스의 토대입니다.
- 자원은 cgroups로 한도가 걸립니다. 컨테이너 메모리 한도는 명시하는 것이 안전합니다.
- 오버커밋과 노이지 네이버는 클라우드 성능이 출렁이는 한 원인입니다.
다음 — 클라우드 #
가상화는 클라우드가 자원을 나눠 파는 토대였습니다. 이제 그 위의 그림, 클라우드 자체를 정리합니다. #8 클라우드 — 소유에서 임대로, 온프레미스부터 IaaS / PaaS / SaaS까지에서는 하드웨어를 소유에서 임대로 바꾼 변화, 온프레미스와 코로케이션과 클라우드의 차이, 그리고 IaaS,PaaS,SaaS가 하드웨어를 어디까지 감추는지를 정리하겠습니다.