Skip to main content

Docker Volume & Network

컨테이너 데이터 지속성(Volume)과 네트워크 통신


📚 시리즈 네비게이션

이전현재다음
Dockerfile & ImageVolume & NetworkDocker Compose

시리즈 목차


📦 Volume (볼륨)

왜 필요한가?

컨테이너는 일시적(ephemeral) 임.

flowchart TB
subgraph Without["볼륨 없이"]
C1["Container"]
D1["Data"]
C1 --- D1
D1 -.->|"컨테이너 삭제 시<br/>함께 삭제됨!"| X1["❌"]
end

볼륨 사용 시:

flowchart TB
subgraph With["볼륨 사용"]
CA["Container A"]
CB["Container B"]
Vol["Volume<br/>(Data)"]

CA --> Vol
CB --> Vol
end

Note["컨테이너 삭제해도<br/>볼륨 데이터 유지"]

세 가지 방식

방식관리경로용도
VolumeDocker/var/lib/docker/volumes/운영 환경 권장
Bind Mount사용자호스트 임의 경로개발 환경, 설정 파일
tmpfs메모리메모리임시 데이터, 보안

Volume (Docker 관리)

# 볼륨 생성
docker volume create mydata

# 볼륨 목록
docker volume ls

# 볼륨 상세 정보
docker volume inspect mydata

# 볼륨 삭제
docker volume rm mydata

# 미사용 볼륨 정리
docker volume prune

컨테이너에 연결:

# -v 옵션 (볼륨명:컨테이너경로)
docker run -d \
--name db \
-v mydata:/var/lib/mysql \
mysql:8.0

# --mount 옵션 (더 명시적)
docker run -d \
--name db \
--mount source=mydata,target=/var/lib/mysql \
mysql:8.0

자동 생성:

# 볼륨이 없으면 자동 생성
docker run -d -v newvolume:/data nginx

Bind Mount (호스트 경로)

호스트의 특정 디렉토리를 컨테이너에 마운트.

# -v 옵션 (호스트경로:컨테이너경로)
docker run -d \
-v /home/user/html:/usr/share/nginx/html \
nginx

# --mount 옵션
docker run -d \
--mount type=bind,source=/home/user/html,target=/usr/share/nginx/html \
nginx

# 읽기 전용
docker run -d \
-v /home/user/html:/usr/share/nginx/html:ro \
nginx

Volume vs Bind Mount 구분:

# 볼륨 (이름만)
-v myvolume:/data

# Bind Mount (경로)
-v /host/path:/data
-v ./local:/data

tmpfs (메모리)

메모리에 임시 저장. 컨테이너 종료 시 삭제됨.

docker run -d \
--tmpfs /tmp \
nginx

# 또는
docker run -d \
--mount type=tmpfs,target=/tmp,tmpfs-size=100m \
nginx

용도:

  • 임시 파일
  • 민감한 데이터 (비밀번호 파일 등)
  • 빠른 I/O 필요

실습: MySQL 데이터 유지

# 볼륨 생성
docker volume create mysql-data

# MySQL 실행 (볼륨 연결)
docker run -d \
--name mysql-test \
-e MYSQL_ROOT_PASSWORD=secret \
-v mysql-data:/var/lib/mysql \
mysql:8.0

# 데이터 생성
docker exec -it mysql-test mysql -u root -psecret -e "
CREATE DATABASE testdb;
USE testdb;
CREATE TABLE users (id INT, name VARCHAR(50));
INSERT INTO users VALUES (1, 'Alice');
"

# 컨테이너 삭제
docker rm -f mysql-test

# 새 컨테이너로 같은 볼륨 연결
docker run -d \
--name mysql-test2 \
-e MYSQL_ROOT_PASSWORD=secret \
-v mysql-data:/var/lib/mysql \
mysql:8.0

# 데이터 확인 (유지됨!)
docker exec -it mysql-test2 mysql -u root -psecret -e "SELECT * FROM testdb.users;"
# +------+-------+
# | id | name |
# +------+-------+
# | 1 | Alice |
# +------+-------+

# 정리
docker rm -f mysql-test2
docker volume rm mysql-data

🌐 Network (네트워크)

왜 필요한가?

컨테이너 간 통신, 외부 연결을 위해 필요함.

flowchart TB
subgraph Network["Docker Network"]
nginx["nginx<br/>:80"]
app["app<br/>:3000"]
mysql["mysql<br/>:3306"]

nginx <--> app
app <--> mysql
end

네트워크 드라이버

