

목 차
🐳 Docker 기본 개념
1. 컨테이너(Container)란 무엇이며 기존 가상화와 컨테이너(Container) 기반의 가상화의 차이점
2. Docker란 무엇인가??
3 기존 방식 vs Docker
4. Docker의 핵심 개념
☸️ Kubernetes 기본 개념
1. Kubernetes란?
2. 왜 필요한가?
3. Kubernetes 아키텍처
4. Kubernetes 핵심 리소스
5. Docker <-> Kubernetes 관계

이번에 Docker에 fastapi를 이미지로 띄워서 백엔드를 만들어보고 있기 때문에,
Docker에 대해서 한번 공부를 해보고 넘어가는 글을 작성하겠습니다.

컨테이너는 애플리케이션과 그 실행 환경(라이브러리, 설정, 종속성)을 하나의 독립된 단위로 패키징하여, 어디서나 동일하게 실행될 수 있도록 만든 가상화 기술(단위)
Docker 컨테이너 이미지는 코드, 런타임, 시스템 도구, 시스템 라이브러리 및 설정 등 애플리케이션을 실행하는 데 필요한 모든 것을 포함하는 경량의 독립 실행형 소프트웨어 패키지
“가벼운 가상머신”처럼 보이지만, 사실은 호스트 OS의 커널을 공유하면서 격리된 공간에서 실행됨.

컨테이너는 종속성, 필요한 라이브러리 및 바이너리와 함께 애플리케이션을 컨테이너 이미지라고 하는 독립된 패키지로 패키지화하여 여러 컴퓨팅 환경에 쉽게 배포 가능
즉, OS레벨에서 어플리케이션 실행 환경을 격리함으로써 마치 다른 OS에서 동작하는 것과 같은 가상 실행 환경을 제공하는 것.

과거에는 애플리케이션을 서버에 배포하려면 다음과 같은 문제가 있었습니다.
서버마다 운영체제(OS)와 라이브러리 버전이 다름
→ 개발 환경과 운영 환경의 차이로 인한 오류 발생
하나의 서버에 여러 애플리케이션이 설치되면
→ 서로 다른 라이브러리 버전이 충돌
새로운 서버를 세팅하려면 OS 설치부터 필요한 패키지 설치까지 많은 시간이 소요됨
이 문제를 해결하기 위해 가상머신(VM)이 등장했지만,
VM은 무겁고 성능 손실이 큰 단점이 있었습니다.
컨테이너는 VM보다 가볍고 빠른 대안으로 등장.

격리성 (Isolation)
이식성 (Portability)
경량성 (Lightweight)
불변성 (Immutable)

컨테이너는 '리눅스 커널 기능'을 활용해서 구현
대표적으로 2가지가 핵심.
Namespace

| 항목 | 가상머신(VM) | 컨테이너 |
|---|---|---|
| 실행 방식 | 하이퍼바이저 위에 Guest OS 실행 | Host OS 커널 공유 |
| 크기 | 수 GB (OS 포함) | 수백 MB ~ 수십 MB |
| 부팅 시간 | 수 분 | 수 초 |
| 격리 방식 | 하드웨어 수준 격리 | OS 커널 수준 격리 |
| 효율성 | 무겁고 자원 낭비 | 가볍고 효율적 |
📌 비유
- VM = 아파트 한 채 (전기·수도·가스 각각 설치)
- 컨테이너 = 오피스텔 한 층 (공용 전기·수도, 각 방은 격리됨)


