본문 바로가기
프로그램 활용/클라우드 가상화 도커

Docker Volume 및 Docker 로 MySql 컨테이너 설정, 데이터 영구 저장

by 3604 2023. 8. 7.
728x90

출처: 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/ 

728x90