Docker 네트워크·볼륨이 중요한 이유
Docker 컨테이너는 기본적으로 격리되어 있다. 컨테이너 간 통신은 네트워크로, 데이터 영속성은 볼륨으로 해결한다. 이 두 가지를 정확히 이해하지 못하면 프로덕션에서 데이터 유실, 네트워크 단절, 보안 취약점이 발생한다.
1. Docker 네트워크 드라이버
| 드라이버 | 용도 | 특징 |
|---|---|---|
bridge |
단일 호스트 컨테이너 간 통신 | 기본 드라이버, DNS 자동 해석 |
host |
호스트 네트워크 직접 사용 | 포트 매핑 불필요, 격리 없음 |
overlay |
멀티 호스트 (Swarm/K8s) | VXLAN 터널링, 암호화 지원 |
macvlan |
물리 네트워크 직접 연결 | 컨테이너에 실제 MAC 주소 할당 |
none |
네트워크 완전 격리 | 보안 민감한 워크로드 |
2. Bridge 네트워크 심화
기본 docker0 브릿지 대신 사용자 정의 브릿지를 사용해야 한다.
# 사용자 정의 네트워크 생성
docker network create --driver bridge
--subnet 172.20.0.0/16
--gateway 172.20.0.1
--ip-range 172.20.240.0/20
app-network
# 컨테이너를 네트워크에 연결
docker run -d --name api --network app-network api-image
docker run -d --name db --network app-network postgres:16
# api 컨테이너에서 db를 이름으로 접근 가능
# ping db → 172.20.x.x (자동 DNS)
| 기능 | 기본 bridge | 사용자 정의 bridge |
|---|---|---|
| DNS 해석 | ❌ IP만 가능 | ✅ 컨테이너 이름으로 접근 |
| 격리 | 모든 컨테이너 공유 | 네트워크별 격리 |
| 런타임 연결/해제 | ❌ | ✅ connect/disconnect |
3. 네트워크 격리 패턴
마이크로서비스에서는 네트워크를 분리해 보안을 강화한다.
# docker-compose.yml
services:
nginx:
image: nginx:alpine
networks:
- frontend
ports:
- "80:80"
api:
image: api:latest
networks:
- frontend # nginx와 통신
- backend # DB와 통신
db:
image: postgres:16
networks:
- backend # api만 접근 가능
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7-alpine
networks:
- backend
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # 외부 인터넷 접근 차단
volumes:
pgdata:
internal: true로 설정하면 해당 네트워크의 컨테이너는 외부 인터넷에 접근할 수 없다. DB와 Redis를 외부로부터 완전히 격리한다. Docker Compose 기본 운영은 Docker Compose 운영 글을 참고하자.
4. Docker 볼륨 유형
| 유형 | 선언 | 특징 |
|---|---|---|
| Named Volume | pgdata:/var/lib/postgresql/data |
Docker 관리, 이식성 높음 |
| Bind Mount | ./data:/app/data |
호스트 경로 직접 마운트 |
| tmpfs | tmpfs: /tmp |
메모리에만 저장, 재시작 시 삭제 |
# Named Volume 생성과 관리
docker volume create --driver local
--opt type=none
--opt device=/mnt/ssd/pgdata
--opt o=bind
pgdata-ssd
# 볼륨 백업
docker run --rm
-v pgdata:/source:ro
-v $(pwd):/backup
alpine tar czf /backup/pgdata-backup.tar.gz -C /source .
# 볼륨 복원
docker run --rm
-v pgdata-new:/target
-v $(pwd):/backup
alpine tar xzf /backup/pgdata-backup.tar.gz -C /target
# 볼륨 정리
docker volume prune -f # 사용하지 않는 볼륨 삭제
docker volume ls --filter dangling=true # 고아 볼륨 확인
5. 볼륨 드라이버와 NFS
멀티 호스트 환경에서는 NFS나 외부 스토리지 드라이버를 사용한다.
# NFS 볼륨
docker volume create --driver local
--opt type=nfs
--opt o=addr=192.168.1.100,rw,nfsvers=4
--opt device=:/exports/data
nfs-data
# docker-compose에서 NFS
volumes:
shared-data:
driver: local
driver_opts:
type: nfs
o: addr=192.168.1.100,rw,nfsvers=4
device: ":/exports/data"
6. 보안 베스트 프랙티스
# 읽기 전용 볼륨
docker run -v config:/app/config:ro api-image
# 읽기 전용 컨테이너 + tmpfs
docker run --read-only
--tmpfs /tmp:rw,noexec,nosuid
--tmpfs /var/run:rw
api-image
# 네트워크 트래픽 암호화 (overlay)
docker network create --driver overlay
--opt encrypted
secure-network
# 특정 IP만 포트 노출
docker run -p 127.0.0.1:5432:5432 postgres:16
| 보안 규칙 | 설명 |
|---|---|
| DB 포트는 127.0.0.1만 | 외부 노출 방지 |
| internal 네트워크 | 백엔드 서비스 인터넷 차단 |
| 읽기 전용 볼륨 | 설정 파일 변조 방지 |
| tmpfs for secrets | 민감 데이터 디스크 미저장 |
7. 트러블슈팅
# 네트워크 상세 정보 (연결된 컨테이너, IP 확인)
docker network inspect app-network
# 컨테이너 간 연결 테스트
docker exec api ping -c 3 db
docker exec api nslookup db
# 볼륨 마운트 확인
docker inspect --format='{{json .Mounts}}' container_name | jq
# 네트워크 대역폭 제한 (tc)
docker exec api tc qdisc add dev eth0 root tbf rate 100mbit burst 32kbit latency 50ms
Docker 이미지 최적화는 Docker Multi-Stage Build 글을 참고하자.
마무리
Docker 네트워크와 볼륨은 컨테이너 인프라의 근간이다. 사용자 정의 브릿지로 DNS 해석을 활용하고, internal 네트워크로 보안을 강화하며, Named Volume으로 데이터를 안전하게 관리하자. 이 기본기가 K8s로 확장할 때도 그대로 적용된다.