Docker & Kubernetes 입문 가이드 | 컨테이너부터 오케스트레이션까지

Docker & Kubernetes 입문 가이드 | 컨테이너부터 오케스트레이션까지

이 글의 핵심

이미지·컨테이너·Compose로 로컬을 맞춘 뒤, Pod·Deployment·Service까지 Kubernetes 맥락을 잡는다. “한 번에 전부”보다는 자주 쓰는 경로를 따라가게 정리했다.


목차

  1. Docker란 무엇인가?
  2. Docker 설치 및 기본 명령어
  3. Dockerfile 작성법
  4. Docker Compose 활용
  5. Kubernetes 기초
  6. Pod와 Deployment
  7. Service와 Ingress
  8. 실전 예제

사전 지식 (초보자를 위한 기초)

1. 가상화란?

가상화는 한 대의 물리 서버에서 여러 환경을 나눠 돌리는 기술이다.

다음은 text를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

전통적인 방식:
┌─────────────────┐
│   애플리케이션   │
├─────────────────┤
│   운영체제       │
├─────────────────┤
│   물리 서버      │
└─────────────────┘

가상 머신 (VM):
┌─────────────────┐
│   앱 A  │ 앱 B  │
├─────────┼───────┤
│  OS A   │ OS B  │  ← 각각 전체 OS 필요 (무거움)
├─────────────────┤
│   하이퍼바이저   │
├─────────────────┤
│   물리 서버      │
└─────────────────┘

컨테이너 (Docker):
┌─────────────────┐
│   앱 A  │ 앱 B  │
├─────────┼───────┤
│ Docker Engine   │  ← OS 공유 (가벼움)
├─────────────────┤
│   운영체제       │
├─────────────────┤
│   물리 서버      │
└─────────────────┘

차이점:

  • VM: 전체 OS 포함, 무겁고 느림 (GB 단위)
  • 컨테이너: OS 커널 공유, 가볍고 빠름 (MB 단위)

2. 왜 Docker를 사용할까?

“내 컴퓨터에서는 되는데…” 문제 해결!

아래 코드는 text를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

개발자 A의 환경:
- Python 3.9
- PostgreSQL 13
- Ubuntu 20.04

개발자 B의 환경:
- Python 3.11
- PostgreSQL 15
- macOS

→ 같은 코드인데 다르게 동작할 수 있다.

Docker를 쓰면 같은 이미지를 기준으로 맞추기 쉬워져서, 환경 차이로 생기는 디버깅을 줄이는 데 도움이 된다.

3. 컨테이너의 장점

이식성 (Portability)

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# 개발 환경에서 테스트
docker run myapp

# 프로덕션 환경에서도 동일하게 실행
docker run myapp

격리성 (Isolation)

컨테이너 A: Node.js 14
컨테이너 B: Node.js 18
→ 서로 영향 없이 독립적으로 실행

효율성 (Efficiency)

VM: 부팅 시간 수 분, 메모리 GB 단위
컨테이너: 시작 시간 수 초, 메모리 MB 단위

1. Docker란 무엇인가?

Docker의 핵심 개념

Docker는 애플리케이션을 컨테이너로 묶어 실행하는 플랫폼이다.

아래 코드는 text를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

Docker 구성 요소:

┌─────────────────────────────────┐
│         Docker Image            │  ← 실행 파일 (레시피)
│  (읽기 전용, 불변)               │
└─────────────────────────────────┘
              ↓ docker run
┌─────────────────────────────────┐
│       Docker Container          │  ← 실행 중인 인스턴스
│  (읽기/쓰기, 실행 중)            │
└─────────────────────────────────┘

이미지는 읽기 전용 레이어의 묶음이고, 컨테이너는 그 위에서 돌아가는 프로세스·쓰기 레이어까지 포함한 실행 단위다.

Docker 아키텍처

다음은 text를 활용한 상세한 구현 코드입니다. 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

┌──────────────────────────────────────┐
│         Docker Client (CLI)          │
│         docker run, docker build     │
└──────────────┬───────────────────────┘
               │ REST API
┌──────────────▼───────────────────────┐
│         Docker Daemon                │
│  - 이미지 관리                        │
│  - 컨테이너 실행                      │
│  - 네트워크 관리                      │
└──────────────┬───────────────────────┘

