hobokai 님의 블로그

Docker 완전 마스터 가이드: 초보자부터 프로덕션까지 컨테이너 기술 정복 본문

DevOps

Docker 완전 마스터 가이드: 초보자부터 프로덕션까지 컨테이너 기술 정복

hobokai 2025. 7. 23. 08:39

목차

  1. Docker란 무엇인가?
  2. Docker 설치 및 초기 설정
  3. Docker 핵심 개념
  4. 이미지와 컨테이너 관리
  5. Dockerfile 작성 마스터
  6. Docker Compose 활용
  7. 네트워킹과 볼륨 관리
  8. Docker 레지스트리
  9. 보안 및 베스트 프랙티스
  10. 모니터링 및 로깅
  11. 프로덕션 배포 전략
  12. Docker와 Kubernetes
  13. 문제 해결 가이드
  14. 결론

Docker란 무엇인가?

Docker는 2013년 Solomon Hykes가 개발한 컨테이너화 플랫폼입니다. 애플리케이션과 그 의존성을 가벼운 컨테이너로 패키징하여 어떤 환경에서든 일관되게 실행할 수 있게 해줍니다.

Docker의 핵심 가치

  • 🚀 이식성 - "한 번 빌드하면 어디서나 실행"
  • 효율성 - VM보다 훨씬 가벼운 리소스 사용
  • 🔧 일관성 - 개발/테스트/프로덕션 환경 동일화
  • 📦 격리 - 애플리케이션 간 독립성 보장
  • 🔄 확장성 - 쉬운 스케일링과 배포
  • 🛠️ DevOps 지원 - CI/CD 파이프라인 최적화

Docker vs 가상머신 비교

특성 Docker 컨테이너 가상머신
리소스 사용량 매우 낮음 높음
시작 시간 초 단위 분 단위
격리 수준 프로세스 레벨 하드웨어 레벨
이식성 매우 높음 제한적
보안 공유 커널 완전 격리
관리 복잡성 낮음 높음

Docker 설치 및 초기 설정

Windows 설치

# Docker Desktop for Windows
# https://desktop.docker.com/win/main/amd64/Docker%20Desktop%20Installer.exe

# Chocolatey 사용
choco install docker-desktop

# winget 사용
winget install Docker.DockerDesktop

# WSL2 백엔드 권장 설정
wsl --set-default-version 2

macOS 설치

# Docker Desktop for Mac
# https://desktop.docker.com/mac/main/amd64/Docker.dmg

# Homebrew 사용
brew install --cask docker

# Apple Silicon Mac의 경우
arch -arm64 brew install --cask docker

Linux 설치

# Ubuntu/Debian
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# 또는 수동 설치
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

# CentOS/RHEL
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce docker-ce-cli containerd.io

# 사용자를 docker 그룹에 추가 (sudo 없이 사용)
sudo usermod -aG docker $USER
newgrp docker

초기 설정 및 검증

# Docker 버전 확인
docker --version
docker version

# Docker 정보 확인
docker info

# Hello World 컨테이너 실행
docker run hello-world

# Docker Compose 설치 (Linux)
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version

Docker 핵심 개념

Docker 아키텍처

Docker Client (CLI) ←→ Docker Daemon (dockerd)
                             ↓
┌─────────────────┬─────────────────┬─────────────────┐
│    Images       │   Containers    │    Networks     │
│   (Template)    │  (Running)      │   (Connection)  │
└─────────────────┴─────────────────┴─────────────────┘
                             ↓
                      Docker Registry
                    (Docker Hub, ECR, etc.)

핵심 구성 요소

1. 이미지 (Images)

  • 컨테이너 실행을 위한 읽기 전용 템플릿
  • 레이어 구조로 구성 (Union File System)
  • 버전 관리 지원 (태그 시스템)

2. 컨테이너 (Containers)

  • 이미지로부터 생성된 실행 인스턴스
  • 격리된 프로세스 환경
  • 상태: Created, Running, Paused, Stopped

3. 레지스트리 (Registry)

  • 이미지 저장소 (Docker Hub, AWS ECR, etc.)
  • Push/Pull을 통한 이미지 공유
  • 공개/비공개 저장소 지원

