“이제와서 시작하는 Docker 마스터하기” Docker를 사용하다 보면 다양한 문제에 직면하게 됩니다. 이번 편에서는 일반적인 Docker 문제들과 해결 방법, 디버깅 기법을 정리했습니다. 이 가이드를 통해 문제를 빠르게 진단하고 해결할 수 있습니다.
일반적인 Docker 문제
1. 컨테이너가 시작되지 않을 때
1
2
3
4
5
6
7
8
9
10
11
12
| # 문제 진단 순서
# 1. 컨테이너 상태 확인
docker ps -a
# 2. 컨테이너 로그 확인
docker logs container-name
# 3. 상세 정보 확인
docker inspect container-name
# 4. 이벤트 확인
docker events --since '10m' --filter container=container-name
|
일반적인 원인과 해결법:
1
2
3
4
5
6
7
8
9
10
| # Exit Code 125: Docker 데몬 문제
systemctl status docker
systemctl restart docker
# Exit Code 126: 컨테이너 명령을 실행할 수 없음
docker run --rm -it image-name /bin/sh
# 실행 파일 권한 확인
# Exit Code 127: 명령을 찾을 수 없음
docker run --rm -it image-name which command-name
|
2. 네트워크 연결 문제
1
2
3
4
5
6
7
8
9
10
11
12
13
| # 네트워크 진단
# 1. 네트워크 목록 확인
docker network ls
# 2. 네트워크 상세 정보
docker network inspect bridge
# 3. 컨테이너 네트워크 설정 확인
docker inspect container-name | grep -A 20 NetworkMode
# 4. 컨테이너 간 연결 테스트
docker exec container1 ping container2
docker exec container1 nc -zv container2 80
|
해결 방법:
1
2
3
4
5
6
7
8
9
10
| # DNS 문제 해결
docker run --dns 8.8.8.8 --dns 8.8.4.4 image-name
# 네트워크 재생성
docker network rm problematic-network
docker network create new-network
# 방화벽 규칙 확인
sudo iptables -L -n
sudo iptables -L DOCKER -n
|
3. 디스크 공간 부족
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| # Docker 디스크 사용량 확인
docker system df
# 상세 정보
docker system df -v
# 정리 명령어
# 사용하지 않는 컨테이너 삭제
docker container prune
# 사용하지 않는 이미지 삭제
docker image prune -a
# 사용하지 않는 볼륨 삭제
docker volume prune
# 사용하지 않는 네트워크 삭제
docker network prune
# 전체 정리 (주의!)
docker system prune -a --volumes
|
자동 정리 스크립트:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| #!/bin/bash
# docker-cleanup.sh
echo "Docker 정리 시작..."
# 중지된 컨테이너 삭제
echo "중지된 컨테이너 삭제 중..."
docker container prune -f
# 사용하지 않는 이미지 삭제 (1주일 이상)
echo "오래된 이미지 삭제 중..."
docker image prune -a -f --filter "until=168h"
# 사용하지 않는 볼륨 삭제
echo "사용하지 않는 볼륨 삭제 중..."
docker volume prune -f
# 빌드 캐시 정리
echo "빌드 캐시 정리 중..."
docker builder prune -f --filter "until=168h"
echo "정리 완료!"
docker system df
|
성능 문제 해결
1. 느린 빌드 속도
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| # 개선 전
FROM node:16
COPY . /app
WORKDIR /app
RUN npm install
RUN npm run build
# 개선 후
FROM node:16 AS builder
WORKDIR /app
# 의존성 캐싱
COPY package*.json ./
RUN npm ci --only=production
# 소스 복사
COPY . .
RUN npm run build
# 멀티 스테이지
FROM node:16-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/index.js"]
|
BuildKit 활성화:
1
2
3
4
5
6
7
8
9
| # BuildKit으로 빌드
DOCKER_BUILDKIT=1 docker build -t myapp .
# 또는 daemon.json에 설정
{
"features": {
"buildkit": true
}
}
|
2. 메모리 문제
1
2
3
4
5
6
7
8
| # 컨테이너 메모리 사용량 확인
docker stats --no-stream
# 메모리 제한 설정
docker run -m 512m --memory-swap 512m image-name
# OOM Kill 비활성화
docker run -m 512m --oom-kill-disable image-name
|
Java 애플리케이션 메모리 설정:
1
2
3
| # JVM 메모리 설정
ENV JAVA_OPTS="-Xmx512m -Xms256m"
CMD ["java", "$JAVA_OPTS", "-jar", "app.jar"]
|
3. CPU 사용률 문제
1
2
3
4
5
6
7
8
| # CPU 사용률 제한
docker run --cpus="1.5" image-name
# CPU 공유 가중치
docker run --cpu-shares=512 image-name
# 특정 CPU 코어 지정
docker run --cpuset-cpus="0,1" image-name
|
로깅과 디버깅
1. 상세 로그 활성화
1
2
3
4
5
6
7
8
9
10
11
12
| # Docker 데몬 디버그 모드
# /etc/docker/daemon.json
{
"debug": true,
"log-level": "debug"
}
# 재시작
systemctl restart docker
# 로그 확인
journalctl -u docker.service -f
|
2. 컨테이너 디버깅
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # 실행 중인 컨테이너 디버깅
docker exec -it container-name /bin/sh
# 디버깅 도구 설치
docker exec container-name apk add --no-cache \
curl wget netcat-openbsd tcpdump
# 프로세스 확인
docker exec container-name ps aux
docker exec container-name top
# 네트워크 상태 확인
docker exec container-name netstat -tulpn
docker exec container-name ss -tulpn
|
3. 디버깅용 컨테이너
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # Dockerfile.debug
FROM myapp:latest
# 디버깅 도구 설치
RUN apt-get update && apt-get install -y \
strace \
tcpdump \
netcat \
curl \
vim \
procps \
&& rm -rf /var/lib/apt/lists/*
# 디버그 포트 노출
EXPOSE 9229
# Node.js 디버그 모드
CMD ["node", "--inspect=0.0.0.0:9229", "app.js"]
|
보안 문제 해결
1. 권한 문제
1
2
3
4
5
6
7
8
9
| # 권한 오류 해결
# 사용자 추가
docker exec container-name adduser -D -u 1000 appuser
# 파일 권한 변경
docker exec container-name chown -R appuser:appuser /app
# 특정 사용자로 실행
docker run --user 1000:1000 image-name
|
2. SELinux 문제 (CentOS/RHEL)
1
2
3
4
5
6
7
8
| # SELinux 상태 확인
getenforce
# 볼륨 마운트 시 :z 옵션 사용
docker run -v /host/path:/container/path:z image-name
# SELinux 컨텍스트 확인
ls -Z /var/lib/docker
|
Docker Compose 문제 해결
1. 서비스 시작 순서
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # docker-compose.yml
version: '3.8'
services:
web:
image: myapp
depends_on:
db:
condition: service_healthy
command: ["./wait-for-it.sh", "db:5432", "--", "npm", "start"]
db:
image: postgres
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
|
2. 환경 변수 문제
1
2
3
4
5
6
7
8
| # 환경 변수 확인
docker compose config
# 환경 변수 디버깅
docker compose run --rm web env
# .env 파일 검증
docker compose --env-file .env.test config
|
도구와 유틸리티
1. Docker 디버깅 도구
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # ctop - 컨테이너 모니터링
docker run --rm -it \
--name=ctop \
-v /var/run/docker.sock:/var/run/docker.sock \
quay.io/vektorlab/ctop:latest
# dive - 이미지 레이어 분석
docker run --rm -it \
-v /var/run/docker.sock:/var/run/docker.sock \
wagoodman/dive:latest image-name
# docker-debug - 실행 중인 컨테이너 디버깅
docker run -it --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
-p 2333:2333 \
zeromake/docker-debug:latest
|
2. 모니터링 설정
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
| # monitoring-stack.yml
version: '3.8'
services:
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker:/var/lib/docker:ro
ports:
- "8080:8080"
prometheus:
image: prom/prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
grafana:
image: grafana/grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
|
일반적인 에러 메시지와 해결법
1. “Cannot connect to the Docker daemon”
1
2
3
4
5
6
7
8
9
| # Docker 서비스 상태 확인
systemctl status docker
# Docker 소켓 권한 확인
ls -la /var/run/docker.sock
# 사용자를 docker 그룹에 추가
sudo usermod -aG docker $USER
newgrp docker
|
2. “No space left on device”
1
2
3
4
5
6
7
8
9
10
| # Docker 루트 디렉토리 변경
# /etc/docker/daemon.json
{
"data-root": "/mnt/docker"
}
# 기존 데이터 이동
systemctl stop docker
rsync -aqxP /var/lib/docker/ /mnt/docker/
systemctl start docker
|
3. “Port is already allocated”
1
2
3
4
5
6
7
8
9
| # 포트 사용 프로세스 확인
sudo lsof -i :80
sudo netstat -tulpn | grep :80
# 프로세스 종료
sudo kill -9 PID
# 또는 다른 포트 사용
docker run -p 8080:80 image-name
|
체크리스트
문제 해결 체크리스트
- Docker 데몬이 실행 중인가?
- 충분한 디스크 공간이 있는가?
- 메모리와 CPU 리소스가 충분한가?
- 네트워크 연결이 정상인가?
- 올바른 이미지 태그를 사용하고 있는가?
- 환경 변수가 올바르게 설정되어 있는가?
- 볼륨 마운트 경로가 존재하는가?
- 포트가 이미 사용 중이지 않은가?
- SELinux나 AppArmor 정책에 문제가 없는가?
- 로그에 명확한 에러 메시지가 있는가?
성능 최적화 팁
1. 빌드 최적화
1
2
3
4
5
| # 빌드 캐시 활용
docker build --cache-from myapp:latest -t myapp:new .
# 병렬 빌드
docker buildx build --platform linux/amd64,linux/arm64 .
|
2. 런타임 최적화
1
2
3
4
5
6
7
8
| # 로깅 드라이버 최적화
docker run --log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
image-name
# 스토리지 드라이버 확인
docker info | grep "Storage Driver"
|
마무리
Docker 문제 해결은 체계적인 접근이 중요합니다. 로그 확인, 리소스 모니터링, 네트워크 진단 등의 기본적인 절차를 따르면 대부분의 문제를 해결할 수 있습니다. 다음 편에서는 Docker 생태계와 미래에 대해 알아보겠습니다.
다음 편 예고
- Docker 생태계 소개
- 관련 기술과 도구들
- 컨테이너 기술의 미래
- 학습 리소스와 커뮤니티
Docker 여정의 마지막 이야기! 🎯
📚 Docker 마스터하기 시리즈
🐳 기초편 (입문자용 - 5편)
- Docker란 무엇인가?
- Docker 설치 및 환경 설정
- 첫 번째 컨테이너 실행하기
- Docker 이미지 이해하기
- Dockerfile 작성하기
💼 실전편 (중급자용 - 6편)
- Docker 네트워크 기초
- Docker 볼륨과 데이터 관리
- Docker Compose 입문
- 멀티 컨테이너 애플리케이션
- Docker Hub 활용하기
- Docker 보안 베스트 프랙티스
🚀 고급편 (전문가용 - 9편)
- Docker 로그와 모니터링
- Docker로 Node.js 애플리케이션 배포
- Docker로 Python 애플리케이션 배포
- Docker로 데이터베이스 운영
- Docker 이미지 최적화
- Docker와 CI/CD
- Docker Swarm 기초
- 문제 해결과 트러블슈팅 ← 현재 글
- Docker 생태계와 미래