┌──────────────▼───────────────────────┐
│         Docker Registry              │
│         (Docker Hub)                 │
│  - 이미지 저장소                      │
└──────────────────────────────────────┘

2. Docker 설치 및 기본 명령어

Docker 설치

Windows/Mac:

# Docker Desktop 다운로드 및 설치
# https://www.docker.com/products/docker-desktop

Linux (Ubuntu):

아래 코드는 bash를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# Docker 설치
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# 현재 사용자를 docker 그룹에 추가
sudo usermod -aG docker $USER

# 설치 확인
docker --version
# Docker version 24.0.7, build afdd53b

기본 명령어

1) 이미지 다운로드 및 실행

아래 코드는 bash를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# Docker Hub에서 이미지 다운로드
docker pull nginx

# 컨테이너 실행
docker run -d -p 8080:80 --name my-nginx nginx
# -d: 백그라운드 실행
# -p 8080:80: 호스트 8080 포트를 컨테이너 80 포트로 매핑
# --name: 컨테이너 이름 지정

# 브라우저에서 http://localhost:8080 접속 → Nginx 페이지 확인

2) 컨테이너 관리

다음은 bash를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 실행 중인 컨테이너 목록
docker ps

# 모든 컨테이너 목록 (중지된 것 포함)
docker ps -a

# 컨테이너 중지
docker stop my-nginx

# 컨테이너 시작
docker start my-nginx

# 컨테이너 재시작
docker restart my-nginx

# 컨테이너 삭제
docker rm my-nginx

# 컨테이너 로그 확인
docker logs my-nginx

# 컨테이너 내부 접속
docker exec -it my-nginx bash

3) 이미지 관리

아래 코드는 bash를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 이미지 목록
docker images

# 이미지 삭제
docker rmi nginx

# 사용하지 않는 이미지 정리
docker image prune

# 모든 리소스 정리 (컨테이너, 이미지, 볼륨, 네트워크)
docker system prune -a

3. Dockerfile 작성법

Dockerfile이란?

Dockerfile은 이미지를 빌드하기 위한 설계도다.

Node.js 애플리케이션 예제

1) 프로젝트 구조

아래 코드는 text를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

my-app/
├── Dockerfile
├── package.json
├── package-lock.json
└── server.js

2) server.js

아래 코드는 javascript를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// 변수 선언 및 초기화
const express = require('express');
const app = express();
const PORT = 3000;

app.get('/', (req, res) => {
  res.json({ message: 'Hello from Docker!' });
});

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

3) package.json

아래 코드는 json를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

{
  "name": "my-app",
  "version": "1.0.0",
  "dependencies": {
    "express": "^4.18.0"
  },
  "scripts": {
    "start": "node server.js"
  }
}

4) Dockerfile

다음은 dockerfile를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 1. 베이스 이미지 선택
FROM node:18-alpine

# 2. 작업 디렉토리 설정
WORKDIR /app

# 3. 의존성 파일 복사
COPY package*.json ./

# 4. 의존성 설치
RUN npm install --production

# 5. 애플리케이션 코드 복사
COPY . .

# 6. 포트 노출
EXPOSE 3000

# 7. 실행 명령어
CMD ["npm", "start"]

5) 이미지 빌드 및 실행

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# 이미지 빌드
docker build -t my-app:1.0 .

# 컨테이너 실행
docker run -d -p 3000:3000 --name my-app my-app:1.0

# 테스트
curl http://localhost:3000
# {"message":"Hello from Docker!"}

Dockerfile 최적화

레이어 캐싱 활용

아래 코드는 dockerfile를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# ❌ 비효율적 (코드 변경 시 매번 npm install)
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm install
CMD ["npm", "start"]

# ✅ 효율적 (package.json 변경 시만 npm install)
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["npm", "start"]

멀티 스테이지 빌드

다음은 dockerfile를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 빌드 스테이지
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# 프로덕션 스테이지
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/server.js"]

# 이미지 크기: 1GB → 100MB

4. Docker Compose 활용

Docker Compose란?

Docker Compose는 여러 컨테이너를 한 번에 띄우고 묶어 주는 도구다.