이미지와 컨테이너 관리

이미지 관리

# 이미지 검색
docker search nginx
docker search --limit=5 python

# 이미지 다운로드
docker pull nginx:latest
docker pull python:3.9-slim
docker pull ubuntu:22.04

# 이미지 목록 확인
docker images
docker image ls
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"

# 이미지 상세 정보
docker image inspect nginx:latest
docker history nginx:latest  # 레이어 히스토리

# 이미지 삭제
docker rmi nginx:latest
docker image rm python:3.9-slim
docker image prune  # 사용하지 않는 이미지 정리
docker image prune -a  # 모든 미사용 이미지 삭제

컨테이너 라이프사이클 관리

# 컨테이너 실행
docker run nginx                    # 포어그라운드 실행
docker run -d nginx                 # 백그라운드 실행 (detached)
docker run -it ubuntu:22.04 bash   # 인터랙티브 모드
docker run --name my-nginx nginx   # 컨테이너 이름 지정

# 포트 매핑
docker run -d -p 8080:80 nginx      # 호스트:컨테이너
docker run -d -P nginx              # 자동 포트 매핑

# 환경 변수 설정
docker run -e NODE_ENV=production node-app
docker run --env-file .env node-app

# 볼륨 마운트
docker run -v /host/path:/container/path nginx
docker run --mount type=bind,source=/host/path,target=/container/path nginx

# 컨테이너 목록 확인
docker ps          # 실행 중인 컨테이너
docker ps -a       # 모든 컨테이너
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"

# 컨테이너 제어
docker start container_name     # 시작
docker stop container_name      # 정지
docker restart container_name   # 재시작
docker pause container_name     # 일시정지
docker unpause container_name   # 일시정지 해제

# 컨테이너 접속
docker exec -it container_name bash
docker attach container_name

# 컨테이너 로그 확인
docker logs container_name
docker logs -f container_name   # 실시간 로그
docker logs --tail 100 container_name  # 최근 100줄

# 컨테이너 삭제
docker rm container_name
docker rm -f container_name     # 강제 삭제
docker container prune          # 중지된 컨테이너 정리

컨테이너 리소스 관리

# 리소스 제한
docker run -m 512m nginx        # 메모리 제한
docker run --cpus="1.5" nginx  # CPU 제한
docker run --memory=1g --cpus=2 nginx

# 실시간 리소스 사용량 확인
docker stats
docker stats container_name

# 컨테이너 정보 확인
docker inspect container_name
docker top container_name       # 프로세스 확인

Dockerfile 작성 마스터

Dockerfile 기본 구조

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

# 메타데이터 설정
LABEL maintainer="your-email@example.com"
LABEL version="1.0"
LABEL description="Node.js application"

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

# 파일 복사
COPY package*.json ./
COPY . .

# 의존성 설치
RUN npm ci --only=production

# 포트 노출
EXPOSE 3000

# 사용자 변경 (보안)
USER node

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

주요 Dockerfile 명령어

FROM - 베이스 이미지

FROM ubuntu:22.04                    # 특정 버전
FROM node:18-alpine                  # 경량화 버전
FROM scratch                         # 빈 이미지에서 시작
FROM node:18 AS builder             # 멀티 스테이지 빌드

RUN - 명령 실행

# 각각의 RUN은 새로운 레이어 생성
RUN apt-get update
RUN apt-get install -y curl

# 레이어 최적화 - 하나의 RUN으로 결합
RUN apt-get update && \
    apt-get install -y curl && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

COPY vs ADD

# COPY - 단순 파일 복사 (권장)
COPY src/ /app/src/
COPY package.json .

# ADD - 추가 기능 (압축 해제, URL 다운로드)
ADD https://example.com/file.tar.gz /tmp/
ADD archive.tar.gz /extracted/

ENV - 환경 변수

ENV NODE_ENV=production
ENV PORT=3000
ENV DATABASE_URL=postgresql://user:pass@db:5432/mydb

# 또는 한 번에
ENV NODE_ENV=production \
    PORT=3000 \
    DATABASE_URL=postgresql://user:pass@db:5432/mydb