📌 실무 팁
최신 Kubernetes는 더 이상 Docker 엔진 자체를 쓰지 않고,
containerd 같은 CNCF 표준 런타임을 사용 (Dockershim 제거)
개발자가 작성한 Dockerfile을 기반으로, Docker Image를 빌드.
이미지 = 계층(Layer) 구조
Base Image (python:3.12)
Dependency Layer (pip install)
App Layer (소스 코드)
예시 : Python 웹앱 빌드.
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "main.py"]
📌 주의
requirements.txt 변경이 잦다면 COPY 순서 최적화 필요
멀티스테이지 빌드를 사용하여 이미지 크기를 줄이는 게 베스트 프랙티스
컨테이너 이미지 레지스트리 제공.
이미지를 저장/공유하는 저장소
공식 : Docker Hub
흐름
📌 실무 포인트
민감 서비스는 Public Registry 금지 → 프라이빗 레지스트리 활용
이미지 태그는 latest 대신 버전 필수 (myapp:1.0.3)
docker network create mynet
docker run -d --name db --network mynet mysql:8.0
docker run -d --name app --network mynet myapp:1.0
-> 동일 네트워크에 있으면 컨테이너끼리 DNS 이름으로 통신 가능
docker volume create mydata
docker run -d \
-v mydata:/var/lib/mysql \
mysql:8.0
📌 실무 팁
DB, 로그 저장소 → 반드시 Volume 사용
Config/Secret은 Volume이 아닌 환경변수 or Secret Manager 사용 권장

Docker는 단순한 실행 도구가 아니라 클라이언트-서버 아키텍처로 설계되어 있습니다.
구성 요소
Docker CLI
Docker Daemon(docckerd)
Docker Registry: 이미지 저장소 (공개/비공개)
containerd
runc
+-------------------+
| Docker CLI | (사용자 명령어 입력)
+-------------------+
|
v
+-------------------+
| Docker Daemon | (컨테이너 실행/관리)
| - API Server |
| - containerd |
| - runc |
+-------------------+
|
v
+-------------------+
| Docker Registry | (이미지 저장소: Docker Hub, ECR 등)
+-------------------+
흐름 예시
1.docker run nginx:latest 실행
2.Daemon이 Docker Hub에서 nginx:latest 이미지 다운로드
3.이미지로 컨테이너 생성 및 실행
1️⃣ CLI → Daemon 요청 전달
CLI에서 docker run nginx:latest 입력
CLI는 Unix Socket(/var/run/docker.sock) 또는 TCP를 통해 Daemon에 API 요청
2️⃣ 이미지 존재 여부 확인
Daemon이 로컬 캐시에 nginx:latest 이미지가 있는지 확인
없다면 Registry(Docker Hub)에서 다운로드(Pull)
docker pull nginx:latest
3️⃣ 이미지 다운로드 & 저장
Registry에서 Layer 단위로 이미지 다운로드
예: nginx:latest
Base Layer: Debian OS
Layer 2: Nginx 설치 파일
Layer 3: 설정 파일
📌 Docker 이미지 = 여러 레이어의 합 (UnionFS)
변경된 레이어만 다운로드 → 속도 & 용량 최적화
4️⃣ 컨테이너 생성
Daemon이 runc를 호출하여 Namespace & Cgroups 설정
컨테이너 내부에 격리된 파일시스템, 네트워크, 프로세스 공간 구성
5️⃣ 컨테이너 실행
nginx 프로세스를 컨테이너 내에서 실행
외부와 연결된 네트워크 포트 바인딩
docker run -d -p 8080:80 nginx:latest
👉 결과: 브라우저에서 http://localhost:8080 접속 시 Nginx 기본 페이지 확인 가능
사용자
|
v
Docker CLI (docker run nginx)
|
v
Docker Daemon (dockerd)
|--- 이미지 로컬에 존재? --- 아니오 ---> Registry에서 Pull
|--- 예시: Docker Hub
|
v
containerd → runc
|
v
리눅스 커널 (Namespaces, Cgroups)
|
v
컨테이너 (nginx 프로세스 실행)