실전 예제: Node.js + PostgreSQL + Redis

docker-compose.yml

다음은 yaml를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

version: '3.8'

services:
  # Node.js 애플리케이션
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgresql://user:password@db:5432/mydb
      - REDIS_URL=redis://redis:6379
    depends_on:
      - db
      - redis
    volumes:
      - ./src:/app/src  # 코드 변경 시 자동 반영

  # PostgreSQL 데이터베이스
  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=mydb
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"

  # Redis 캐시
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"

volumes:
  postgres_data:

실행 명령어

아래 코드는 bash를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 모든 서비스 시작
docker-compose up -d

# 로그 확인
docker-compose logs -f

# 특정 서비스 로그
docker-compose logs -f app

# 서비스 중지
docker-compose down

# 볼륨까지 삭제
docker-compose down -v

5. Kubernetes 기초

Kubernetes란?

Kubernetes (K8s)는 컨테이너를 배포·확장·복구까지 자동화하려는 오케스트레이션 플랫폼이다.

아래 코드는 text를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

Docker: 컨테이너 실행
Kubernetes: 수백 개의 컨테이너를 자동으로 관리

예시:
- 컨테이너가 죽으면 자동으로 재시작
- 트래픽 증가 시 자동으로 컨테이너 추가
- 로드 밸런싱 자동 처리

Kubernetes 아키텍처

다음은 text를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

┌─────────────────────────────────────────┐
│         Control Plane (마스터)           │
│  - API Server: 모든 요청 처리            │
│  - Scheduler: Pod 배치 결정              │
│  - Controller: 상태 관리                 │
│  - etcd: 클러스터 데이터 저장            │
└─────────────┬───────────────────────────┘

    ┌─────────┼─────────┐
    │         │         │
┌───▼───┐ ┌──▼────┐ ┌──▼────┐
│ Node1 │ │ Node2 │ │ Node3 │  ← Worker Nodes
│ Pod A │ │ Pod B │ │ Pod C │
│ Pod D │ │ Pod E │ │       │
└───────┘ └───────┘ └───────┘

핵심 개념

Pod

  • 가장 작은 배포 단위
  • 1개 이상의 컨테이너 포함
  • 같은 Pod 내 컨테이너는 IP 공유

Deployment

  • Pod의 선언적 업데이트
  • 롤링 업데이트, 롤백 지원
  • 레플리카 수 관리

Service

  • Pod에 대한 네트워크 접근
  • 로드 밸런싱
  • 고정된 IP/DNS 제공

6. Kubernetes 설치 및 기본 명령어

Minikube 설치 (로컬 테스트용)

다음은 bash를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# macOS
brew install minikube

# Windows (Chocolatey)
choco install minikube

# Linux
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# Minikube 시작
minikube start

# kubectl 설치 확인
kubectl version --client

기본 kubectl 명령어

다음은 bash를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 클러스터 정보
kubectl cluster-info

# 노드 목록
kubectl get nodes

# Pod 목록
kubectl get pods

# 모든 리소스 목록
kubectl get all

# 상세 정보
kubectl describe pod <pod-name>

# 로그 확인
kubectl logs <pod-name>

# Pod 내부 접속
kubectl exec -it <pod-name> -- bash

7. Pod와 Deployment

Pod 생성

nginx-pod.yaml

아래 코드는 yaml를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.25
    ports:
    - containerPort: 80

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# Pod 생성
kubectl apply -f nginx-pod.yaml

# Pod 확인
kubectl get pods

# Pod 삭제
kubectl delete pod nginx-pod

Deployment 생성

nginx-deployment.yaml

다음은 yaml를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3  # 3개의 Pod 실행
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"

다음은 bash를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# Deployment 생성
kubectl apply -f nginx-deployment.yaml

# Deployment 확인
kubectl get deployments

# Pod 확인 (3개 생성됨)
kubectl get pods

# 스케일링 (5개로 증가)
kubectl scale deployment nginx-deployment --replicas=5

# 롤링 업데이트
kubectl set image deployment/nginx-deployment nginx=nginx:1.26

# 롤백
kubectl rollout undo deployment/nginx-deployment

# 업데이트 상태 확인
kubectl rollout status deployment/nginx-deployment