고급 Dockerfile 패턴

멀티 스테이지 빌드

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

# 프로덕션 스테이지
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

최적화된 Node.js Dockerfile

FROM node:18-alpine AS base
WORKDIR /app
COPY package*.json ./

# 개발 의존성 포함 빌드 스테이지
FROM base AS deps
RUN npm ci

# 빌드 스테이지
FROM base AS build
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

# 프로덕션 런타임
FROM base AS runtime
ENV NODE_ENV=production
RUN addgroup --system --gid 1001 nodejs && \
    adduser --system --uid 1001 nextjs
COPY --from=build --chown=nextjs:nodejs /app/dist ./dist
COPY --from=build --chown=nextjs:nodejs /app/package*.json ./
RUN npm ci --only=production && npm cache clean --force
USER nextjs
EXPOSE 3000
CMD ["npm", "start"]

Docker 이미지 빌드

# 기본 빌드
docker build -t my-app:latest .
docker build -t my-app:v1.0 -f Dockerfile.prod .

# 빌드 인수 사용
docker build --build-arg NODE_ENV=production -t my-app .

# 캐시 없이 빌드
docker build --no-cache -t my-app .

# 타겟 스테이지 지정
docker build --target production -t my-app:prod .

# 멀티 플랫폼 빌드
docker buildx build --platform linux/amd64,linux/arm64 -t my-app:multi .

Docker Compose 활용

Docker Compose란?

여러 컨테이너로 구성된 애플리케이션을 정의하고 실행하는 도구입니다.

docker-compose.yml 기본 구조

version: '3.8'

services:
  web:
    build: 
      context: .
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=development
      - DATABASE_URL=postgresql://postgres:password@db:5432/myapp
    volumes:
      - .:/app
      - /app/node_modules
    depends_on:
      - db
      - redis
    networks:
      - app-network

  db:
    image: postgres:14
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
      POSTGRES_DB: myapp
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    networks:
      - app-network

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    networks:
      - app-network

volumes:
  postgres_data:

networks:
  app-network:
    driver: bridge

실제 프로젝트 예시 - MERN 스택

version: '3.8'

services:
  # MongoDB 데이터베이스
  mongo:
    image: mongo:6
    container_name: mern_mongo
    restart: unless-stopped
    environment:
      MONGO_INITDB_ROOT_USERNAME: admin
      MONGO_INITDB_ROOT_PASSWORD: password123
    volumes:
      - mongo_data:/data/db
    ports:
      - "27017:27017"
    networks:
      - mern_network

  # Express.js 백엔드
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    container_name: mern_backend
    restart: unless-stopped
    environment:
      - NODE_ENV=development
      - MONGO_URI=mongodb://admin:password123@mongo:27017/mernapp?authSource=admin
      - JWT_SECRET=your-secret-key
    ports:
      - "5000:5000"
    volumes:
      - ./backend:/app
      - /app/node_modules
    depends_on:
      - mongo
    networks:
      - mern_network

  # React.js 프론트엔드
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile.dev
    container_name: mern_frontend
    restart: unless-stopped
    environment:
      - REACT_APP_API_URL=http://localhost:5000
    ports:
      - "3000:3000"
    volumes:
      - ./frontend:/app
      - /app/node_modules
    depends_on:
      - backend
    networks:
      - mern_network

  # Nginx 리버스 프록시 (프로덕션용)
  nginx:
    image: nginx:alpine
    container_name: mern_nginx
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - frontend
      - backend
    networks:
      - mern_network
    profiles:
      - production

volumes:
  mongo_data:

networks:
  mern_network:
    driver: bridge

Docker Compose 명령어

# 서비스 시작
docker-compose up                    # 포어그라운드
docker-compose up -d                 # 백그라운드
docker-compose up --build            # 이미지 다시 빌드

# 특정 서비스만 시작
docker-compose up web db

# 서비스 중지
docker-compose down                  # 컨테이너 삭제
docker-compose down -v              # 볼륨도 함께 삭제
docker-compose stop                 # 컨테이너만 중지

# 서비스 상태 확인
docker-compose ps
docker-compose top

