[ VOLUME 관리 ]
- Image : 읽기 (o)
- Container : 읽기/쓰기 (o)
- Volume : Container와 분리된 저장소
VOLUME 방식
[ VOLUME 방식 ]
- Docker에서 자체적으로 관리하는 Data 저장소
- 호스트 OS의 /var/lib/docker/volumes 아래에 자동으로 생성되며 Container에 Mount됨
- Container가 삭제되어도 Volume이 남아 있어서 Data 유지가 가능
- 지속성이 필요한 Data에 적합 (DB, 파일 스토리지, 이미지 업로드 등)
- Docker가 권한, 경로 등을 직접 관리해 줘서 운영환경에 매우 안정적
[ VOLUME 홈 디렉터리 ]
# cd /var/lib/docker/volumes
|

[ VOLUME 내부 구조 ]
# tree -L 4 /var/lib/docker/volumes

nginx Web 서버를 실행하면서, Docker 볼륨을 Web 콘텐츠 경로에 Mount 하고 8080 포트로 외부 접속 가능하게 설정했다. 이렇게 설정하면 아래와 같다.
- Container 이름 : DamiWeb
- Web페이지 저장 디렉터리 : testvol (Docker Volume 이름)
- 외부 접속 주소 : http://<서버 IP>:8080
volumes 하위 디렉터리에 'testvol' 이라는 Docker Volume이 생성되고 이 Volume은 Container가 삭제되더라도 Data는 유지되는 안전한 저장소가 된다.
# docker container run -d --name myWeb -v testvol:/usr/share/nginx/html -p 8080 nginx
BIND MOUNT 방식
[ BIND MOUNT 방식 ]
- 호스트 머신의 지정된 디렉터리를 Container 내부에 그대로 연결하는 방식
- 내가 직접 지정한 경로를 Container에 Mount 하는 구조
- 사용자가 직접 디렉터리 관리
- 실시간으로 파일 반영이 가능
- 로컬에서 수정 → Container 실시간 적용됨 (Web 개발에 적합)
- 호스트 OS에 의존적이므로 운영 환경에서는 적합 X
- 퍼미션, 경로 의존적
Nginx Web 서버를 Docker Container로 실행하면서, 호스트 디렉터리 Mount와 포트 연결까지 하는 방식이다. (호스트의 /www 디렉터리를 nginx 컨테이너의 Web 루트 디렉터리인 /usr/share/nginx/html에 Mount) 이렇게 설정하면 아래와 같다.
- Container 이름 : myWeb
- Container 내부 Web 루트 : /usr/share/nginx/html /usr/local/apache2/htdocs
- 호스트 디렉터리 /www에 HTML 파일을 넣으면 → 브라우저에서 볼 수 있음
- 접속 주소 : http://<서버 IP>:8080
# docker run -d --name myWeb1 -v /www:/usr/share/nginx/html -p 8080:80 nginx
http://192.168.10.100:8080 접속 가능
VOLUME 방식 & BIND MOUNT 방식
|
Volume 방식
|
Bind Mount 방식
|
저장 위치
|
Docker 내부 관리
|
호스트 경로 직접 지정
|
안전성
|
↑
|
↓
|
실시간성
|
↓
|
↑
|
삭제 영향
|
Container 삭제해도 유지
|
Container 삭제 시 연결만 끊김
|
사용 예
|
Container 삭제해도 유지
|
코드 반영, 설정 수정
|
VOLUME
[ VOLUME 생성 ]
# docker volume create [Volume명]
|
# docker volume create DamiV

생성된 Volume
[ VOLUME 삭제 ]
- 해당 Volume과 관련된 모든 Data와 기록이 완전히 삭제됨
# docker volume rm [Volume명]
|
# docker volume rm DamiV

삭제된 Volume
[ VOLUME 상세 정보 확인 ]
# docker volume instpect [Volume명]
|
# docker volume inspect mysql_vol

MYSQL - VOLUME
[ Volume 방식을 이용한 MYSQL Container Volume 구성 ]
Docker로 MySQL Database Server를 실행하고,
그 Server에 접속해서 직접 새로운 Database를 생성
MySQL 데이터베이스 서버를 Docker Container로 실행한다. (Docker로 MySQL 서버 Container 실행)
이렇게 하면 Container가 MySQL 서버처럼 작동한다.
# docker container run -d --name mydb -v mysql:/var/lib/mysql -p 3306:3306 \
> -e MYSQL_ROOT_PASSWORD=password mysql:5.7
- docker container run : 새 Container 실행
- -d : 백그라운드 모드
- --name mydb : Container 이름 = mydb
- -v mysql:/var/lib/mysql : Docker Volume mysql을 MySQL의 Data 디렉터리에 Mount
- -p 3306:3306 : 호스트의 3306포트를 Container의 3306 포트에 연결 (MySQL 기본 포트)
- -e MYSQL_ROOT_PASSWORD=password : root 사용자 비밀번호를 password로 설정
- mysql:5.7 : 사용할 Image (MySQL 5.7 버전)

