본문으로 바로가기
Docker 기초 7편: 이미지 Layer와 tar 내부 구조
LinkedInGitHub
WORKSPACE

EXPLORER

157 POSTS
BLOG
면접질문
해야하는 거
AI 시대, 개발자는 사라지는가?
Python Counter, 빈도수를 쉽게 세는 방법
정렬
1. 투 포인터
DFS와 BFS
알고리즘 논리
코딩 테스트 핵심 알고리즘 정리파이썬 딕셔너리와 코딩 테스트 활용
예시로 살펴보는 AXAX 프로젝트, 문제 정의부터 확산까지AX 시대의 가치 정의와 현장 리딩
MSA
1. Singleton PatternSOLID
Kafka의 핵심 설계 원리Kafka 메시징 시스템의 구성과 동작 방식Kafka 기본 개념과 EC2 Docker 구성
쿠버네티스 입문
Modular Monolith1. MonolithMSA, 서비스 분리와 운영의 원리
Socket이란 무엇인가
네크워크 참조 모델
전체 데이터 구조REST API의 개념과 설계 원칙2. Field/ Parameter / Argument/ this
Actuator 란?EntityManagerJPA 연관관계 매핑JPA 트랜잭션(Transaction)입력값 검증Java의 AOP(Aspect Oriented Programming)Async : AsynchronousBeanJPA(Java Persistence API)Proxy 패턴Spring MVCdocker container1. Spirng 필요컴포넌트 스캔
Spring 컨테이너
application.yamlLombok
이번 강의는 무엇을 노리고 있을까?Spring AI를 배우기 전에 정리할 것23
1. 기술 스택
개발 문서를 읽기 위한 핵심 기술 용어
Docker를 이해하기 위한 운영체제 기초
sigterm
6. 설정과 저장소, 앱을 운영할 수 있는 상태로 만들기5. Service와 Ingress, 요청은 어디로 흐를까4. 직접 실험하는 Kubernetes, Pod 복구부터 롤백까지3. kubectl과 Pod, 상태에서 원인을 찾는 법2. 클러스터는 명령을 어떻게 Pod로 바꿀까1. 쿠버네티스, 원하는 상태와 컨테이너 이미지Calico쿠버네티스 입문, 원하는 상태를 유지하는 시스템
Psql JSONB, 행 잠금, 멱등성Psql 함수,프로시져,트리거
머신러닝 입문딥러닝 학습 기본 개념데이터 시각화기초 통계와 ML 파이프라인 연결분석 자동화와 파이프라인 설계
CNN 아키텍처 발전 과정이미지 세그멘테이션 모델과 핵심 개념객체 탐지 모델과 핵심 개념
딥러닝 데이터셋 엔지니어링
딥러닝 학습 문제 진단과 디버깅
도메인 적응 방법현대 LLM 워크플로의 패턴
Transformer에서 LoRA 적용 대상 정하기LoRA (Low-Rank Adaptation)
LLM 양자화와 QLoRA
분산 학습과 MLOps딥러닝 모델 경량화와 추론 최적화딥러닝 기본 학습 테크닉딥러닝 중급 학습 테크닉
Mixture of Experts(MoE) 핵심 개념멀티모달 파운데이션 모델 핵심 개념State Space Model과 MambaTransformer와 Vision Transformer
Latent Space
1Chunking?
DevOps 기초 1편
실습에서는?Agile 개요, 왜 필요한가?
CI/CD 기초 4편: 배포 전략과 운영CI/CD 기초 3편: Jenkins와 Argo CD를 이용한 GitOps 배포CI/CD 기초 2편: Docker 이미지와 배포 파이프라인CI/CD 기초 1편: 개념과 GitHub Actions
OCI: 컨테이너 이미지와 런타임의 공통 표준Docker 기초 13편: Compose Healthcheck와 실전 구성Docker 기초 12편: Compose 네트워크와 VolumeDocker 기초 11편: Compose 명령어와 환경 변수Docker 기초 10편: Compose 기본 구조와 이미지 빌드Docker 기초 9편: Docker 및 Kubernetes 네트워크Docker 기초 8편: 컨테이너 런타임과 격리Docker 기초 7편: 이미지 Layer와 tar 내부 구조Docker 기초 6편: 이미지 Layer와 빌드 최적화Docker 기초 5편: 컨테이너 기본 명령어와 VolumeDocker 기초 4편: 가상화와 컨테이너 이미지 생명주기Docker 기초 3편: CI/CD 연결과 배포 원칙Docker 기초 2편: Layer, Registry, Volume과 NetworkDocker 기초 1편: Dockerfile, Image와 Container
NginxNginx 로드 밸런싱과 HTTPSNginx 리버스 프록시와 Spring Boot 연결Nginx 기초와 동작 구조
05. Pinia 상태 관리: store 설계와 사용법04. Vue 컴포넌트 설계: props, emit, slot과 생명주기03. Vue Composition API 정리02. Vue 기초 문법 점검: JavaScript, 템플릿01. Vue.js 입문: 핵심 구조와 렌더링
Java 심화 Part 3: 함수형 프로그래밍과 LambdaJava 심화 Part 2: AnnotationJava 심화 Part 1: Reflection
Java 기초 Part 5: Stream APIJava 기초 Part 4: 제네릭Java 기초 Part 3: 제어문Java 기초 Part 2: 주석과 JavadocJava 기초 Part 1: 백엔드 배경과 Java 실행 구조
Java 디버깅 Part 1: 자주 헷갈리는 핵심 개념Java 디버깅 Part 2: VS Code 자동 컴파일과 프로젝트 구조
Java 실행과 JVM Part 3: ClassLoader와 JVM 메모리Java 실행과 JVM Part 2: 메모리와 데이터 흐름Java 실행과 JVM Part 1: Java와 Python 컴파일 비교
Java 객체지향 Part 5: static 메서드와 중첩 클래스Java 객체지향 Part 4: 상속과 인터페이스Java 객체지향 Part 3: 좋은 설계와 OOP 4대 특성Java 객체지향 Part 2: OOP 핵심 문법Java 객체지향 Part 1: 클래스, 객체, 필드와 생성자
Spring 기초 Part 11: Actuator와 애플리케이션 모니터링Spring 기초 Part 10: 비동기 처리와 @AsyncSpring 기초 Part 9: JPA 트랜잭션과 동시성 제어Spring 기초 Part 8: AOP와 공통 관심사 분리Spring 기초 Part 7: Proxy 패턴과 Spring ProxySpring 기초 Part 6: JPA 연관관계 매핑Spring 기초 Part 5: EntityManager와 영속성 컨텍스트Spring 기초 Part 4: JPA, Entity와 RepositorySpring 기초 Part 3: REST API 요청값과 입력값 검증Spring 기초 Part 2: Spring MVC 요청 처리 흐름Spring 기초 Part 1: IoC, Bean, DI와 주요 Annotation
DNS = Domain Name System
Spring Boot, WebSocket, Vue, Docker 로 Raspberry Pi 실시간 모니터링 프로젝트 만들기 - 1편1. Spring Boot 구현
1. GitHub Project 만들기
Python 코드 품질: 디버깅부터 테스트와 자동화까지Python 01. 실행 구조와 실무 기초
sLLM 핵심 기술과 전체 구조제한된 자원에서 sLLM 구축하기
시대 단상에 대한 주저리주저리
WORKSPACE