# 로그 확인
docker-compose logs
docker-compose logs -f web          # 특정 서비스 실시간 로그

# 스케일링
docker-compose up -d --scale web=3

# 설정 검증
docker-compose config
docker-compose config --services

네트워킹과 볼륨 관리

Docker 네트워킹

네트워크 타입

# 기본 네트워크 확인
docker network ls

# bridge (기본) - 같은 호스트 내 컨테이너 통신
# host - 호스트 네트워크 직접 사용
# none - 네트워크 없음
# overlay - 여러 호스트 간 통신 (Swarm)

사용자 정의 네트워크

# 브리지 네트워크 생성
docker network create my-network
docker network create --driver bridge --subnet=172.20.0.0/16 my-custom-net

# 컨테이너를 네트워크에 연결
docker run -d --name web --network my-network nginx
docker run -d --name db --network my-network postgres

# 실행 중인 컨테이너를 네트워크에 연결
docker network connect my-network container_name

# 네트워크에서 연결 해제
docker network disconnect my-network container_name

# 네트워크 상세 정보
docker network inspect my-network

컨테이너 간 통신

# 같은 네트워크의 컨테이너는 이름으로 통신 가능
docker run -d --name db --network my-app postgres
docker run -d --name web --network my-app -e DATABASE_HOST=db nginx

# 포트 노출 (호스트에서 접근)
docker run -d -p 8080:80 --name web nginx  # 8080 → 80
docker run -d -P nginx                     # 자동 포트 할당

Docker 볼륨

볼륨 타입

  1. Named Volume: Docker가 관리하는 볼륨
  2. Bind Mount: 호스트 디렉토리 마운트
  3. tmpfs Mount: 메모리에 임시 저장

볼륨 관리

# Named Volume 생성
docker volume create my-volume
docker volume create --driver local --opt type=nfs --opt device=:/path/to/dir my-nfs-volume

# 볼륨 목록 및 정보
docker volume ls
docker volume inspect my-volume

# 볼륨 사용
docker run -v my-volume:/data nginx              # Named volume
docker run -v /host/path:/container/path nginx   # Bind mount
docker run --tmpfs /tmp nginx                    # tmpfs mount

# Mount 명령 사용 (더 명확한 문법)
docker run --mount source=my-volume,target=/data nginx
docker run --mount type=bind,source=/host/path,target=/container/path nginx
docker run --mount type=tmpfs,target=/tmp nginx

# 볼륨 삭제
docker volume rm my-volume
docker volume prune  # 사용하지 않는 볼륨 정리

볼륨 백업 및 복원

# 볼륨 백업
docker run --rm -v my-volume:/data -v $(pwd):/backup alpine tar czf /backup/backup.tar.gz -C /data .

# 볼륨 복원
docker run --rm -v my-volume:/data -v $(pwd):/backup alpine tar xzf /backup/backup.tar.gz -C /data

# 컨테이너 간 볼륨 복사
docker run --rm -v source-volume:/from -v target-volume:/to alpine cp -R /from/. /to/

Docker 레지스트리

Docker Hub 사용

# Docker Hub 로그인
docker login

# 이미지 태깅
docker tag my-app:latest username/my-app:latest
docker tag my-app:latest username/my-app:v1.0

# 이미지 업로드
docker push username/my-app:latest
docker push username/my-app:v1.0

# 이미지 다운로드
docker pull username/my-app:latest

프라이빗 레지스트리

# 로컬 레지스트리 실행
docker run -d -p 5000:5000 --name registry registry:2

# 프라이빗 레지스트리에 업로드
docker tag my-app localhost:5000/my-app
docker push localhost:5000/my-app

# SSL 인증서가 없는 레지스트리 사용
# /etc/docker/daemon.json
{
  "insecure-registries": ["localhost:5000"]
}

AWS ECR 사용

# AWS CLI 로그인
aws ecr get-login-password --region region | docker login --username AWS --password-stdin account-id.dkr.ecr.region.amazonaws.com

# 레지스트리 생성
aws ecr create-repository --repository-name my-app

# 이미지 업로드
docker tag my-app:latest account-id.dkr.ecr.region.amazonaws.com/my-app:latest
docker push account-id.dkr.ecr.region.amazonaws.com/my-app:latest