\ = 줄바꿈 (띄어쓰기해야 함)
MySQL 진입 후 DB를 생성한다.
여기에 MySQL Data가 저장된다.
Container가 꺼져도 이 디렉터리는 남아 있어서 Data가 유지된다.
# mysql -h 192.168.10.100 -u root -p
> create database mydb;
mysql 이라는 Docker Volume이 생성되어 있다.
여기에 MySQL Data가 저장되고 유지된다.
# cd /var/lib/docker/volumes

mysql 안에 Data 저장됨
_data = Docker Volume의 핵심 경로!
진짜 Data는 _data 안에만 들어 있다.
mysql 관련 디렉터리가 두 개가 생성되어 있어서 Volume Data 저장 경로가 어디인지 확인해 봤다. mydb Container가 어디에 Mount 되어있는지 확인하면 실제 저장 경로를 알 수 있다.
# docker inspect mydb | grep -A 5 Mounts

정답은? mysql
APACHE - BIND MOUNT
[ Volume 방식을 이용한 APACHE Container Volume 구성 ]
Apache Web 서버 Container를 실행하고, Docker Volume을 연결해서 Web 페이지 파일을 만들어 출력 (Docker Volume 방식을 사용해서 Apache Web 서버 Container를 실행)
Apache를 Container로 실행시키고 Web 루트 경로에 'mywebvol' 이라는 Volume을 연결해 줬다.
# docker container run -d --name myweb -v mywebvol:/usr/local/apache2/htdocs -p 80:80 httpd
- docker container run : Container를 실행
- -d : 백그라운드 실행
- -name myweb : Container 이름 = myweb
- -v mywebvol:/usr/local/apache2/htdocs : mywebvol 이라는 Volume을 Apache의 Web 루트 디렉터리에 Mount
- -p 80:80 : 호스트의 80포트를 Container의 80포트에 연결 (Web 접속 가능)
- httpd : Apache Web 서버 Image 사용

출력할 Index 파일을 작성해 준다. (/var/lib/docker/volumes/mywebvol/_data/index.html) 이렇게 하면 실제로는 Container 안에 있는 /usr/local/apache2/htdocs/index.html 이 만들어지는 것과 같다.
# vi /var/lib/docker/volumes/mywebvol/_data/index.html

Server 주소로 접속한다.
Index 문구가 정상적으로 출력되는 것을 확인했다.

http:192.168.10.100:80
< echo로 실습 >
# docker run -d --name mynginx \
> -v /www:/usr/share/nginx/html \
> -p 8080:80 \
> nginx
# echo 'Docker Web Site Mount Test' > /www/index.html


http://192.168.10.100:8080
NFS - BIND MOUNT
[ NFS를 이용한 Web Server Volume 구성 ]

Docker2
|
NFS Server : Web 파일을 공유하는 Server
|
Docker3
|
NFS Client + NGINX(Web Server) : 공유된 파일로 Web Site 운영)
|
< Docker2 : NFS Server >
NFS 패키지 설치 후 공유할 디렉터리를 생성해 디렉터리 안에 Web 파일을 만든다.
# dnf -y install nfs*
# mkdir /webnfs
# vi /webnfs/index.html

모든 Client에게 webnfs 디렉터리 읽기/쓰기가 가능하도록 공유 설정 파일을 수정해 준다.
# vi /etc/exports

exports에 작성한 내용을 시스템에 즉시 적용해 주고 restart, firewalld stop
(exportfs -v로 확인해 줬다 = (Server 용) NFS 서버에서 공유 중인 디렉터리 목록 출력 명령어)
# exportfs -ra
# systemctl restart nfs*

<Docker3 : NFS Client>
마찬가지로 NFS 패키지 설치 후 Mount 용 디렉터리를 생성해 준다. 그다음에 NFS Mount! (IP는 NFS Server 입력) 계속 Mount에 실패해서 Docker2에서 두 가지 restart를 해줬다.
(showmoutn -e로 확인 = (Clinet 용) NFS로 공유 중인 디렉터리 목록 출력 명령어)
# dnf -y install nfs*
# mkdir /nfscli
# systemctl restart rpcbind (Docker2)
# systemctl restart nfs-server (Docker2)
# mount -t nfs 192.168.10.200:/webnfs /nfscli


정상적으로 Mount가 된 것을 확인했다.

NGINX Container에서 WEB 페이지로 제공하려면 nginx Web 루트 디렉터리 (/usr/share/nginx/html/) 에 NFS Mount 디렉터리를 연결해야 함
이제 Nginx Web 브라우저 접속으로 Container와 Mount 연동을 해본다.
Docker2/3 모두 restart docker를 해주고
# docker run -d --name NfsWeb -v /nfscli:/usr/share/nginx/html -p 8080:80 nginx

NFS Server에서 공유된 index.html이 Client nginx 홈페이지로 출력된 화면, NFS Server에 있는 파일이 Web 페이지로 출력된다.

http://192.168.10.250:8080