출처: https://rondeveloper.tistory.com/92
1. 들어가며
이번 게시글에서는 Docker Volume 에 대한 이해 및 MySql 을 Docker 컨테이너로 세팅하고 데이터베이스 데이터를 영구적으로 저장하는 방법을 알아보고자 합니다.
2. Docker Volume
Docker 컨테이너에 저장되는 데이터는 기본적으로 Docker 컨테이너가 삭제될 때 함께 사라집니다.
그러나 MySql 컨테이너와 같이 DB를 구동하는 컨테이너에서는 Docker 컨테이너의 생성, 삭제 여부에 관계없이 데이터를 영속적으로 저장해야 합니다.
이렇게 Docker 컨테이너의 생성, 삭제 여부와 관계없이 데이터를 영속적으로 저장할 수 있도록 Docker는 두가지 옵션을 제공합니다. 그 중 하나가 바로 Docker Volume 입니다.
Docker Volume 과 관련된 명령어는 다음과 같습니다.
2.1. volume 생성
$ docker volume create [volume 이름]
$ docker volume create testdb-volume
2.2. volume 조회
$ docker volume ls
2.3. volume 상세정보 보기
$ docker volume inspect [volume name]
$ docker volume inspect testdb-volume
2.4. volume 삭제
$ docker volume rm [volume name]
$ docker volume rm testdb-volume
3. Docker Volume 암시적 생성 및 제거
MySQL:latest image 의 Dockerfile 을 보면 다음과 같습니다.
# ...
VOLUME [/var/lib/mysql]
# ...
이는 해당 Docker image 가 실행될 때, 컨테이너 내의 /var/lib/mysql 디렉터리가 호스트 PC의 /var/lib/docker/volumes/${volume_name}/_data에 마운트된다는 의미입니다.
(volume 이름은 임의의 해쉬값으로 생성됩니다.)
mysql:latest 를 실행해 봅니다.
$ docker run --name testdb -e MYSQL_ROOT_PASSWORD=ron -d mysql
이렇게 하면, docker는 /var/lib/mysql 디렉토리를 외부 volume 을 사용해 마운트합니다.
다음 명령어로 실행된 docker 컨테이너에 마운트된 volume을 확인할 수 있습니다.
$ docker inspect testdb
출력된 결과를 보면, docker host 내 /var/lib/docker/volumes/fadc9f58e88133d456c5d7373a81aab77a7d82cc128cdfc0694bdd9485a3800f/_data 디렉토리가 있고, 이 경로의 내용이 /var/lib/mysql로 마운트되어 있음을 알 수 있습니다.
다음 명령을 실행하면 현재 docker host에 있는 volume 목록을 확인할 수 있습니다.
$ docker volume ls
출력된 volume 목록을 보면 해시값으로 volume 이름이 생성되어 있고, fadc9f58... 으로 시작하는 volume이 local 드라이버를 사용해 만들어져 있음을 알 수 있습니다.
mysql 컨테이너가 마운트하고 있는 volume 에 기록을 남기기 위해 다음과 같이 testdb 라는 이름을 가진 데이터베이스를 만들어보겠습니다.
# mysql 클라이언트 접속
$ docker exec -it testdb mysql --password=ron
# testdb 데이터베이스 생성
$ create database testdb;
# mysql 클라이언트 빠져나오기
$ exit;
이제 testdb 컨테이너에는 testdb 라는 이름의 database 가 만들어졌습니다.
testdb 컨테이너 가동을 멈추고 다시 시작해보겠습니다.
# testdb 컨테이너 가동 중단
$ docker container stop testdb
# testdb 컨테이너 시작
$ docker container start testdb
# testdb 데이터베이스가 존재하는지 확인하기 위해 mysql 클라이언트 접속
$ docker exec -it testdb mysql --password=ron
# database 목록 확인
$ show databases;
# database 목록 확인 후 mysql 클라이언트 빠져 나오기
$ exit;
확인 결과 여전히 testdb database 가 남아있습니다.
그렇다면 아예 컨테이너를 삭제 후 다시 만들면 어떻게 될까?
# testdb 컨테이너 가동 중단
$ docker container stop testdb
# testdb 컨테이너 삭제
$ docker container rm testdb
# testdb 컨테이너 생성 및 시작
$ docker run --name testdb -e MYSQL_ROOT_PASSWORD=ron -d mysql
# testdb 컨테이너 상세정보 확인
$ docker inspect testdb
# docker volume 목록 확인
$ docker volume ls
testdb 컨테이너 상세정보 확인 결과는 다음과 같습니다.
처음에 만들었던 컨테이너의 volume 이름은 fadc9f58... 이었는데, 방금 만들어진 컨테이너의 volume 이름은 6ca7aea8e... 으로 바뀌었음을 알 수 있습니다.
docker volume 목록 확인 결과는 다음과 같습니다.
앞서 만들어졌던 volume 과 방금 만들어진 volume 이 전부 존재합니다.
그렇다면 처음에 만들었던 컨테이너에 존재하는 testdb 가 방금 만들어진 컨테이너에 존재할까요? 한번 확인해보겠습니다.
# testdb 데이터베이스가 존재하는지 확인하기 위해 mysql 클라이언트 접속
$ docker exec -it testdb mysql --password=ron
# database 목록 확인
$ show databases;
# database 목록 확인 후 mysql 클라이언트 빠져 나오기
$ exit;
testdb 라는 이름의 db 가 존재하지 않습니다.
이렇게 docker 가 암시적으로 만든 volume은 docker 컨테이너가 docker stop 되고 docker rm, 즉 제거될 때 함께 제거됩니다. 따라서 새로운 docker 컨테이너 생성 시 새로운 volume 이 생성됩니다.
4. Docker Volume의 명시적 생성
docker 컨테이너의 생성, 삭제 여부에 상관없이 데이터를 영속적으로 저장하기 위해서는 컨테이너 생성 시 명시적으로 volume 을 만들어 사용합니다. 이렇게 생성된 volume은 컨테이너가 제거된 다음에도 계속 남아 있습니다.
다음 명령을 실행해 명시적으로 volume 을 생성할 수 있습니다.
# testdb-volume 이름을 가진 volume 생성(명시적 volume 생성)
$ docker volume create testdb-volume
# volume 목록 확인
$ docker volume ls
이렇게 생성된 명시적 volume은 다음 명령을 실행해 docker image에 정의된 volume의 마운트 디렉토리에 연결할 수 있습니다.
$ docker run --rm -d --name testdb -e MYSQL_ROOT_PASSWORD=ron -v testdb-volume:/var/lib/mysql mysql
--rm 옵션 : 컨테이너 가동을 멈출 때 제거하겠다는 의미입니다.
-v 옵션 : 명시적으로 만든 volume을 /var/lib/mysql 의 경로에 매핑하도록 했습니다.
혹시 컨테이너가 제거되더라도 이 volume 은 docker host 내에 유지됩니다.
# mysql 클라이언트 접속
$ docker exec -it testdb mysql --password=ron
# testdb 데이터베이스 생성
$ create database testdb;
# mysql 클라이언트 빠져나오기
$ exit;
이 testdb 컨테이너를 중지하면, 완전히 --rm 옵션으로 인해 컨테이너가 삭제되지만, volume은 여전히 남아있음을 알 수 있습니다.
# testdb 컨테이너 가동 중지
$ docker stop testdb
# 컨테이너 목록 확인
$ docker container ls --all
# Volume 목록 확인
$ docker volume ls
이제 testdb 컨테이너를 다시 만들어보고 이전에 삭제된 컨테이너에서 생성한 testdb 데이터베이스가 존재하는지 확인해보겠습니다.
# testdb 컨테이너 생성
$ docker run --rm -d --name testdb -e MYSQL_ROOT_PASSWORD=ron -v testdb-volume:/var/lib/mysql mysql
# mysql 클라이언트 접속
$ docker exec -it testdb mysql --password=ron
# 데이터베이스 목록 확인
$ show databases;
# mysql 클라이언트 빠져 나오기
$ exit
testdb-volume에 저장되어 있던 testdb 라는 데이터베이스는 여전히 존재함을 알 수 있습니다
5. 결론
docker 컨테이너의 생성, 삭제 여부에 상관없이 데이터를 영속적으로 저장하기 위해서는 컨테이너 생성 시 명시적으로 volume 을 만들어 사용해야 합니다. 이렇게 생성된 volume은 컨테이너가 제거된 다음에도 계속 남아 있습니다.
6. 출처
https://joont92.github.io/docker/volume-container-%EC%B6%94%EA%B0%80%ED%95%98%EA%B8%B0/
'프로그램 활용 > 클라우드 가상화 도커' 카테고리의 다른 글
쿠버네티스 도커 단일 인스턴스 스테이트풀 애플리케이션 실행하기 (0) | 2023.08.08 |
---|---|
DBeaver(디비버) Public Key Retrieval is not allowed 에러 (0) | 2023.08.07 |
Mysql Container Volume 통해 Docker Volume을 이해 해보자 (0) | 2023.08.07 |
MYSQL 도커 사용시) ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2) (0) | 2023.08.07 |
Docker Error: “Can’t Connect to Local MySQL Server Through Socket” (0) | 2023.08.07 |