8. Service와 Ingress

Service 생성

nginx-service.yaml

아래 코드는 yaml를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: LoadBalancer  # ClusterIP, NodePort, LoadBalancer
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# Service 생성
kubectl apply -f nginx-service.yaml

# Service 확인
kubectl get services

# Minikube에서 서비스 접속
minikube service nginx-service

Service 타입 비교

아래 코드는 text를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

1. ClusterIP (기본값)
   - 클러스터 내부에서만 접근 가능
   - 외부 노출 안됨

2. NodePort
   - 각 노드의 특정 포트로 접근 가능
   - 포트 범위: 30000-32767

3. LoadBalancer
   - 클라우드 로드 밸런서 자동 생성
   - 외부 IP 할당

9. 실전 예제

예제 1: Node.js 애플리케이션 배포

1) Dockerfile

아래 코드는 dockerfile를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

2) deployment.yaml

다음은 yaml를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:1.0
        ports:
        - containerPort: 3000
        env:
        - name: NODE_ENV
          value: "production"
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: url
---
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  type: LoadBalancer
  selector:
    app: myapp
  ports:
  - port: 80
    targetPort: 3000

3) 배포

다음은 bash를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 이미지 빌드
docker build -t myapp:1.0 .

# Minikube에 이미지 로드
minikube image load myapp:1.0

# Secret 생성
kubectl create secret generic db-secret \
  --from-literal=url='postgresql://user:pass@db:5432/mydb'

# 배포
kubectl apply -f deployment.yaml

# 확인
kubectl get all

예제 2: ConfigMap과 Secret

configmap.yaml

아래 코드는 yaml를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  APP_NAME: "MyApp"
  LOG_LEVEL: "info"
  API_URL: "https://api.example.com"

secret.yaml

아래 코드는 yaml를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

apiVersion: v1
kind: Secret
metadata:
  name: app-secret
type: Opaque
stringData:
  DB_PASSWORD: "mypassword"
  API_KEY: "secret-key-123"

deployment에서 사용

다음은 yaml를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  template:
    spec:
      containers:
      - name: myapp
        image: myapp:1.0
        envFrom:
        - configMapRef:
            name: app-config
        - secretRef:
            name: app-secret

10. 헬스 체크 및 모니터링

Liveness와 Readiness Probe

다음은 yaml를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  template:
    spec:
      containers:
      - name: myapp
        image: myapp:1.0
        ports:
        - containerPort: 3000
        
        # Liveness Probe (컨테이너 살아있는지 확인)
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
          failureThreshold: 3
        
        # Readiness Probe (트래픽 받을 준비 됐는지 확인)
        readinessProbe:
          httpGet:
            path: /ready
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5

헬스 체크 엔드포인트 구현

아래 코드는 javascript를 사용한 구현 예제입니다. 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// server.js
app.get('/health', (req, res) => {
  // 컨테이너가 살아있는지 확인
  res.status(200).json({ status: 'ok' });
});

app.get('/ready', (req, res) => {
  // DB 연결 등 확인
  if (dbConnected) {
    res.status(200).json({ status: 'ready' });
  } else {
    res.status(503).json({ status: 'not ready' });
  }
});

11. 볼륨과 영속성

Volume 타입

1) emptyDir (임시 볼륨)

아래 코드는 yaml를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

apiVersion: v1
kind: Pod
metadata:
  name: cache-pod
spec:
  containers:
  - name: app
    image: myapp
    volumeMounts:
    - name: cache
      mountPath: /app/cache
  volumes:
  - name: cache
    emptyDir: {}  # Pod 삭제 시 데이터 삭제

2) PersistentVolume (영구 볼륨)

다음은 yaml를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# PersistentVolume
apiVersion: v1
kind: PersistentVolume
metadata:
  name: postgres-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /data/postgres

---
# PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

---
# Deployment에서 사용
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
spec:
  template:
    spec:
      containers:
      - name: postgres
        image: postgres:15
        volumeMounts:
        - name: postgres-storage
          mountPath: /var/lib/postgresql/data
      volumes:
      - name: postgres-storage
        persistentVolumeClaim:
          claimName: postgres-pvc

12. 네임스페이스와 리소스 관리