SEARCH

제목, 카테고리와 태그로 검색하세요.

VERSION CONTROL

SOURCE CONTROL

masterGitHub Pages
저장소 열기
BUILD STATUS

RUN AND DEBUG

게시물은 GitHub Actions에서 검증하고 정적 페이지로 빌드합니다.

Actions 열기
WORKSPACE

MANAGE

홈 열기전체 게시물태그 보기블로그 소개
Docker 기초 7편: 이미지 Layer와 tar 내부 구조●
workspace>posts>devops>docker>docker-07-image-layer-archive.md
DevOps / Docker2026.08.171 min read6 tags

Docker 기초 7편: 이미지 Layer와 tar 내부 구조

Docker 이미지와 Layer의 특징, tar 명령어와 이미지 아카이브 내부 구조 확인 방법을 정리한다.

Docker를 이해할 때는 다음 흐름을 먼저 잡으면 쉽다.

flowchart LR
    A["Dockerfile<br/>실행 환경 설명서"] -->|docker build| B["Image<br/>배포 가능한 설계도"]
    B -->|docker run| C["Container<br/>격리된 프로세스"]
    C --> D["Linux Kernel<br/>실제 실행과 격리 담당"]
  • Dockerfile 은 이미지를 만드는 방법을 적은 문서.
  • 이미지(Image) 는 애플리케이션 실행에 필요한 파일과 설정을 묶은 읽기 전용 패키지.
  • 컨테이너(Container) 는 이미지를 바탕으로 실행된 격리된 프로세스 또는 프로세스 그룹.
  • Linux Kernel 은 Namespace, cgroups 등의 기능으로 컨테이너를 실제로 격리하고 제한.