보안 및 베스트 프랙티스

이미지 보안

# 1. 최소 권한 원칙 - 루트 사용자 피하기
FROM node:18-alpine
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
USER nextjs

# 2. 최신 베이스 이미지 사용
FROM node:18-alpine  # 특정 버전 명시
# FROM node:latest   # latest 태그 피하기

# 3. 불필요한 패키지 제거
RUN apk add --no-cache git && \
    npm install && \
    apk del git

# 4. 민감한 정보 하드코딩 금지
# 환경 변수 또는 시크릿 사용
ENV DATABASE_URL=$DATABASE_URL

컨테이너 보안 설정

# 읽기 전용 루트 파일시스템
docker run --read-only -v /tmp:/tmp:rw my-app

# 권한 제한
docker run --user 1001:1001 my-app
docker run --cap-drop ALL --cap-add CHOWN my-app

# 리소스 제한
docker run -m 512m --cpus 0.5 my-app

# seccomp, AppArmor 프로필 적용
docker run --security-opt seccomp=profile.json my-app

.dockerignore 작성

# .dockerignore 파일
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
.env.local
.nyc_output
coverage
.cache
dist
build

이미지 취약점 스캔

# Docker Scout (Docker Desktop 내장)
docker scout quickview my-app:latest
docker scout cves my-app:latest

# Trivy 사용
trivy image my-app:latest

# Snyk 사용
snyk container test my-app:latest

모니터링 및 로깅

컨테이너 모니터링

# 리소스 사용량 모니터링
docker stats
docker stats --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}"

# 시스템 이벤트 모니터링
docker system events
docker system events --filter container=my-app

# 시스템 정보
docker system info
docker system df  # 디스크 사용량

로깅 설정

# 로그 드라이버 설정
docker run --log-driver json-file --log-opt max-size=10m --log-opt max-file=3 my-app

# syslog 드라이버
docker run --log-driver syslog --log-opt syslog-address=tcp://192.168.1.3:514 my-app

# 로그 확인
docker logs my-app
docker logs --follow --tail 100 my-app

Docker Compose 모니터링 스택

version: '3.8'

services:
  # 애플리케이션
  app:
    build: .
    ports:
      - "3000:3000"
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  # Prometheus 모니터링
  prometheus:
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'

  # Grafana 대시보드
  grafana:
    image: grafana/grafana:latest
    ports:
      - "3001:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - grafana_data:/var/lib/grafana

  # 로그 수집 (ELK 스택)
  elasticsearch:
    image: elasticsearch:8.5.0
    environment:
      - discovery.type=single-node
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    volumes:
      - elasticsearch_data:/usr/share/elasticsearch/data

  logstash:
    image: logstash:8.5.0
    volumes:
      - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf

  kibana:
    image: kibana:8.5.0
    ports:
      - "5601:5601"
    depends_on:
      - elasticsearch

volumes:
  prometheus_data:
  grafana_data:
  elasticsearch_data:

프로덕션 배포 전략

배포 패턴

Blue-Green 배포

# Green (새 버전) 환경 준비
docker run -d --name app-green my-app:v2
docker run -d --name app-green-db postgres:14

# 헬스 체크 후 로드 밸런서 전환
# Blue (기존) 환경 제거
docker stop app-blue app-blue-db
docker rm app-blue app-blue-db

Rolling 업데이트

# docker-compose.yml
version: '3.8'
services:
  app:
    image: my-app:latest
    deploy:
      replicas: 3
      update_config:
        parallelism: 1
        delay: 10s
        failure_action: rollback
        order: start-first

Canary 배포

# 기존 버전 (90%)
docker-compose scale app=9

# 새 버전 (10%)
docker run -d --name app-canary my-app:v2

헬스 체크 구현

# Dockerfile에서 헬스 체크
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1
# Docker Compose에서 헬스 체크
version: '3.8'
services:
  app:
    build: .
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s

환경별 구성 관리

# 환경별 Compose 파일
docker-compose.yml                    # 기본
docker-compose.override.yml           # 개발 (자동 로드)
docker-compose.prod.yml              # 프로덕션