네임스페이스

아래 코드는 bash를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 네임스페이스 생성
kubectl create namespace dev
kubectl create namespace prod

# 특정 네임스페이스에 배포
kubectl apply -f deployment.yaml -n dev

# 네임스페이스 목록
kubectl get namespaces

# 특정 네임스페이스의 리소스 확인
kubectl get all -n dev

리소스 쿼터

아래 코드는 yaml를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

apiVersion: v1
kind: ResourceQuota
metadata:
  name: dev-quota
  namespace: dev
spec:
  hard:
    requests.cpu: "10"
    requests.memory: 20Gi
    limits.cpu: "20"
    limits.memory: 40Gi
    pods: "50"

13. 실전 배포 전략

롤링 업데이트

다음은 yaml를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 10
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2        # 최대 2개 추가 Pod
      maxUnavailable: 1  # 최대 1개 중단 허용
  template:
    spec:
      containers:
      - name: myapp
        image: myapp:2.0

배포 과정:

아래 코드는 text를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

초기: [v1] [v1] [v1] [v1] [v1]

1단계: [v1] [v1] [v1] [v1] [v1] [v2] [v2]
       (2개 추가)

2단계: [v1] [v1] [v1] [v1] [v2] [v2]
       (1개 중단)

3단계: [v1] [v1] [v1] [v2] [v2] [v2]
       ...

최종: [v2] [v2] [v2] [v2] [v2]

Blue-Green 배포

아래 코드는 bash를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# Blue (현재 버전)
kubectl apply -f deployment-blue.yaml

# Green (새 버전) 배포
kubectl apply -f deployment-green.yaml

# Service를 Green으로 전환
kubectl patch service myapp -p '{"spec":{"selector":{"version":"green"}}}'

# 문제 발생 시 Blue로 롤백
kubectl patch service myapp -p '{"spec":{"selector":{"version":"blue"}}}'

14. 모니터링 및 로깅

기본 모니터링

아래 코드는 bash를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 리소스 사용량 확인
kubectl top nodes
kubectl top pods

# 이벤트 확인
kubectl get events --sort-by='.lastTimestamp'

# Pod 상태 확인
kubectl get pods -o wide

# 특정 Pod 상세 정보
kubectl describe pod <pod-name>

로그 수집

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# 실시간 로그
kubectl logs -f <pod-name>

# 이전 컨테이너 로그 (재시작된 경우)
kubectl logs <pod-name> --previous

# 여러 Pod 로그 (label selector)
kubectl logs -l app=myapp --tail=100

15. 트러블슈팅

자주 발생하는 문제

1) ImagePullBackOff

아래 코드는 bash를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 증상
kubectl get pods
# NAME      READY   STATUS             RESTARTS
# myapp-x   0/1     ImagePullBackOff   0

# 원인: 이미지를 다운로드할 수 없음
# 해결:
# - 이미지 이름 확인
# - Docker Hub 인증 확인
# - Minikube에 이미지 로드: minikube image load myapp:1.0

2) CrashLoopBackOff

아래 코드는 bash를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 증상
kubectl get pods
# NAME      READY   STATUS              RESTARTS
# myapp-x   0/1     CrashLoopBackOff    5

# 원인: 컨테이너가 시작 후 바로 종료
# 해결:
kubectl logs myapp-x  # 로그 확인
kubectl describe pod myapp-x  # 상세 정보 확인

# 일반적인 원인:
# - 애플리케이션 에러
# - 환경 변수 누락
# - 의존성 서비스 미준비

3) Pending 상태

아래 코드는 bash를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 증상
kubectl get pods
# NAME      READY   STATUS    RESTARTS
# myapp-x   0/1     Pending   0

# 원인: 스케줄링 불가
kubectl describe pod myapp-x

# 일반적인 원인:
# - 리소스 부족 (CPU, 메모리)
# - PVC 바인딩 실패
# - Node selector 미매칭

16. Docker vs Kubernetes 비교

항목DockerKubernetes
용도컨테이너 실행컨테이너 오케스트레이션
규모단일 호스트다중 호스트 클러스터
자동 복구없음자동 재시작
스케일링수동자동 (HPA)
로드 밸런싱없음내장
롤링 업데이트없음지원
학습 곡선낮음높음

