[멋사 클라우드 5기] Day 39 - Docker Image & Container

2026. 4. 6. 19:56·Learning Log

Docker란 무엇인가

Docker는 컨테이너(Container) 기반의 오픈소스 가상화 플랫폼이다.

개발하다 보면 이런 경험을 한 번쯤 하게 된다. 내 컴퓨터에서는 잘 되는 코드가 친구 컴퓨터나 서버에 올리면 오류가 난다. 운영체제, 설치된 라이브러리 버전, 환경변수 등이 서로 다르기 때문이다.

Docker는 이 문제를 해결한다. 애플리케이션 코드와 그것이 실행되기 위해 필요한 모든 것(런타임, 라이브러리, 설정 등)을 하나의 컨테이너로 묶는다. 컨테이너는 어디서 실행하든 항상 동일한 환경을 보장한다.

VM과 Docker의 차이

Docker와 VM(가상머신) 둘 다 격리된 환경을 만들지만, 동작 방식이 다르다.

VM은 하드웨어를 가상화한다. 그 위에 독립적인 운영체제(Guest OS)를 올리기 때문에 크기가 크고 부팅이 느리다.

Docker는 운영체제를 가상화하지 않는다. 호스트 OS의 커널을 공유하면서 프로세스만 격리한다. 그래서 훨씬 가볍고 빠르다.

구분 VM (가상머신) Docker (컨테이너)

가상화 대상 하드웨어 전체 프로세스(OS 커널 공유)
크기 수 GB 수 MB ~ 수백 MB
부팅 속도 수 분 1초 이내
리소스 사용 무거움 가벼움
격리 수준 완전한 격리 프로세스 수준 격리

Docker 아키텍처

Docker는 크게 세 가지 구성요소로 이루어져 있다.

Docker Client

사용자가 Docker와 소통하는 창구다. 터미널에서 docker run, docker build 같은 명령어를 입력하면, 이 명령이 Docker Client를 통해 전달된다.

Docker Daemon (dockerd)

Docker의 실제 엔진이다. Client에서 명령을 받아 컨테이너를 생성하고, 이미지를 빌드하고, 네트워크와 볼륨을 관리한다. 백그라운드에서 항상 실행 중이다.

Docker Registry

Docker Image를 저장하고 배포하는 저장소다. 가장 대표적인 퍼블릭 레지스트리는 Docker Hub다. docker pull로 이미지를 받아오고, docker push로 올린다.

사용자 입력
   ↓
Docker Client  →  명령 전달  →  Docker Daemon
                                   ↓
                              Docker Registry (이미지 다운로드/업로드)

Docker Image

Image란 무엇인가

Docker Image는 컨테이너를 만들기 위한 읽기 전용 템플릿이다.

붕어빵 틀로 비유하면 이해하기 쉽다. Image는 붕어빵 틀이다. 틀 자체는 변하지 않는다. 이 틀로 붕어빵(컨테이너)을 여러 개 찍어낼 수 있다.

Image 안에는 아래 내용이 모두 담겨 있다.

  • 기반 운영체제 (Ubuntu, Alpine Linux 등)
  • 런타임 (Python, Node.js, Java 등)
  • 애플리케이션 소스 코드
  • 라이브러리 및 의존성
  • 설정 파일

Image 이름 구조

[레지스트리 주소]/[사용자명]/[이미지명]:[태그]

예시 의미

nginx:latest Docker Hub의 공식 nginx 이미지, 최신 버전
node:18-alpine Node.js 18버전, Alpine Linux 기반
myname/myapp:v1.0 내가 직접 만들어 올린 이미지

태그를 명시하지 않으면 자동으로 latest가 붙는다. 운영 환경에서는 버전 태그를 명시적으로 지정하는 것이 좋다.

주요 Image 명령어