# 프로덕션 환경 실행
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

Docker와 Kubernetes

Docker에서 Kubernetes로 마이그레이션

Docker Compose에서 Kubernetes 변환

# Kompose 도구 사용
curl -L https://github.com/kubernetes/kompose/releases/latest/download/kompose-linux-amd64 -o kompose
chmod +x kompose
sudo mv ./kompose /usr/local/bin/kompose

# 변환 실행
kompose convert -f docker-compose.yml

직접 Kubernetes 매니페스트 작성

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: app
        image: my-app:latest
        ports:
        - containerPort: 3000
        env:
        - name: NODE_ENV
          value: "production"
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"

---
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-app-service
spec:
  selector:
    app: my-app
  ports:
  - port: 80
    targetPort: 3000
  type: LoadBalancer

로컬 Kubernetes 개발 환경

# minikube 사용
minikube start
minikube docker-env
eval $(minikube docker-env)

# Docker Desktop Kubernetes 활성화
# Settings > Kubernetes > Enable Kubernetes

# Kind 사용 (Kubernetes in Docker)
kind create cluster --name my-cluster

문제 해결 가이드

일반적인 문제들

1. 포트 충돌

# 사용 중인 포트 확인
netstat -tlnp | grep :3000
lsof -i :3000

# 다른 포트 사용
docker run -p 3001:3000 my-app

2. 권한 문제

# Docker 그룹에 사용자 추가 (Linux)
sudo usermod -aG docker $USER
newgrp docker

# 볼륨 권한 문제 해결
docker run -v /host/path:/container/path --user $(id -u):$(id -g) my-app

3. 메모리 부족

# Docker Desktop 메모리 설정 확인
docker system df
docker system prune -a  # 불필요한 데이터 정리

# 컨테이너 메모리 제한
docker run -m 512m my-app

4. 네트워크 연결 문제

# 컨테이너 네트워크 디버깅
docker exec -it container_name sh
ping other_container_name
nslookup other_container_name

# 포트 연결 확인
docker port container_name

디버깅 도구들

# 컨테이너 내부 조사
docker exec -it container_name bash
docker exec -it container_name sh  # Alpine 기반

# 컨테이너 프로세스 확인
docker top container_name

# 파일시스템 변경사항 확인
docker diff container_name

# 컨테이너에서 호스트로 파일 복사
docker cp container_name:/path/to/file ./local_file
docker cp ./local_file container_name:/path/to/file

성능 최적화

이미지 크기 최적화

# 멀티 스테이지 빌드 사용
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app .
CMD ["npm", "start"]

빌드 캐시 활용

# 자주 변하지 않는 것부터 먼저
COPY package*.json ./
RUN npm install

# 자주 변하는 것은 나중에
COPY . .

.dockerignore 최적화

# 불필요한 파일 제외로 빌드 컨텍스트 크기 감소
node_modules
.git
*.log
.cache
dist
build
coverage

결론

Docker는 현대 소프트웨어 개발과 배포에서 필수적인 기술입니다. 컨테이너 기술을 통해 개발 환경의 일관성, 배포의 효율성, 그리고 인프라 관리의 간소화를 실현할 수 있습니다.

Docker 마스터 로드맵

  1. 기초: Docker 개념, 기본 명령어, 이미지/컨테이너 관리
  2. 중급: Dockerfile 작성, Docker Compose, 네트워킹, 볼륨
  3. 고급: 보안, 모니터링, 프로덕션 배포, 최적화
  4. 전문가: Kubernetes 연동, CI/CD 파이프라인, 마이크로서비스 아키텍처

계속 학습하기 위한 리소스

실무 적용 팁

  • 점진적 도입: 기존 프로젝트에 단계적으로 적용
  • 모니터링 필수: 프로덕션 환경에서는 반드시 모니터링 설정
  • 보안 고려: 이미지 스캔, 권한 관리, 시크릿 관리
  • 문서화: 팀 내 Docker 사용법과 베스트 프랙티스 문서화

Docker를 마스터하고 컨테이너 기술을 활용한 효율적인 개발 환경을 구축해보세요! 🐳