쉬운 비유: Dockerfile은 요리법, Image는 밀키트, Container는 밀키트로 실제 조리한 한 접시. 같은 이미지로 여러 컨테이너를 제작 가능.

다시 한 번 말하지만, 도커의 핵심 철학 중 하나는 재탕이다.


1. Docker 이미지와 레이어

먼저 알아둘 단어

단어뜻쉬운 비유
Image애플리케이션 실행 파일, 라이브러리, 설정을 묶은 읽기 전용 패키지프로그램을 찍어내는 설계도
Layer이전 상태에서 추가,수정,삭제된 파일의 묶음투명 필름 한 장
rootfs컨테이너가 /로 보는 루트 파일 시스템컨테이너 전용 서랍장
Metadata실행 명령, 환경 변수, 포트 등 이미지의 설정 정보제품 사용 설명서
Digest콘텐츠를 해시한 고유 식별값내용이 바뀌면 함께 바뀌는 디지털 지문

1.1 이미지는 무엇인가?

Docker 이미지는 애플리케이션을 실행하는 데 필요한 다음 요소를 묶은 배포 단위.

  • 여러 개의 파일 시스템 레이어
  • 실행 명령(CMD, ENTRYPOINT)
  • 환경 변수, 작업 디렉터리, 사용자 등의 설정
  • 레이어의 순서와 Digest를 가리키는 Manifest

레이어는 일반적으로 파일 시스템의 변경분을 tar 형식으로 직렬화해 저장한다. 이미지 전체가 단일 거대한 파일인 것이 아니라, 여러 변경분과 메타데이터가 조합된 구조.

주의: 레이어에는 주로 파일 시스템 변경분이 들어가고, CMD, LABEL, EXPOSE 같은 실행 설정은 이미지 설정 메타데이터에 기록된다.

1.2 레이어는 어떻게 쌓이는가?

flowchart BT
    L1["Layer 1<br/>Base OS 파일"] --> L2["Layer 2<br/>패키지 설치"]
    L2 --> L3["Layer 3<br/>애플리케이션 복사"]
    L3 --> CFG["Image Config<br/>CMD,환경 변수,포트"]

다음 Dockerfile을 예로 들어 보자.

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "webserver.py"]
  • FROM: 부모 이미지의 기존 레이어를 가져온다.
  • COPY, RUN, ADD: 보통 파일 시스템 변경분을 새 레이어에 기록.
  • CMD, ENTRYPOINT, ENV, EXPOSE: 주로 실행 설정 메타데이터를 기록.
  • WORKDIR 등 일부 명령은 빌더와 상황에 따라 파일 시스템 변경과 이미지 이력의 표현이 달라질 수 있다.

따라서 Dockerfile 명령어 하나가 항상 실제 파일 시스템 레이어 하나와 정확히 대응하는 것은 아니다. docker image history에는 파일 변경이 없는 0B 단계도 표시될 수 있습니다.

1.3 레이어의 특징

  • 이미지 레이어는 기본적으로 읽기 전용입.
    • 여러 이미지와 컨테이너가 동일한 레이어를 안전하게 공유하고, 원본 이미지가 변경되는 것을 방지하기 위해 읽기 전용으로 사용.
    • 컨테이너에서 파일을 수정하면 이미지 레이어를 직접 변경하지 않고, 컨테이너 위에 생성된 별도의 쓰기 가능한 레이어에 변경 사항을 저장.
  • 부모에서 자식 순서로 쌓인다.
    • 위 레이어의 파일이 아래 레이어의 같은 경로에 있는 파일을 가릴 수 있다.
  • 파일 삭제도 아래 레이어를 실제로 지우지 않는다.
    • 읽기 전용인 아래 레이어를 변경할 수 없으므로, 위 레이어에 whiteout이라는 삭제 표시를 남겨 파일이 삭제된 것처럼 보이게 한다.
  • 동일한 Digest의 레이어는 여러 이미지와 컨테이너가 공유할 수 있다.
    • 레이어가 읽기 전용이므로 여러 곳에서 함께 사용해도 내용이 바뀌거나 서로의 작업에 영향을 주지 않는다.
    • 이를 통해 디스크 사용량과 이미지 다운로드 시간을 줄일 수 있다.