| 항목 | 전통 VM 방식 | Docker 컨테이너 |
|---|---|---|
| 실행 방식 | 하이퍼바이저 위에 Guest OS 실행 | Host OS 커널 공유 |
| OS 필요 여부 | VM마다 OS 필요 (무겁다) | Host OS 공유, 컨테이너마다 OS 불필요 |
| 성능 | OS 부팅 포함 → 느림 | 프로세스 단위 실행 → 빠름 |
| 자원 사용 | VM마다 수 GB 필요 | 수 MB ~ 수백 MB |
| 이식성 | 환경에 따라 동작 불가 가능성 ↑ | 동일 이미지면 어디서든 실행 |
| 배포 방식 | 수동 설치, 스크립트 관리 | docker run 한 줄로 실행 |
| 확장성 | VM 추가/삭제 필요 | 컨테이너 복제/삭제로 즉시 확장 |
비유
- VM = 독립된 아파트 (각자 전기·수도·가스 설치)
- Docker = 한 건물의 오피스텔 (공용 전기/수도, 각 세대 격리)
기존 배포 방식
1.서버에 SSH 접속
2.OS 업데이트
3.Python, Node.js, Java 설치
4.requirements.txt 또는 package.json에 따라 라이브러리 설치
5.애플리케이션 실행
⚠️ 문제점
Docker 배포 방식.
✅ 장점


Docker Image는 레이어(layer) 구조로 이루어져 있습니다.
[ Layer 3: Config Layer ] ← COPY, CMD, ENTRYPOINT
[ Layer 2: App Layer ] ← RUN npm install, pip install
[ Layer 1: Base Image ] ← ubuntu:20.04 / alpine:3.19
----------------------------
Docker Image
변경 시 레이어 단위로 기록 -> 빠른 빌드 가능.
레이어 구조는 Union File System (UnionFS)을 이용하여 관리됩니다.

이미지 빌드 시 , "변경된 레이어만 새로 저장"
캐시 활용 가능 -> 빠른 빌드.
ex)
FROM python:3.12
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt # Application Layer
COPY . . # Config Layer
CMD ["python", "main.py"]
👉 requirements.txt를 수정하지 않으면, pip install 단계가 캐시되어 빌드 시간 단축

alpine 기반 이미지 사용 (python:3.12-slim 등)
멀티 스테이지 빌드 활용
공식 이미지 사용 권장
취약점 검사: docker scan, trivy

Docker Container는
Docker Image를 실행한 인스턴스(프로세스)입니다.
실제로 애플리케이션이 동작하는 환경이며, OS 레벨에서 격리된 공간을 사용합니다.

휘발성
격리성
경량성

# nginx 실행
docker run -d -p 8080:80 nginx:1.25
-d: 백그라운드 실행
-p: 포트 매핑 (Host:Container)
nginx:1.25: 사용할 이미지
👉 브라우저에서 http://localhost:8080 접속 시 nginx 서버 응답

docker run -d \
-v mydata:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=1234 \
mysql:8.0
-v mydata:/var/lib/mysql → 볼륨 마운트
컨테이너 삭제해도 /var/lib/mysql에 데이터 보존

create → start → (running) → stop → rm
docker ps → 실행 중인 컨테이너 확인
docker stop "id" → 중지
docker rm "id" → 삭제

로그 관리.
docker logs <컨테이너명>으로 확인 가능
운영 환경에서는 ELK Stack 또는 Loki로 중앙화 필요
리소스 제한.
docker run -d --cpus="1.0" --memory="512m" myapp:1.0
보안.
root 권한 실행 지양
USER 명령어로 비루트 계정 지정



Docker Volume은 컨테이너의 데이터를 영구적으로 저장하기 위한 Docker의 공식 메커니즘입니다.
기본적으로 컨테이너 파일시스템은 휘발성이므로, 컨테이너 삭제 시 데이터도 함께 삭제됩니다.
Volume을 사용하면 데이터가 호스트 머신에 저장되어, 컨테이너 재시작/재생성에도 데이터 유지 가능.
docker run -d \
-v /mydata/mysql:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=1234 \
mysql:8.0
-> 컨테이너 삭제해도 /mydata/mysql 에 데이터 유지.