드라이버설명용도
bridge기본, 독립된 네트워크단일 호스트
host호스트 네트워크 직접 사용성능, 포트 매핑 불필요
none네트워크 없음격리된 컨테이너
overlay다중 호스트 연결Swarm, 클러스터
macvlan물리 네트워크에 직접 연결레거시 앱

Bridge 네트워크

기본 bridge (docker0)

# 기본 네트워크로 실행
docker run -d --name web nginx

# IP 확인
docker inspect web | grep IPAddress
# "IPAddress": "172.17.0.2"

# 다른 컨테이너에서 접근
docker run --rm alpine ping -c 3 172.17.0.2

⚠️ 기본 bridge에서는 컨테이너 이름으로 통신 불가.

사용자 정의 bridge (권장)

# 네트워크 생성
docker network create mynet

# 네트워크 목록
docker network ls

# 컨테이너 실행 (네트워크 지정)
docker run -d --name web --network mynet nginx
docker run -d --name app --network mynet alpine sleep 3600

# 컨테이너 이름으로 통신 가능!
docker exec app ping -c 3 web
# PING web (172.18.0.2): 56 data bytes
# 64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.089 ms

# 네트워크 상세
docker network inspect mynet

# 정리
docker rm -f web app
docker network rm mynet

사용자 정의 bridge 장점:

  • 컨테이너 이름으로 DNS 해석
  • 더 나은 격리
  • 실행 중 네트워크 연결/분리 가능

Host 네트워크

호스트의 네트워크를 직접 사용함.

docker run -d --network host nginx

# 포트 매핑 없이 호스트의 80 포트 사용
curl http://localhost:80

특징:

  • 포트 매핑 불필요 (-p 옵션 무시됨)
  • 네트워크 성능 좋음
  • 포트 충돌 주의
  • Linux에서만 완전 지원

None 네트워크

네트워크 완전 격리.

docker run -d --network none alpine sleep 3600

# 네트워크 없음
docker exec <container> ip addr
# lo만 존재

네트워크 명령어

# 네트워크 목록
docker network ls

# 네트워크 생성
docker network create mynet
docker network create --driver bridge --subnet 10.10.0.0/16 mynet

# 네트워크 상세
docker network inspect mynet

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

# 네트워크 연결 해제
docker network disconnect mynet container_name

# 네트워크 삭제
docker network rm mynet

# 미사용 네트워크 정리
docker network prune

실습: 3-Tier 네트워크

# 네트워크 생성
docker network create app-net

# MySQL (DB)
docker run -d \
--name db \
--network app-net \
-e MYSQL_ROOT_PASSWORD=secret \
-e MYSQL_DATABASE=appdb \
mysql:8.0

# App (Backend) - DB 연결
docker run -d \
--name app \
--network app-net \
-e DB_HOST=db \
-e DB_PORT=3306 \
node:18-alpine sleep 3600

# Nginx (Frontend)
docker run -d \
--name web \
--network app-net \
-p 8080:80 \
nginx

# 연결 테스트
docker exec app ping -c 2 db
docker exec app ping -c 2 web
docker exec web ping -c 2 app

# 정리
docker rm -f web app db
docker network rm app-net

🔌 포트 매핑

기본 문법

# -p 호스트포트:컨테이너포트
docker run -d -p 8080:80 nginx

# 여러 포트
docker run -d -p 8080:80 -p 8443:443 nginx

# 특정 IP
docker run -d -p 127.0.0.1:8080:80 nginx

# 랜덤 포트
docker run -d -p 80 nginx
docker port <container> # 할당된 포트 확인

# UDP
docker run -d -p 53:53/udp dns-server

포트 확인

# 컨테이너 포트 매핑 확인
docker port <container>

# 또는
docker ps
# PORTS: 0.0.0.0:8080->80/tcp

📋 Volume 명령어 요약

# 볼륨
docker volume create <n>
docker volume ls
docker volume inspect <n>
docker volume rm <n>
docker volume prune

# 컨테이너에 연결
-v <volume>:<path> # 볼륨
-v <host_path>:<path> # Bind mount
-v <volume>:<path>:ro # 읽기 전용
--mount source=<vol>,target=<path>

📋 Network 명령어 요약

# 네트워크
docker network create <n>
docker network ls
docker network inspect <n>
docker network rm <n>
docker network prune

# 연결
docker network connect <net> <container>
docker network disconnect <net> <container>

# 실행 시 지정
--network <n>
--network host
--network none

🔗 시리즈 네비게이션

이전다음
Dockerfile & Image BuildDocker Compose

시리즈 목차로 돌아가기


🔗 참고 자료