물리 서버, 가상 머신 (VM), 컨테이너. 서버 환경이 어떻게 변해왔는지, 컨테이너 관련 용어들의 관계를 정리합니다.
서버 환경의 변천
물리 서버 → VM → 컨테이너
물리 서버와 VM은 사용자 입장에서 거의 동일합니다. OS 설치하고, Java 설치하고, jar 배포하고. 차이는 하드웨어를 직접 만지느냐, 콘솔에서 클릭하느냐 정도입니다.
패러다임이 바뀌는 건 VM → 컨테이너 구간입니다.
컨테이너의 구조
기존 서버 환경 (물리 서버 / VM)
Application (jar)
Java (JDK)
OS (Linux)
─────────────
물리 서버 / VM
기존 서버 환경은 각 계층을 하나하나 직접 설치합니다.
컨테이너
┌─ 컨테이너 ──────────┐
│ Application (jar) │
│ Java (JDK) │
│ 최소한의 OS 라이브러리 │
└──────────────────────┘
─────────────
호스트 OS 커널 (공유)
─────────────
물리 서버 / VM
컨테이너는 호스트의 OS 커널을 공유합니다. OS를 통째로 설치하지 않고, 앱 실행에 필요한 최소한만 패키징합니다. 그래서 기존 서버 환경보다 가볍고 빠릅니다.
OS 커널, OS 라이브러리
OS는 커널과 라이브러리로 구성됩니다.
OS = 커널 + 라이브러리 (유저스페이스)
| 구분 | 역할 | 컨테이너에서 |
|---|---|---|
| OS 커널 | 하드웨어 제어, 메모리 관리, 프로세스 관리 | 호스트 것을 공유 |
| OS 라이브러리 | 앱이 파일을 읽거나 네트워크 통신할 때 사용 | 이미지에 포함 |
Java는 직접 OS 커널과 통신하지 않고, OS 라이브러리(glibc 등)를 통해 OS 커널 기능을 사용합니다.
Java → OS 라이브러리 (이미지에 포함) → OS 커널 (호스트 공유)
그래서 이미지에 “최소한의 OS 라이브러리"가 필요합니다. 다만 OS를 통째로 넣는 게 아니라 최소한만 포함하므로, 크기 차이가 큽니다.
| 구분 | 크기 |
|---|---|
| 일반 OS 설치 (Ubuntu) | 수 GB |
| 컨테이너 OS 베이스 이미지 (Alpine Linux) | 수십 MB |
| 컨테이너 Java 베이스 이미지 (amazoncorretto:21) | 200~400MB |
용어 관계
이미지와 컨테이너
| 용어 | 프로그래밍 비유 | 설명 |
|---|---|---|
| 이미지 | 클래스 (설계도) | 앱 실행에 필요한 모든 것을 패키징한 결과물. 불변(immutable) |
| 컨테이너 | 인스턴스 (실행체) | 이미지를 실행한 프로세스 |
이미지 하나로 컨테이너 여러 개를 실행할 수 있습니다.
[이미지]
├→ 컨테이너 1 (운영 서버)
├→ 컨테이너 2 (운영 서버)
└→ 컨테이너 3 (운영 서버)
이미지를 만드는 흐름
Dockerfile (설치 매뉴얼 작성)
↓ 빌드
이미지 (스냅샷 생성)
↓ 실행
컨테이너 (실행)
Spring Boot 기준 Dockerfile 예시:
FROM amazoncorretto:21 # 베이스 이미지 (OS 라이브러리 + Java)
COPY app.jar /app/app.jar # 애플리케이션 (jar)
ENTRYPOINT ["java", "-jar", "/app/app.jar"] # 실행 명령어
베이스 이미지를 선택하면 OS 라이브러리와 Java가 자동으로 포함됩니다. 개발자가 OS 라이브러리를 직접 설치할 일은 거의 없습니다.
이미지 용어 정리
같은 것을 문맥에 따라 다르게 부릅니다.
컨테이너 이미지 = Docker 이미지 = OCI 이미지 = 이미지
- 컨테이너 이미지: 정식 명칭
- Docker 이미지: Docker가 유명해서 대명사처럼 사용
- OCI 이미지: 표준 스펙 이름 (Open Container Initiative)
- 이미지: 실무에서 줄여서 부르는 표현
Docker가 만든 이미지 포맷이 OCI 표준으로 정리된 것이므로, 사실상 모두 같은 의미입니다.
컨테이너 생태계
이미지 포맷
OCI (Open Container Initiative) 가 표준입니다. Docker에서 유래했고, 어떤 빌드 도구로 만들든 결과물은 동일한 OCI 이미지입니다.
이미지 빌드 도구
이미지를 생성하는 도구입니다.
| 도구 | 특징 |
|---|---|
| Docker | 가장 유명. 범용 |
| Jib (Google) | Docker 없이 빌드 가능. Java 전용 |
| Kaniko (Google) | Docker 없이 빌드 가능. CI/CD 환경 |
| Buildpacks | Spring Boot 공식 지원. Dockerfile 불필요 |
Jib은 Docker 데몬 없이 Java 레벨에서 직접 OCI 이미지를 만듭니다. Java 생태계에서 많이 사용합니다.
런타임 (실행 도구)
컨테이너 1개를 실행하는 도구입니다.
| 런타임 | 특징 |
|---|---|
| Docker | 가장 유명. 빌드 + 실행 모두 가능 |
| containerd | Docker 내부에서 쓰이던 런타임. 더 가벼움 |
| Podman | Docker 대체제. Red Hat 계열에서 선호 |
오케스트레이션 (운영/관리 도구)
컨테이너 여러 개를 운영/관리하는 도구입니다. 내부적으로 런타임을 사용해서 컨테이너를 실행합니다.
오케스트레이션 (ECS, Kubernetes)
↓ 사용
런타임 (containerd 등)
↓ 실행
컨테이너
| 도구 | 특징 |
|---|---|
| AWS ECS | AWS 전용. 간편 |
| Kubernetes | 범용 (멀티 클라우드, 온프레미스). 복잡 |
ECS는 containerd를 이용해서 컨테이너를 실행하고, 추가로 오토스케일링, 로드밸런싱, 무중단 배포 등 운영/관리를 해줍니다.
전체 흐름
빌드 → 저장 → 배포 → 실행 → 관리
| 단계 | 동작 | 도구 |
|---|---|---|
| 빌드 | 이미지 생성 | Docker, Jib 등 |
| 저장 | 이미지를 저장소에 업로드 | Docker Hub, AWS ECR 등 |
| 배포 | 저장소에서 이미지 다운로드 | 오케스트레이션이 처리 |
| 실행 | 컨테이너 실행 | 오케스트레이션이 처리 |
| 관리 | 모니터링, 재시작, 스케일링 | 오케스트레이션이 처리 |
개발자는 이미지를 빌드해서 저장소에 올리기까지만 하고, 이후는 오케스트레이션 도구(ECS 등)가 처리합니다.
[개발자] [오케스트레이션 (ECS)]
빌드 → 저장 → 배포 → 실행 → 관리