레이어 공유 덕분에 다음 효과가 생긴다.

  • 같은 베이스 이미지를 중복 저장하지 않아 디스크를 절약한다.
  • 이미 보유한 레이어는 다시 받지 않아 pull이 빨라진다.
  • 동일한 이미지를 사용하면 서버가 달라도 비슷한 실행 환경을 재현할 수 있다.

1.4 컨테이너를 실행하면 무엇이 달라지는가?

이미지를 실행하면 읽기 전용 이미지 레이어 위에 컨테이너 전용 쓰기 레이어가 추가된다.

flowchart BT
    B["Base image layer<br/>읽기 전용"] --> L1["Package layer<br/>읽기 전용"]
    L1 --> L2["Application layer<br/>읽기 전용"]
    L2 --> U["Container writable layer<br/>컨테이너별 읽기,쓰기"]
    V["Volume<br/>영구 데이터"] -. 별도 마운트 .-> U

컨테이너 안에서 파일을 수정해도 원본 이미지가 바뀌지는 않는다. 변경 내용은 해당 컨테이너의 쓰기 레이어에 저장된다.

컨테이너를 삭제하면 쓰기 레이어도 함께 사라진다. 데이터베이스 파일처럼 유지해야 할 데이터는 Volume이나 Bind Mount에 저장해야 합니다.


2. tar와 이미지 내부 구조

먼저 알아둘 단어

단어뜻쉬운 비유
Archive여러 파일과 디렉터리를 하나로 묶은 파일이삿짐 상자
tar아카이브를 만들고 푸는 형식이자 명령어물건을 한 상자에 포장하는 도구
gzip데이터 크기를 줄이는 압축 방식상자 속 진공 압축팩
Manifest이미지 구성과 레이어 순서를 기록한 문서상자 안 물품 목록
BlobDigest로 이름 붙여 저장한 실제 데이터 덩어리번호표가 붙은 포장물

쉬운 비유: tar는 여러 서류를 한 파일철에 모으는 작업이고, gzip은 그 파일철을 눌러 부피까지 줄이는 작업.

2.1 tar 기본 사용법

.tar는 여러 파일을 하나로 묶은 것이다. tar 자체와 압축은 별개이며, gzip을 함께 사용하면 보통 .tar.gz 또는 .tgz가 된다.

# 여러 파일과 디렉터리를 files.tar로 묶기
tar -cvf files.tar file1.txt file2.txt directory/

# .tar 내부 목록 확인
tar -tvf files.tar

# .tar 풀기
tar -xvf files.tar

# gzip으로 압축된 .tar.gz 만들기
tar -czvf files.tar.gz file1.txt file2.txt directory/

# .tar.gz 풀기
tar -xzvf files.tar.gz

주요 옵션은 다음과 같습니다.

옵션뜻
c새 아카이브 생성(Create)
x아카이브 해제(Extract)
t내부 목록 조회(List)
v처리 과정을 자세히 출력(Verbose)
f뒤에 오는 값을 아카이브 파일명으로 사용(File)
zgzip 압축 또는 해제
flowchart LR
    F1["file1"] --> TAR["tar"]
    F2["file2"] --> TAR
    D["directory/"] --> TAR
    TAR --> A["files.tar"]
    A --> G["gzip"]
    G --> TGZ["files.tar.gz"]

2.2 Docker 이미지가 tar와 닮은 이유

컨테이너 이미지도 실행 파일들을 레이어별 묶음으로 저장. 각 레이어가 파일 시스템 변경분을 담고, Manifest가 레이어의 순서를 연결.

flowchart TD
    M["manifest<br/>레이어 순서"] --> C["config<br/>실행 설정과 이력"]
    M --> L1["layer blob 1<br/>Base OS"]
    M --> L2["layer blob 2<br/>패키지"]
    M --> L3["layer blob 3<br/>앱 파일"]

다만 docker save 결과의 정확한 디렉터리 형태와 Blob 압축 여부는 Docker 버전과 이미지 저장 방식에 따라 달라질 수 있다. 구조를 추측하기보다 file, jq, tar로 실제 형식을 확인하는 것이 안전.

2.3 예제 이미지 만들기

ARG UBUNTU_VERSION=22.04
FROM ubuntu:${UBUNTU_VERSION}