docker pull nginx               # Docker Hub에서 nginx 이미지 다운로드
docker images                   # 로컬에 저장된 이미지 목록 확인
docker image ls                 # 위와 동일
docker image inspect nginx      # 이미지 상세 정보 (레이어, 설정 등) 확인
docker rmi nginx                # 이미지 삭제
docker image prune              # 사용하지 않는 이미지 전체 삭제

Image Layer

레이어 구조란

Docker Image는 단일 파일이 아니다. 여러 개의 레이어(Layer) 가 순서대로 쌓여서 하나의 이미지를 구성한다.

각 레이어는 이전 레이어로부터의 변경 사항만 저장한다. 포토샵의 레이어와 비슷한 개념이다.

아래 Dockerfile을 예시로 보면:

FROM ubuntu:22.04               # 레이어 1: Ubuntu 기본 이미지
RUN apt-get install -y python3  # 레이어 2: Python 설치
COPY app.py /app/               # 레이어 3: 소스 코드 복사

명령어 하나가 레이어 하나를 만든다. 이 레이어들이 순서대로 쌓여 최종 이미지가 된다.

레이어 캐싱 (Layer Caching)

레이어 구조의 가장 큰 장점은 캐싱이다.

이미지를 다시 빌드할 때, Docker는 변경되지 않은 레이어는 다시 빌드하지 않고 캐시를 그대로 재사용한다.

예를 들어 소스 코드(app.py)만 수정했다면, Python을 설치하는 레이어(레이어 2)는 캐시를 쓰고, 코드 복사 레이어(레이어 3)부터만 다시 실행한다. 빌드 시간이 크게 단축된다.

변경 없음 → 캐시 재사용 (빠름)
변경 있음 → 해당 레이어부터 다시 빌드

⚠️ 캐싱은 위에서 아래 순서로 동작한다. 특정 레이어가 변경되면 그 아래 모든 레이어도 다시 빌드된다. Dockerfile 작성 시 잘 바뀌지 않는 명령어를 위쪽에 배치하면 좋다.

레이어 공유

여러 이미지가 같은 레이어를 공유할 수 있다. Ubuntu 기반 이미지를 여러 개 빌드해도, Ubuntu 레이어는 디스크에 딱 한 번만 저장된다. 저장 공간을 효율적으로 사용한다.

컨테이너 레이어 (쓰기 가능 레이어)

Image의 모든 레이어는 읽기 전용이다. 컨테이너가 실행되면, 맨 위에 쓰기 가능한 레이어가 하나 추가된다. 컨테이너 안에서 파일을 생성하거나 수정하면 이 레이어에 기록된다.

컨테이너를 삭제하면 이 쓰기 레이어도 함께 사라진다. Image 레이어 자체는 아무 영향을 받지 않는다.

┌─────────────────────────────┐
│  쓰기 가능 레이어             │ ← 컨테이너 실행 시 추가 (컨테이너 삭제 시 소멸)
├─────────────────────────────┤
│  레이어 3: COPY app.py      │ ← 읽기 전용 (Image 레이어)
├─────────────────────────────┤
│  레이어 2: RUN apt-get ...  │ ← 읽기 전용 (Image 레이어)
├─────────────────────────────┤
│  레이어 1: FROM ubuntu      │ ← 읽기 전용 (Image 레이어)
└─────────────────────────────┘

Docker Container

Container란 무엇인가

Container는 Docker Image를 실제로 실행한 인스턴스다. Image가 붕어빵 틀이라면 Container는 그 틀로 찍어낸 붕어빵이다.

하나의 Image로 Container를 동시에 여러 개 실행할 수 있다. 각 Container는 서로 완전히 격리되어 독립적으로 동작한다.

Container의 특성

격리성: 각 컨테이너는 자신만의 파일시스템, 프로세스 공간, 네트워크 인터페이스를 갖는다. 컨테이너 A가 충돌해도 컨테이너 B에는 아무 영향이 없다.

일회성: 컨테이너 안에서 생성되거나 변경된 데이터는 컨테이너가 삭제되면 함께 사라진다. 데이터를 영구적으로 보존하려면 Volume을 사용해야 한다.

