1. 프롤로그 - EC2 청구서를 보고 충격받았던 날
클라우드에서 서버를 여러 대 운영하다 보면, 매달 청구서가 나올 때마다 가슴이 철렁하는 순간이 온다. "CPU 사용률 5%인데 왜 이렇게 많이 나가지?" 관련 문서를 찾다 보면 공통된 조언을 만나게 된다. "컨테이너로 전환해봐. 서버 비용이 1/5로 줄어들 거야."
그래서 도커를 공부하기 시작했는데, 처음엔 완전히 헷갈렸다. "도커는 가벼운 VM이다"라고 이해했는데, 나중에 알고 보니 이건 완전히 틀린 개념이었다. VM과 컨테이너는 근본적으로 다른 기술이다. 마치 아파트와 쉐어하우스처럼.
아파트(VM)는 각 세대마다 화장실, 부엌, 보일러가 다 따로 있다. 완전히 독립적이다. 옆집이 불나도 나랑은 상관없다. 반면 쉐어하우스(Container)는 부엌(커널)을 공유하지만, 방(namespace)은 분리되어 있다. 가벼운 대신 옆집에서 부엌에 불을 내면 나도 위험하다.
이 차이를 제대로 이해하고 나니, 왜 AWS Fargate가 고객마다 커널을 분리하는지, 왜 Firecracker가 탄생했는지, 왜 Docker Desktop이 Mac에서 느린지 모든 게 와닿았다. 그 과정에서 정리한 내용을 공유해본다.
2. 삽질 스토리 - "Docker는 가상머신 아니었어?"
첫 번째 착각은 이거였다. "Docker = 가벼운 VirtualBox"라고 생각했다. 틀렸다.
VirtualBox (VM 방식)
- VirtualBox를 켜면 Ubuntu가 부팅된다 (GRUB 화면이 뜬다)
- 그 안에서
uname -r치면 Ubuntu 커널이 나온다 - CPU, RAM, 하드디스크가 가상으로 에뮬레이션된다
- 호스트가 Windows여도 게스트는 Linux를 돌릴 수 있다
Docker (Container 방식)
- Docker를 실행하면 호스트 커널이 그대로 사용된다
docker run ubuntu bash해서 들어가도, 커널은 호스트 Mac/Linux 커널이다- CPU, RAM은 에뮬레이션 없이 직접 쓴다 (오버헤드 0%)
- Mac에서 Linux 컨테이너를 돌리면? 사실 내부적으로 Linux VM을 먼저 띄운다
이걸 실감한 순간이 있었다. Mac에서 docker stats 명령을 쳤는데, CPU 사용률이 이상하게 높았다. 알고 보니 Docker Desktop은 HyperKit이라는 경량 VM 위에서 Linux 커널을 돌리고, 그 위에서 컨테이너를 실행하고 있었던 거다. 그래서 Mac에서 Docker가 느린 거였다. 리눅스 서버에서 직접 돌리는 것과는 체감이 완전히 달랐다.
# Mac에서 Docker 실행하면 실제로는 이런 구조
HyperKit (VM) → Linux Kernel → Docker Container
결국 이거였다: 컨테이너는 "OS를 공유하는" 기술이다. 그래서 Linux 컨테이너는 Linux 호스트에서만 네이티브로 돌아간다. Windows나 Mac에서는 어차피 VM을 거쳐야 한다.
3. 가상화의 역사 - 1964년부터 2024년까지
기술의 흐름을 이해하면, 미래가 보인다고 받아들였다.
- 1964: IBM CP-40. 메인프레임 시분할을 위해 최초의 가상머신 개념 등장. 당시엔 컴퓨터 한 대가 억 단위였으니, 쪼개 쓰는 게 필수였다.
- 1999: VMware Workstation 출시. x86 아키텍처 가상화의 대중화. 이때부터 PC 하나로 리눅스 공부가 가능해졌다.
- 2003: Xen Hypervisor 오픈소스 공개. AWS EC2의 기반 기술이 된다.
- 2006: Linux cgroups 구글 엔지니어들이 커밋. 컨테이너의 자원 제한 기반 기술.
- 2008: LXC (Linux Containers) 등장. namespaces와 cgroups를 결합한 최초의 완성형 컨테이너.
- 2013: Docker 등장. LXC를 개발자도 쓸 수 있게 포장하여 혁명을 일으킴. Dockerfile 한 장으로 배포가 가능해졌다.
- 2018: AWS Firecracker 공개. Lambda 함수를 각각 MicroVM에 격리하는 기술. VM의 보안성과 컨테이너의 속도를 결합.
- 2024: WebAssembly (Wasm) on Server가 부상 중. 제3의 경량 격리 기술로 떠오르고 있다.
4. VM 깊게 파보기 - 하이퍼바이저 Type 1 vs Type 2
VM을 생성하고 구동하는 소프트웨어를 하이퍼바이저(Hypervisor) 또는 VMM(Virtual Machine Monitor)이라고 한다.
Type 1: Bare-metal (Native)
하드웨어 바로 위에 설치된다. Host OS가 없다.
- 제품: VMware ESXi, Microsoft Hyper-V, Citrix Xen, KVM (커널 모듈이지만 성능상 Type 1)
- 장점: 오버헤드가 극도로 적다. 엔터프라이즈 데이터센터, AWS/GCP 같은 클라우드가 이 방식을 쓴다.
- 단점: 설치가 까다롭다. 일반 개발자는 거의 안 쓴다.
Type 2: Hosted
Windows나 macOS 같은 Host OS 위에 응용 프로그램으로 설치된다.
- 제품: VirtualBox, VMware Fusion/Workstation, Parallels Desktop
- 장점: 설치가 쉽다. 개발/테스트용으로 최고.
- 단점: 하드웨어 접근 시 Host OS의 드라이버를 거쳐야 하므로 느리다.
내가 처음 리눅스를 공부할 때 VirtualBox를 썼는데, 가끔 디스크 I/O가 답답할 정도로 느렸던 이유가 바로 이거였다. 디스크 읽기/쓰기가 게스트 OS → VirtualBox → Host OS 드라이버 → 하드웨어 이렇게 세 단계를 거치니 당연히 병목이 생긴다.
성능 특성 (Performance Profile)
- CPU: Intel VT-x, AMD-V 하드웨어 가상화 지원 덕분에 네이티브의 95-99% 성능이 나온다.
- Memory: Guest OS가 부팅되면서 커널용 메모리를 미리 점유한다 (고정 할당). Ubuntu VM 하나 띄우면 최소 512MB~1GB는 무조건 먹는다.
- I/O: 디스크와 네트워크는 에뮬레이션을 거치므로 병목이 발생할 수 있다. 그래서 Virtio 같은 반가상화(Paravirtualization) 드라이버를 쓴다.
5. 컨테이너 깊게 파보기: Namespace, Cgroups, Capability
컨테이너는 별도의 OS가 아니다. Host OS 커널 입장에서는 그저 PID, UID, Network가 분리된 프로세스일 뿐이다.
Namespace: 격리의 마법 (The Isolation Magic)
Namespace는 프로세스에게 "너는 혼자야"라고 거짓말을 한다.
- PID Namespace: 컨테이너 안에서
ps aux치면 PID 1번(init)부터 시작하는 것처럼 보인다. 하지만 호스트에서 보면 평범한 PID 12345번 프로세스다. - MNT Namespace: 컨테이너는 자기만의 루트 디렉토리(
/)를 가진 것처럼 보인다. 실제로는 호스트의/var/lib/docker/overlay2/xyz/경로다. - NET Namespace: 컨테이너는 자기만의 IP 주소(
172.17.0.2)를 가진 것처럼 보인다. 호스트는veth가상 네트워크 인터페이스로 이를 연결한다.
# 실제로 Docker 컨테이너 실행하면 이렇게 된다
docker run -d nginx
# 호스트에서 보면
ps aux | grep nginx
# root 12345 0.0 0.1 nginx: master process
# PID는 12345번인데, 컨테이너 안에서는 PID 1번으로 보인다
Cgroups: 자원 배급 시스템 (Resource Rationing)
Cgroups는 "너는 이만큼만 써"라고 제한을 건다.
- CPU:
--cpus=1.5옵션을 주면, CPU 코어 1.5개만큼만 쓸 수 있다. - Memory:
--memory=512m옵션을 주면, 512MB 넘어가는 순간 OOM Killer가 프로세스를 죽인다. - Disk I/O:
--device-write-bps옵션으로 디스크 쓰기 속도를 제한할 수 있다.
# Docker 컨테이너에 리소스 제한 걸기
docker run -d \
--cpus=0.5 \
--memory=256m \
--name limited-nginx \
nginx
실제로 한번은 컨테이너가 메모리를 무한정 잡아먹어서 호스트가 다운됐던 적이 있었다. 그 이후로는 무조건 --memory 제한을 건다. 특히 프로덕션에서는 필수다.
Capability: 루트 권한 쪼개기 (Root Privilege Splitting)
리눅스의 root 권한은 너무 막강하다. 시스템 시간 변경, 커널 모듈 로드, 네트워크 설정 변경 등 뭐든 할 수 있다. Capability는 이 권한을 30개 정도로 잘게 쪼갠다.
CAP_NET_ADMIN: 네트워크 설정 변경 가능CAP_SYS_TIME: 시스템 시간 변경 가능CAP_SYS_MODULE: 커널 모듈 로드 가능
Docker는 기본적으로 위험한 Capability를 다 제거한다. 그래서 컨테이너 안에서 sudo reboot를 쳐도 안 먹힌다.
6. 보안 비교 - 가장 치명적인 차이 (The Kill Switch)
"컨테이너는 뚫릴 수 있다." 이것이 클라우드 제공자들의 악몽이었다.
VM Security: Hard Isolation
VM은 하드웨어 가상화 기술을 통해 메모리 영역을 철저히 분리한다. VM 하나가 악성코드에 감염되어도, 하이퍼바이저를 뚫고 호스트 머신을 장악하거나 옆의 VM을 공격하는 것(VM Escape)은 매우 어렵다. CPU의 MMU(Memory Management Unit)가 하드웨어 레벨에서 메모리를 분리하기 때문이다.
Container Security: Soft Isolation (Kernel Sharing Risk)
모든 컨테이너가 하나의 커널을 공유한다. 만약 커널에 버그가 있다면?
- 예시 1: Dirty COW 취약점 (CVE-2016-5195). 커널 메모리를 덮어쓸 수 있는 버그.
- 예시 2: 컨테이너 A에서 해커가 커널 취약점을 이용해 호스트 루트 권한을 얻으면, 옆집 컨테이너 B의 데이터도 다 볼 수 있다.
그래서 AWS Fargate 같은 퍼블릭 컨테이너 서비스는, 서로 모르는 고객의 컨테이너를 같은 서버(커널) 위에서 절대 돌리지 않는다. 고객마다 EC2 인스턴스를 분리하거나, Firecracker MicroVM으로 격리한다.
실제로 --privileged 옵션 관련 보안 사고 사례가 문서에 많이 나온다. 개발자가 실수로 이 옵션을 켜고 컨테이너를 띄웠다가, 그 컨테이너가 해킹당하면서 호스트 전체가 장악당할 뻔한 케이스다. 그래서 프로덕션에서는 --privileged 옵션을 절대 쓰지 않는 게 원칙이다.
7. 미래 기술 - MicroVM과 gVisor (Convergence)
VM의 보안성과 컨테이너의 속도를 합치려는 시도가 "Sandbox Container"다.
Firecracker (AWS Lambda의 비밀)
불필요한 장치(USB, 키보드, 모니터)를 다 뺀 초경량 KVM 기반 VM이다.
- 부팅 속도: 125ms
- 메모리 오버헤드: 5MB
- 사용 방식: 각 Lambda 함수를 Firecracker VM 안에 가둬서 실행한다.
AWS는 왜 이걸 만들었을까? 멀티테넌시 보안 때문이다. 고객 A의 Lambda 함수와 고객 B의 Lambda 함수를 같은 커널 위에서 돌리면 위험하다. 그래서 각각 MicroVM에 격리한다. 컨테이너만큼 빠르면서 VM만큼 안전하다.
gVisor (Google Cloud Run의 비밀)
애플리케이션과 호스트 커널 사이에 "가짜 커널(Sentry)"을 끼워 넣는다. Sentry는 Go 언어로 작성됐다.
- 동작 방식: 앱이 시스템 콜(
open,read,write)을 하면, gVisor가 중간에서 가로채 검사하고 안전하게 처리한다. - 장점: 시스템 콜 레벨에서 샌드박싱이 가능하다. 커널 취약점으로부터 안전하다.
- 단점: 시스템 콜마다 오버헤드가 있다. 일반 컨테이너보다 10-15% 느리다.
Google Cloud Run이 여러 고객의 컨테이너를 같은 노드에서 돌릴 수 있는 이유가 바로 gVisor 덕분이다.
8. 비용 분석: EC2 vs Fargate vs Lambda
기술적 차이보다 중요한 게 비용(TCO)이다. 청구서를 보면 답이 나온다.
| 항목 | EC2 (VM) | Fargate (Container) | Lambda (Function) |
|---|---|---|---|
| 과금 기준 | 인스턴스 실행 시간 (초) | CPU/Memory 사용량 (초) | 요청 수 + 실행 시간 (ms) |
| 유휴 비용 | 트래픽 없어도 100% 비용 발생 | 트래픽 없어도 100% 비용 발생 | 0원 (Zero Scale) |
| 관리 비용 | OS 패치, 보안 업데이트 직접 함 | AWS가 OS 관리 | AWS가 런타임 관리 |
| 적합한 상황 | 24시간 돌아가는 베이스 로드 | 가변적인 워크로드, 배치 작업 | 간헐적인 이벤트, API |
실제 사례 - 비용 최적화 예시
- Before: EC2 t3.medium 여러 대 (24시간 가동) → 상당한 월 비용
- After: Fargate Task (피크 타임에만 스케일 아웃) → 비용 대폭 절감
컨테이너로 전환하면 서버 비용을 60% 이상 절감할 수 있다는 사례가 많다. 다만 Fargate도 유휴 시간엔 비용이 나간다. 그래서 간헐적인 API는 Lambda로 전환하는 방식도 많이 쓴다. 트래픽이 없으면 비용이 0원이니까.
9. 선택 가이드 - 언제 VM을 쓰고, 언제 컨테이너를 쓸까?
컨테이너를 써야 할 때 (90%의 경우)
- 일반적인 웹/앱 백엔드
- 마이크로서비스 아키텍처
- CI/CD 파이프라인
- 개발 환경 통일 (Docker Compose)
VM을 써야 할 때
- 보안이 생명인 금융/헬스케어 (멀티테넌트)
- 서로 다른 OS 필요 (Linux 호스트에서 Windows 앱 실행)
- 레거시 애플리케이션 (컨테이너화 불가능)
하이브리드 - VM 안에 컨테이너
요즘 트렌드는 Containers in VMs다. AWS EKS는 EC2 인스턴스(VM) 위에서 쿠버네티스 포드(Container)를 돌린다. 두 겹의 격리를 얻는다.
Bare Metal → Type 1 Hypervisor → EC2 VM → Kubernetes → Container
이게 현대 클라우드의 표준 아키텍처다.
10. 정리하며 - 경계가 흐려지는 미래
처음엔 VM과 컨테이너가 완전히 다른 세계였다. 하지만 지금은 Kata Containers (컨테이너를 VM으로 실행), Firecracker (MicroVM), gVisor (샌드박스 컨테이너) 같은 기술로 경계가 흐려지고 있다.
결국 이거였다: 성능, 보안, 비용 중 2개만 선택할 수 있다. 그래서 상황에 맞는 기술을 고르는 게 중요하다.
- 빠르고 저렴하지만 보안이 약한 → 일반 컨테이너
- 빠르고 안전하지만 비싼 → MicroVM
- 안전하고 저렴하지만 느린 → VM
나는 이제 청구서를 보면서 떨지 않는다. 적재적소에 기술을 쓰는 법을 배웠으니까.
Virtual Machine vs Containers: My Journey Through Cloud Billing Hell
1. Prologue: The Day I Got My AWS Bill
Running multiple servers in the cloud, you eventually hit that moment when the monthly AWS bill makes you wince. "Why am I paying this much when my CPU usage is 5%?" Search through the documentation and communities and you keep finding the same advice: "Switch to containers. You'll cut your server costs by 80%."
So I dove into Docker. At first, I was completely confused. I thought "Docker is just a lightweight VM." Turns out, that's completely wrong. VMs and containers are fundamentally different technologies. Think of it like apartments vs co-living spaces.
An apartment (VM) has its own bathroom, kitchen, and boiler. Completely independent. If your neighbor's place catches fire, you're safe. But a co-living space (Container) shares the kitchen (kernel) while keeping bedrooms (namespaces) separate. It's lighter, but if someone sets the kitchen on fire, everyone's in danger.
Once I understood this difference, everything clicked. Why AWS Fargate isolates kernels per customer. Why Firecracker was invented. Why Docker Desktop is slow on Mac. Let me share what I learned the hard way.
2. The Confusion: "Wait, Docker Isn't a VM?"
My first misconception was thinking "Docker = lightweight VirtualBox." Wrong.
VirtualBox (VM approach)
- When you start VirtualBox, Ubuntu boots (you see the GRUB screen)
- Running
uname -rinside shows the Ubuntu kernel - CPU, RAM, and disk are virtually emulated
- You can run Linux guests on a Windows host
Docker (Container approach)
- Docker uses the host kernel directly
- Even if you
docker run ubuntu bash, the kernel is your host Mac/Linux kernel - CPU and RAM are used directly, zero emulation overhead
- Running Linux containers on Mac? Docker Desktop secretly spins up a Linux VM first
I realized this when I ran docker stats on my Mac and CPU usage was suspiciously high. Turns out Docker Desktop runs HyperKit (a lightweight VM), boots a Linux kernel inside it, and then runs containers on that. That's why Docker feels slower on Mac. Running it natively on a Linux server is a completely different experience.
# On Mac, Docker actually works like this:
HyperKit (VM) → Linux Kernel → Docker Container
The key insight: Containers "share the OS." Linux containers run natively only on Linux hosts. On Windows or Mac, you're always going through a VM layer anyway.
3. The Timeline: From 1964 to 2024
Understanding the technology evolution helps predict the future.
- 1964: IBM CP-40. The first virtual machine concept for mainframe time-sharing. Back then, computers cost millions, so sharing was essential.
- 1999: VMware Workstation released. x86 virtualization went mainstream. You could finally study Linux on a single PC.
- 2003: Xen Hypervisor open-sourced. This became the foundation of AWS EC2.
- 2006: Linux cgroups committed by Google engineers. The resource limitation foundation for containers.
- 2008: LXC (Linux Containers) emerged. The first complete container combining namespaces and cgroups.
- 2013: Docker launched. Made LXC developer-friendly and sparked a revolution. One Dockerfile could define your entire deployment.
- 2018: AWS Firecracker released. Isolates each Lambda function in a MicroVM. Combines VM security with container speed.
- 2024: WebAssembly (Wasm) on the server is rising. The third lightweight isolation technology.
4. Deep Dive: VM Architecture and Hypervisor Types
The software that creates and runs VMs is called a Hypervisor (or VMM - Virtual Machine Monitor).
Type 1: Bare-metal (Native)
Installed directly on hardware. No host OS.
- Products: VMware ESXi, Microsoft Hyper-V, Citrix Xen, KVM (technically a kernel module, but performs like Type 1)
- Pros: Minimal overhead. Used in enterprise datacenters and cloud providers (AWS/GCP).
- Cons: Complex setup. Most developers never touch it.
Type 2: Hosted
Installed as an application on a host OS (Windows/macOS).
- Products: VirtualBox, VMware Fusion/Workstation, Parallels Desktop
- Pros: Easy to install. Perfect for dev/test environments.
- Cons: Slow because hardware access goes through the host OS drivers.
When I first studied Linux using VirtualBox, disk I/O was painfully slow. Now I know why. Every disk read/write went through Guest OS → VirtualBox → Host OS drivers → Hardware. Three layers of indirection.
Performance Characteristics
- CPU: Thanks to hardware virtualization (Intel VT-x, AMD-V), you get 95-99% of native performance.
- Memory: The guest OS reserves kernel memory on boot (fixed allocation). Spinning up an Ubuntu VM consumes at least 512MB-1GB just for the OS.
- I/O: Disk and network go through emulation, causing bottlenecks. That's why paravirtualization drivers like Virtio exist.
5. Deep Dive: Container Internals (Namespace, Cgroups, Capabilities)
A container isn't a separate OS. From the host kernel's perspective, it's just a process with isolated PID, UID, and network.
Namespace: The Isolation Magic
Namespaces lie to the process, saying "You're alone."
- PID Namespace: Running
ps auxinside a container shows PID 1 (init). But from the host, it's just process 12345. - MNT Namespace: The container sees its own root directory (
/). But it's actually/var/lib/docker/overlay2/xyz/on the host. - NET Namespace: The container thinks it has its own IP (
172.17.0.2). The host connects it via avethvirtual network interface.
# When you run a Docker container
docker run -d nginx
# On the host, you see
ps aux | grep nginx
# root 12345 0.0 0.1 nginx: master process
# It's PID 12345 on the host, but PID 1 inside the container
Cgroups: Resource Rationing
Cgroups say "You can only use this much."
- CPU:
--cpus=1.5limits the container to 1.5 CPU cores. - Memory:
--memory=512mkills the process (OOM Killer) if it exceeds 512MB. - Disk I/O:
--device-write-bpsthrottles disk write speed.
# Limiting container resources
docker run -d \
--cpus=0.5 \
--memory=256m \
--name limited-nginx \
nginx
I once had a container eat infinite memory and crash the host. Ever since, I always set --memory limits. Especially in production. Non-negotiable.
Capabilities: Splitting Root Privileges
Linux root is too powerful. It can change system time, load kernel modules, modify network settings, etc. Capabilities split this into ~30 fine-grained permissions.
CAP_NET_ADMIN: Modify network settingsCAP_SYS_TIME: Change system timeCAP_SYS_MODULE: Load kernel modules
Docker removes dangerous capabilities by default. That's why sudo reboot inside a container doesn't work.
6. Security Comparison: The Critical Difference
"Containers can be breached." This was the cloud provider's nightmare.
VM Security: Hard Isolation
VMs use hardware virtualization to strictly separate memory regions. If one VM gets infected with malware, escaping the hypervisor to compromise the host or attack neighboring VMs (VM Escape) is extremely difficult. The CPU's MMU (Memory Management Unit) separates memory at the hardware level.
Container Security: Soft Isolation (Kernel Sharing Risk)
All containers share one kernel. What if the kernel has a bug?
- Example 1: Dirty COW vulnerability (CVE-2016-5195). A bug allowing kernel memory overwrites.
- Example 2: If a hacker exploits a kernel vulnerability from Container A to gain host root, they can see all data from Container B.
That's why AWS Fargate never runs different customers' containers on the same kernel. They either isolate EC2 instances per customer or use Firecracker MicroVMs.
Security incident reports around the --privileged flag are common in the wild. A developer accidentally uses this flag, the container gets compromised, and the entire host is nearly taken over. That's why --privileged should be banned in production environments.
Container Defense-in-Depth
To secure containers, we layer defenses:
- Seccomp: Filter system calls. Block dangerous ones like
reboot(),swapon(). - AppArmor/SELinux: Profile-based Mandatory Access Control.
- User Namespaces: Map container
root(UID 0) to hostnobody(UID 65534). - Read-only Filesystem: Prevent attackers from downloading malware or modifying binaries.
7. The Future: MicroVMs and gVisor (Convergence)
The industry is trying to combine VM security with container speed. Enter "Sandbox Containers."
Firecracker (The Secret Behind AWS Lambda)
A stripped-down KVM-based VM with unnecessary devices removed (USB, keyboard, monitor).
- Boot Time: 125ms
- Memory Overhead: 5MB
- How It's Used: Each Lambda function runs inside its own Firecracker VM.
Why did AWS build this? Multi-tenancy security. Running Customer A's Lambda and Customer B's Lambda on the same kernel is risky. So each gets its own MicroVM. As fast as containers, as secure as VMs.
# Firecracker architecture
Firecracker MicroVM → Minimal Linux Kernel → Lambda Function Container
gVisor (The Secret Behind Google Cloud Run)
Inserts a "fake kernel (Sentry)" between the app and host kernel. Sentry is written in Go.
- How It Works: When the app makes a system call (
open,read,write), gVisor intercepts, validates, and safely processes it. - Pros: Sandboxing at the system call level. Protected from kernel vulnerabilities.
- Cons: System call overhead. 10-15% slower than regular containers.
Google Cloud Run can run multiple customers' containers on the same node thanks to gVisor.
Kata Containers
Runs standard Docker images inside lightweight VMs (QEMU/Firecracker). You get the Docker workflow (images, tags, portability) with VM isolation. Kubernetes can use Kata as a runtime, giving you VM-level security per pod.
# Kubernetes pod with Kata Containers
apiVersion: v1
kind: Pod
metadata:
name: secure-app
spec:
runtimeClassName: kata
containers:
- name: app
image: myapp:latest
8. Cost Analysis: EC2 vs Fargate vs Lambda
Technical differences matter, but TCO (Total Cost of Ownership) matters more. The billing statement reveals the truth.
| Item | EC2 (VM) | Fargate (Container) | Lambda (Function) |
|---|---|---|---|
| Billing Basis | Instance runtime (seconds) | CPU/Memory usage (seconds) | Requests + Runtime (ms) |
| Idle Cost | 100% even with zero traffic | 100% even with zero traffic | $0 (Zero Scale) |
| Management Cost | You handle OS patching/security | AWS manages OS | AWS manages runtime |
| Best For | 24/7 baseline workloads | Variable workloads, batch jobs | Sporadic events, APIs |
Cost Optimization Example
- Before: Multiple EC2 t3.medium instances (24/7) → Significant monthly cost
- After: Fargate Tasks (scale out only during peak) → Substantial cost reduction
Teams that have made this switch report 60%+ cost reductions. Note that Fargate still charges during idle time. A common follow-up is moving sporadic APIs to Lambda. Zero traffic = $0 cost.
Infrastructure Cost (Server Density)
Containers achieve higher density. On a 64GB RAM server:
- VMs: Guest OS takes 1GB overhead each. You might run 20 VMs.
- Containers: No OS overhead. You might run 100 containers.
Result: You need 5x fewer servers with containers. Massive hardware savings.
9. Decision Guide: When to Use What
Use Containers (90% of cases)
- General web/app backends
- Microservices architecture
- CI/CD pipelines
- Dev environment consistency (Docker Compose)
# Simple Dockerfile example
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
Use VMs
- Security-critical: finance/healthcare (multi-tenant isolation)
- Different OS needed (running Windows apps on Linux host)
- Legacy applications (can't containerize)
Hybrid: Containers in VMs
The modern trend is Containers in VMs. AWS EKS runs Kubernetes pods (containers) on EC2 instances (VMs). You get two layers of isolation.
Bare Metal → Type 1 Hypervisor → EC2 VM → Kubernetes → Container
This is the standard modern cloud architecture.
10. Comprehensive Glossary
- Virtual Machine (VM): An emulation of a computer system with virtual hardware.
- Container: A standard unit of software packaging code and dependencies.
- Hypervisor: Software creating and running VMs (Type 1 or Type 2).
- Guest OS: The OS installed inside a VM.
- Host OS: The OS running on physical hardware.
- Kernel: The OS core managing system resources.
- Namespace: Linux kernel feature for process isolation (PID, NET, etc.).
- Cgroups: Linux kernel feature for resource limitation (CPU, RAM).
- Docker: Platform for developing, shipping, and running containers.
- Kubernetes: Orchestration system for managing containerized applications.
- MicroVM: Lightweight VM optimized for fast startup (e.g., Firecracker).
- Serverless: Cloud model where the provider manages code execution (using MicroVMs/Containers).
- Cold Start: Delay when starting a new serverless function instance.
- Bare Metal: Physical server without virtualization software.
- Multi-tenancy: Architecture where one software instance serves multiple customers.
- Bin Packing: Efficiently fitting workloads onto servers to maximize utilization.
- OOM Killer: Out Of Memory Killer. Linux kernel feature that kills processes when RAM is full.
- Privileged Mode: Container mode with access to all host devices (insecure).
- Sandbox: Security mechanism for running programs in a restricted environment.
- VMM: Another name for Hypervisor (Virtual Machine Monitor).
11. Frequently Asked Questions (FAQ)
Q: Which is faster, VM or Container? A: Containers are faster because they run natively on the host OS kernel. VMs have overhead from hardware emulation and the guest OS.
Q: Can I replace all VMs with Containers? A: Not necessarily. If you need legacy apps, different operating systems, or strict security isolation, VMs are still better.
Q: Is Docker a Type 2 Hypervisor? A: No. Docker isn't a hypervisor at all. It uses kernel features to isolate processes.
Q: Do containers have their own Kernel? A: No. Containers share the host OS kernel. This is the main architectural difference from VMs.
Q: What is "Cloud Native"? A: It usually means using containers, microservices, and orchestration to build scalable applications.
Q: Why are VMs considered "Heavy"? A: Because they include a full OS image (kernel, drivers, libraries, system tools), taking up GBs of space and RAM.
Q: What is the main security risk of Containers? A: Kernel sharing. A vulnerability in the kernel affects all containers on that host.
Q: Can I run Docker inside a VM? A: Yes. This is the standard way to run Docker in the cloud (e.g., EC2 instances running Docker).
Q: Can I run a VM inside a Container? A: Yes (KVM inside Docker), but it requires special privileges and is complex to set up.
Q: What is the future of virtualization? A: Convergence. Lightweight VMs (MicroVMs) running containers, managed by Kubernetes.