# FROM 앞에서 선언한 ARG를 빌드 단계 안에서 다시 사용하려면 재선언.
ARG UBUNTU_VERSION

RUN apt-get update \
    && apt-get install -y --no-install-recommends curl lsb-release nginx \
    && rm -rf /var/lib/apt/lists/*

RUN echo "현재 빌드에 사용된 Ubuntu 버전: ${UBUNTU_VERSION}"

LABEL maintainer="sample@example.com"
LABEL description="Linux version example"

EXPOSE 8080/tcp
EXPOSE 80/tcp

WORKDIR /var/www/html
COPY index.html .

CMD ["nginx", "-g", "daemon off;"]
# 마지막의 점(.)은 현재 디렉터리를 빌드 컨텍스트로 전달한다는 뜻.
docker build --tag indepth-container:1.0 .

# Dockerfile 단계와 이미지 이력 확인
docker image history indepth-container:1.0

2.4 이미지를 저장하고 분해하기

mkdir -p indepth-container
cd indepth-container

docker save --output indepth-container.tar indepth-container:1.0

# 먼저 목록만 확인
tar -tvf indepth-container.tar

# 현재 디렉터리에 해제
tar -xvf indepth-container.tar
find . -maxdepth 3 -type f | sort

manifest.json이 있다면 다음처럼 확인.

jq . manifest.json

개념적인 내용은 다음과 같다. Digest 값은 빌드할 때마다 달라질 수 있다.

[
  {
    "Config": "blobs/sha256/<config-digest>",
    "RepoTags": ["indepth-container:1.0"],
    "Layers": [
      "blobs/sha256/<base-layer-digest>",
      "blobs/sha256/<package-layer-digest>",
      "blobs/sha256/<app-layer-digest>"
    ]
  }
]

Blob의 실제 유형과 파일 목록은 다음처럼 확인.

cd blobs/sha256
file *

# tar 형식 Blob
tar -tvf <layer-digest>

# gzip으로 압축된 tar Blob
tar -tzvf <layer-digest>

Manifest의 Layers 순서는 이미지의 파일 시스템을 구성하는 순서입니다. CMD, LABEL, EXPOSE처럼 파일을 바꾸지 않는 명령은 별도의 파일 시스템 레이어가 없을 수 있으므로, Dockerfile의 모든 줄과 Layers 배열을 일대일로 맞추면 안 됨.

2.5 MariaDB 이미지로 확인하기

docker pull mariadb:10.11
mkdir -p indepth-mariadb
cd indepth-mariadb

docker save --output mariadb.tar mariadb:10.11
tar -xvf mariadb.tar
jq . manifest.json

특정 레이어의 내용은 다음과 같이 확인할 수 있다.

file blobs/sha256/<layer-digest>
tar -tvf blobs/sha256/<layer-digest>

예를 들어 엔트리포인트가 추가된 레이어라면 usr/local/bin/docker-entrypoint.sh 같은 파일이 나타날 수 있다. 정확한 Digest와 레이어 수는 이미지 버전에 따라 달라진다.


TAGS#Docker#Image#Layer#tar#Manifest#Blob
PREVIOUSDocker 기초 6편: 이미지 Layer와 빌드 최적화NEXTDocker 기초 8편: 컨테이너 런타임과 격리
DISCUSSION

COMMENTS

GitHub 계정으로 로그인하여 댓글을 남길 수 있습니다. 댓글은 GitHub Discussions에 공개 저장되며, 작성 내용과 GitHub 프로필 정보가 다른 방문자에게 보일 수 있습니다.

GitHub 로그인 후 댓글 쓰기Discussion 열기
DOCUMENT STRUCTURE

이 문서에는 목차가 없습니다.

DOCUMENT INFO
TYPE
Markdown
DATE
2026.08.17
READ
1 min read
WORDS
0
CATEGORY
DevOps / Docker
RELATED DOCUMENTS
Docker 기초 6편: 이미지 Layer와 빌드 최적화Docker 기초 2편: Layer, Registry, Volume과 NetworkDocker 기초 1편: Dockerfile, Image와 ContainerOCI: 컨테이너 이미지와 런타임의 공통 표준Docker 기초 13편: Compose Healthcheck와 실전 구성Docker 기초 12편: Compose 네트워크와 Volume
main DevOps / Docker
1 min readUTF-8Markdown
본문 글씨 크기
RECENTLY OPENED1
Docker 기초 7편: 이미지 Layer와 tar 내부 구조recently opened