경량성: VM과 달리 컨테이너는 프로세스 수준에서 격리되기 때문에 수초 안에 시작하고 종료된다.

Container의 생명주기

생성(Created) → 실행(Running) → 일시정지(Paused) → 
재개(Running) → 종료(Stopped) → 삭제(Removed)

주요 Container 명령어

# 컨테이너 실행
docker run nginx                          # nginx 이미지로 컨테이너 실행 (포그라운드)
docker run -d nginx                       # 백그라운드로 실행 (-d: detach)
docker run -d -p 8080:80 nginx            # 포트 연결하여 백그라운드 실행
docker run -d --name my-nginx nginx       # 컨테이너에 이름 지정
docker run -it ubuntu /bin/bash           # 대화형 모드로 실행 (-i: 표준입력 유지, -t: 터미널 할당)

# 컨테이너 목록 확인
docker ps                                 # 실행 중인 컨테이너만 표시
docker ps -a                              # 종료된 컨테이너 포함 전체 표시

# 컨테이너 제어
docker stop my-nginx                      # 컨테이너 정상 종료 (SIGTERM 신호)
docker kill my-nginx                      # 컨테이너 강제 종료 (SIGKILL 신호)
docker start my-nginx                     # 종료된 컨테이너 다시 시작
docker restart my-nginx                   # 재시작
docker rm my-nginx                        # 컨테이너 삭제 (종료 상태일 때만 가능)
docker rm -f my-nginx                     # 실행 중이어도 강제 삭제

# 컨테이너 내부 접근 및 모니터링
docker exec -it my-nginx /bin/bash        # 실행 중인 컨테이너 내부로 진입
docker logs my-nginx                      # 컨테이너 로그 확인
docker logs -f my-nginx                   # 실시간 로그 스트리밍
docker inspect my-nginx                   # 컨테이너 상세 정보 (JSON 형식)
docker stats                              # 실행 중인 모든 컨테이너 리소스 사용량

포트 매핑 이해하기 (p)

컨테이너는 격리된 환경이기 때문에 외부에서 직접 접근할 수 없다. -p 옵션으로 호스트의 포트와 컨테이너의 포트를 연결해야 한다.

-p [호스트 포트]:[컨테이너 포트]

예시: -p 8080:80
→ 브라우저에서 localhost:8080으로 접속하면 컨테이너 내부 80 포트로 연결된다.

'Learning Log' 카테고리의 다른 글

[멋사 클라우드 5기] Day 40 - Dockerfile  (0) 2026.04.06
[멋사 클라우드 5기] Day 37 & 38 - Linux (3)  (0) 2026.03.25
[멋사 클라우드 5기] Day 35 & 36 - Linux (2)  (0) 2026.03.25
[멋사 클라우드 5기] Day 33 & 34 - Linux (1)  (1) 2026.03.25
[멋사 클라우드 5기] Day 31 & 32 - OSI 7 Layers  (1) 2026.03.16
'Learning Log' 카테고리의 다른 글
  • [멋사 클라우드 5기] Day 40 - Dockerfile
  • [멋사 클라우드 5기] Day 37 & 38 - Linux (3)
  • [멋사 클라우드 5기] Day 35 & 36 - Linux (2)
  • [멋사 클라우드 5기] Day 33 & 34 - Linux (1)
allluck777
allluck777
allluck777
    • 분류 전체보기 (44) N
      • AWS (0)
      • Network (0)
      • Linux (0)
      • Docker (0)
      • Project (4)
        • CloudNote (4)
      • Learning Log (36) N
      • Lecture (3)
        • 스프링 입문 - 코드로 배우는 스프링 부트, 웹 .. (3)
  • 전체
    오늘
    어제
  • hELLO· Designed By정상우.v4.10.6
allluck777
[멋사 클라우드 5기] Day 39 - Docker Image & Container
상단으로

티스토리툴바