Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
Tags
- 인메모리데이터베이스
- 메시징 패턴
- 분산 시스템
- 모노리스 분해
- CI/CD
- 서비스 메시
- Kafka 클러스터
- docker
- rabbitmq
- RabbitMQ Exchange
- 서비스 설계
- 프로덕션 운영
- 이벤트 스트리밍
- 모니터링
- 마이크로서비스 통신
- infrastructureascode
- devops
- 고가용성
- 분산 모니터링
- 세션저장소
- 마이크로서비스
- ApacheBench
- 클러스터
- kubernetes
- 메시지 브로커
- 컨테이너오케스트레이션
- 보안
- 클라우드
- 마이크로서비스 운영
- Python
Archives
- Today
- Total
hobokai 님의 블로그
Docker 완전 마스터 가이드: 초보자부터 프로덕션까지 컨테이너 기술 정복 본문
목차
- Docker란 무엇인가?
- Docker 설치 및 초기 설정
- Docker 핵심 개념
- 이미지와 컨테이너 관리
- Dockerfile 작성 마스터
- Docker Compose 활용
- 네트워킹과 볼륨 관리
- Docker 레지스트리
- 보안 및 베스트 프랙티스
- 모니터링 및 로깅
- 프로덕션 배포 전략
- Docker와 Kubernetes
- 문제 해결 가이드
- 결론
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 볼륨
볼륨 타입
- Named Volume: Docker가 관리하는 볼륨
- Bind Mount: 호스트 디렉토리 마운트
- 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 마스터 로드맵
- 기초: Docker 개념, 기본 명령어, 이미지/컨테이너 관리
- 중급: Dockerfile 작성, Docker Compose, 네트워킹, 볼륨
- 고급: 보안, 모니터링, 프로덕션 배포, 최적화
- 전문가: Kubernetes 연동, CI/CD 파이프라인, 마이크로서비스 아키텍처
계속 학습하기 위한 리소스
- 📚 공식 문서: https://docs.docker.com/
- 🎓 Docker 공식 트레이닝: https://training.docker.com/
- 🧪 Play with Docker: https://labs.play-with-docker.com/
- 📖 Docker Deep Dive: Nigel Poulton 저서
- 🏆 Docker Certified Associate: 공식 인증
실무 적용 팁
- 점진적 도입: 기존 프로젝트에 단계적으로 적용
- 모니터링 필수: 프로덕션 환경에서는 반드시 모니터링 설정
- 보안 고려: 이미지 스캔, 권한 관리, 시크릿 관리
- 문서화: 팀 내 Docker 사용법과 베스트 프랙티스 문서화
Docker를 마스터하고 컨테이너 기술을 활용한 효율적인 개발 환경을 구축해보세요! 🐳
'DevOps' 카테고리의 다른 글
| Terraform 완전 마스터 가이드: Infrastructure as Code로 클라우드 인프라 자동화 (2) | 2025.07.23 |
|---|---|
| Kubernetes 완전 정복 가이드: 컨테이너 오케스트레이션부터 프로덕션까지 (0) | 2025.07.23 |
| Git 완전 정복 가이드: 초보자부터 고급 사용자까지 버전 관리 마스터하기 (6) | 2025.07.23 |
| Linux OS 완전 가이드: 초보자부터 고급 사용자까지 (0) | 2025.07.23 |