언제 무엇을 사용할까?

아래 코드는 text를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

Docker만 사용:
- 개발 환경
- 소규모 프로젝트
- 단일 서버

Docker + Kubernetes:
- 프로덕션 환경
- 대규모 서비스
- 고가용성 필요
- 자동 스케일링 필요

17. 실전 팁

Docker 최적화

1) 이미지 크기 줄이기

아래 코드는 dockerfile를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# ❌ 큰 이미지 (1GB)
FROM node:18
COPY . .
RUN npm install

# ✅ 작은 이미지 (100MB)
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .

2) .dockerignore 활용

아래 코드는 text를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# .dockerignore
node_modules
npm-debug.log
.git
.env
*.md
dist
coverage

Kubernetes 최적화

1) 리소스 제한 설정

아래 코드는 yaml를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

resources:
  requests:
    memory: "128Mi"
    cpu: "100m"
  limits:
    memory: "256Mi"
    cpu: "200m"

2) Horizontal Pod Autoscaler

다음은 yaml를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

18. 다음 단계

학습 로드맵

다음은 text를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

1단계: Docker 기초
  ✓ 컨테이너 개념 이해
  ✓ 기본 명령어 숙지
  ✓ Dockerfile 작성

2단계: Docker 실전
  ✓ Docker Compose
  ✓ 멀티 스테이지 빌드
  ✓ 이미지 최적화

3단계: Kubernetes 기초
  ✓ Pod, Deployment
  ✓ Service
  ✓ kubectl 명령어

4단계: Kubernetes 실전
  ✓ ConfigMap, Secret
  ✓ 볼륨 관리
  ✓ 헬스 체크

5단계: 고급 주제
  ✓ Helm (패키지 관리)
  ✓ Ingress Controller
  ✓ 모니터링 (Prometheus, Grafana)
  ✓ CI/CD 연동

추천 학습 자료

공식 문서:

실습 환경:

온라인 강의:

  • Docker Mastery (Udemy)
  • Kubernetes for Developers (Pluralsight)

FAQ

Q1. Docker와 VM의 차이는?

VM은 게스트 OS까지 올리는 반면, 컨테이너는 호스트 커널을 공유한다. 그래서 기동·이미지 크기·오버헤드에서 보통 컨테이너가 유리하다.

Q2. Kubernetes 없이 Docker만 써도 되나?

개발·스테이징·소규모 서비스는 Compose까지로도 많이 간다. 여러 노드 스케일·셀프 힐링·롤링 배포까지 표준으로 가져가려 할 때 K8s를 본격적으로 고른다.

Q3. Minikube와 Docker Desktop의 Kubernetes는?

Minikube는 로컬에 클러스터를 올리기 위한 도구로 잘 쓰인다. Docker Desktop에 붙은 K8s는 같은 머신에서 이미지 빌드와 묶어 쓰기 편하다. 둘 다 학습용으로 자주 고른다.

Q4. 프로덕션에서 어떤 Kubernetes를 사용하나요?

  • AWS: EKS (Elastic Kubernetes Service)
  • GCP: GKE (Google Kubernetes Engine)
  • Azure: AKS (Azure Kubernetes Service)
  • 자체 호스팅: kubeadm, Rancher

Q5. Docker Compose vs Kubernetes?

  • Docker Compose: 단일 호스트, 개발/테스트
  • Kubernetes: 다중 호스트, 프로덕션

요약

핵심 정리

Docker:

  • 컨테이너로 애플리케이션 패키징
  • “내 컴퓨터에서는 되는데” 문제 해결
  • 가볍고 빠른 실행

Kubernetes:

  • 컨테이너 오케스트레이션
  • 자동 스케일링, 자동 복구
  • 프로덕션 환경 필수

학습 순서:

  1. Docker 기본 명령어
  2. Dockerfile 작성
  3. Docker Compose
  4. Kubernetes 기본 개념
  5. kubectl 명령어
  6. 실전 배포

다음 글 추천


키워드: Docker, Kubernetes, Container, k8s, kubectl, Pod, Deployment, DevOps, 컨테이너, 오케스트레이션, 마이크로서비스

... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3