Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

41장. 왜 컨테이너인가 — VM과의 차이

이 장에서 말하고자 하는 것

지금까지 우리는 EC2 위에 애플리케이션을 띄우는 그림을 그렸다.

그런데 운영해보면 EC2만으로 부족한 지점이 보인다.

  • 새 서버에 환경을 똑같이 깔기 어렵다
  • 개발과 운영 환경이 미묘하게 다르다
  • 배포가 느리다
  • 한 서버에 여러 서비스를 띄우면 충돌이 잘 난다

이걸 한 번에 풀어주는 게

컨테이너 (Container)

이고 표준 도구가

Docker

다.


1. VM과 컨테이너의 차이

VM

[하드웨어] → [Hypervisor] → [Guest OS] → [App]

OS 자체를 통째로 만든다. 무겁고 부팅이 느리다.

컨테이너

[하드웨어] → [Host OS] → [Container = 프로세스 격리] → [App]

OS는 공유하고 프로세스만 격리한다.
수십 MB, 초 단위 부팅.


2. 컨테이너가 풀어주는 4가지

환경 재현성

"내 컴퓨터에서는 잘 됐는데..."

이미지에 OS · 런타임 · 라이브러리 · 코드를 다 담는다.
어디서든 동일하게 실행된다.

빠른 배포

docker run my-app:v2

EC2 새로 띄우는 것보다 압도적으로 빠르다.

격리

한 머신에 여러 컨테이너를 띄워도 런타임 충돌이 없다.

표준 인터페이스

빌드 → 이미지 → 실행이 표준이라
ECS · EKS · K8s 어디서든 같은 이미지가 돈다.


3. 우리 서비스에서

척추 그림이 이 단원에서 바뀐다.

이전:
  ALB → EC2 (애플리케이션 직접 설치)

지금부터:
  ALB → ECS (Fargate) → 컨테이너 안의 애플리케이션

같은 트래픽 분배 구조에서 “서버” 가 “컨테이너” 로 바뀐 것이다.


4. 직접 확인해보기 — CLI

docker run -p 8080:8080 nginx

8080 포트로 nginx가 즉시 뜬다. 이게 컨테이너의 첫 모습이다.


5. 코드로는 이렇게 생겼다 — Dockerfile

FROM node:20-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 8080
CMD ["node", "server.js"]

이 파일이 곧 컨테이너 이미지의 설계도다. 다음 장에서 자세히 다룬다.


6. 이렇게 쓰면 망한다 — 안티패턴

안티패턴 1. 컨테이너 안에 데이터를 영구 저장한다

컨테이너 죽으면 데이터도 사라진다.

영구 데이터는 RDS · S3 · EFS 같은 외부 저장소로

안티패턴 2. 한 컨테이너에 여러 프로세스를 띄운다

  • 디버깅 어렵다
  • 한쪽이 죽어도 컨테이너는 살아 있는 척한다
  • 스케일링이 어색하다

한 컨테이너 = 한 프로세스

안티패턴 3. 이미지를 latest로 받는다

배포마다 다른 이미지가 떨어진다. 롤백 불가.

항상 명시적 버전 태그 (커밋 해시 · 시맨틱 버전)

안티패턴 4. 운영체제를 통째로 베이스로 잡는다

FROM ubuntu:22.04 (70MB+) 대신
FROM node:20-alpine (50MB) 또는 distroless 베이스를 쓴다.


7. 한 줄로 정리

컨테이너는 환경을 패키징해 어디서든 같게 돌리는 표준이며,
MSA가 자연스럽게 위에 올라타는 토대다


8. 이 장의 핵심 정리

  1. VM은 OS 통째, 컨테이너는 프로세스 격리.
  2. 컨테이너는 환경 재현성, 빠른 배포, 격리, 표준 인터페이스를 동시에 해결한다.
  3. 컨테이너는 일회용으로 다뤄야 한다. 영구 데이터는 외부 저장소에.
  4. 한 컨테이너에 한 프로세스만 띄운다.
  5. 이미지 태그는 항상 명시적으로, latest 의존을 피한다.