Volume은 Host 파일시스템의 특정 디렉토리에 저장됨
컨테이너의 특정 경로에 마운트되어, 컨테이너 안팎에서 동일한 데이터를 읽고 쓸 수 있음
Docker가 자체적으로 Volume을 관리 (/var/lib/docker/volumes/)

Docker가 관리하는 볼륨
예: -v mydata:/var/lib/mysql
호스트 경로를 직접 지정하지 않고 이름만 부여
호스트의 디렉토리를 직접 지정
예: -v /mydata/mysql:/var/lib/mysql
유연하지만, 호스트 경로 변경 시 관리 어려움
메모리에만 존재하는 임시 스토리지 (속도 빠름, 컨테이너 종료 시 사라짐)
예: 캐싱, 세션 데이터 저장용

# Named Volume
docker volume create mydata
docker run -d \
-v mydata:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=1234 \
mysql:8.0
# Bind Mount
docker run -d \
-v /mydata/mysql:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=1234 \
mysql:8.0

개발 환경: Bind Mount (코드 자동 반영 편리)
운영 환경: Named Volume (안정적 관리)


docker network create mynet
docker run -d --name db --network mynet mysql:8.0
docker run -d --name app --network mynet myapp:1.0
👉 app 컨테이너에서 db:3306으로 접속 가능 (DNS 지원)
docker run --network host nginx
⚠️ 단점: 포트 충돌 가능성 ↑, 격리 ↓
docker run --network none alpine
docker network ls # 네트워크 목록 확인
docker network inspect mynet # 네트워크 상세 정보
docker network create mynet # 사용자 정의 네트워크 생성
docker network connect mynet mycontainer # 컨테이너 연결
Bridge 모드
Host 모드
Overlay 모드
보안
불필요한 네트워크 포트는 닫기
방화벽 및 네트워크 정책(NACL, Security Group 등) 병행

-Kubernetes(K8s)는 컨테이너 기반 애플리케이션의 배포, 확장, 관리, 네트워킹을 자동화하는 오케스트레이션 플랫폼.

컨테이너 장애 시 자동 복구 불가
트래픽 급증 시 컨테이너 수동 확장
컨테이너 IP가 유동적
무중단 배포 불가
Self-Healing (죽은 Pod 자동 재시작)
Auto Scaling (트래픽에 따라 Pod 수 조절)
Service Discovery (고정 주소 제공)
Rolling Update & Rollback (무중단 배포)

+----------------------+
| Control Plane |
|----------------------|
| API Server |
| etcd (DB) |
| Scheduler |
| Controller Manager |
+----------+-----------+
|
+----------v----------+
| Worker Node |
| kubelet + kube-proxy|
| Container Runtime |
+---------------------+
API Server: 명령 접수
etcd: 상태 저장
Scheduler: Pod 배치 결정
Controller Manager: 상태 유지
Kubelet: Pod 실행
Kube-proxy: 네트워크 라우팅
Runtime: Docker/containerd

가장 작은 실행 단위
1개 이상의 컨테이너 포함 가능
Pod를 관리하는 상위 리소스
롤링 업데이트 지원
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.25
ports:
- containerPort: 80
Pod 집합에 접근할 수 있는 고정 Endpoint 제공.
유형: ClusterIP, NodePort, LoadBalancer.
도메인 기반 라우팅.
HTTPS 지원.
ConfigMap: 설정값 저장.
Secret: 비밀번호, 토큰 등 민감정보 저장 (Base64 인코딩)

| 기능 | Docker | Kubernetes |
|---|---|---|
| 실행 단위 | Container | Pod |
| 실행 정의 | Dockerfile | Deployment YAML |
| 확장 | 수동 run 반복 | ReplicaSet 자동 확장 |
| 복구 | 수동 재시작 | Self-Healing |
| 네트워킹 | Docker Network | Service + Ingress |
| 배포 전략 | 없음 | Rolling Update, Blue-Green, Canary |
