Docker & Kubernetes

도커 볼륨(Docker Volume) 활용하기

beekei 2022. 12. 27. 00:19
반응형

만약 도커로 데이터베이스 컨테이너를 실행해 애플리케이션을 구동한다 했을 때 해당 데이터베이스 컨테이너가 삭제된다면 데이터도 삭제가 되고 복구할 수 없게 된다.

이런 경우에 데이터를 유지를 위한 몇 가지 방법이 있는데 그중 가장 활용하기 쉬운 방법이 볼륨 활용이다.

 

볼륨을 활용하는 방법은 여러 가지가 있다.

1. 호스트 볼륨 공유

호스트 볼륨 공유는 호스트화 컨테이너의 볼륨을 공유하는 것이다.

만약 MySQL 컨테이너를 사용해 애플리케이션을 구동한다 했을 때 호스트와 MySQL에서 데이터를 저장하는 볼륨을 공유할 수 있다.

$ docker run -d \
--name mysql \ 
-e MYSQL_DATABASE=sample \
-e MYSQL_ROOT_PASSWORD=password \
-v /home/ec2-user/mysql:/var/lib/mysql \ 
mysql:5.7

위 예제는 -v 옵션을 사용해 MySQL 컨테이너 내 /var/lib/mysql 디렉터리를 호스트 내 /home/ec2-user/mysql 디렉터리에 공유하여 컨테이너를 실행시켰다. (/var/lib/mysql 디렉터리는 MySQL에서 데이터를 저장하는 기본 디렉터리)

호스트 볼륨 공유

이 경우 MySQL 컨테이너가 삭제되어도 공유된 볼륨은 그대로 유지된다.

호스트 내 디렉터리는 직접 생성하지 않아도 도커에서 자동으로 생성한다.

 

호스트 볼륨 공유에서 -v 옵션의 형식은 {호스트 공유 디렉터리}:{컨테이너의 공유 디렉터리}로 사용된다.

주의할 점은 디렉터리 공유 시 디렉터리 자체가 덮어써지기 때문에 호스트 내 디렉터리에만 있던 파일은 사라지게 된다.

디렉터리 단위의 공유 뿐 아니라 파일 단위에 공유도 가능하며, 동시에 여러 개의 -v 옵션을 사용할 수도 있다.


2. 볼륨 컨테이너 

컨테이너 볼륨은 호스트 볼륨 공유를 사용해 볼륨 컨테이너를 생성하고 다른 컨테이너와 볼륨을 공유하는 방법이다.

$ docker run -d -it -p 22:22 \
--name volume_container \ 
-v /home/ec2-user/volumes:/home/volume \
ubuntu:20.04

$ docker run -d -it -p 23:22 \
--name other_container \ 
--volumes-from volume_container \
ubuntu:20.04

위 예제는 --volumes-from 옵션을 사용해 호스트 내 디렉터리와 볼륨을 공유하는 volume_container를 생성하고 other_container에서 volume_container의 볼륨과 공유했다.

볼륨 컨테이너

여러 개의 컨테이너가 동일한 컨테이너에 --volumes-from 옵션을 사용함으로써 볼륨을 공유해 사용할 수도 있다.


3.  도커 볼륨

도커 볼륨은 docker volume 명령어를 사용해 도커 자체에서 제공하는 볼륨 기능을 활용하는 방법이다.

$ docker volume create --name myvolume
$ docker volume ls
DRIVER    VOLUME NAME
local     myvolume

 

위 예제는 docker volume create 명령어로 볼륨을 생성하고, docker volume ls 명령어로 생성된 볼륨을 확인했다.

볼륨을 생성할 때 플러그인 드라이버를 설정해 여러 종류의 스토리지 백엔드를 쓸 수 있지만 여기서는 기본적으로 제공되는 드라이버인 local을 사용한다.

이 볼륨은 localhost에 저장되며 도커 엔진에 의해 생성되고 삭제된다.

 

이제 다른 컨테이너와 생성한 볼륨을 공유해 사용하면 된다.

$ docker run -d -it -p 22:22 \
--name other_container1 \ 
-v myvolume:/root \
ubuntu:20.04

$ docker run -d -it -p 23:22 \
--name other_container2 \ 
-v myvolume:/root \
ubuntu:20.04

위 예시에서 생성된 볼륨을 컨테이너 내 /root 디렉터리에 마운트 한다.

도커 볼륨

도커 볼륨에서 -v 옵션의 형식은 {볼륨의 이름}:{컨테이너의 공유 디렉터리}로 사용된다.

 

볼륨은 디렉터리 하나에 상응하는 단위로써 도커 엔진에서 관리한다.

사용자 입장에서는 딱히 알 필요는 없지만 docker volume inspect 명령어를 사용하면 myvolume 볼륨이 실제로 어디에 저장되는지 알 수 있다.

$ docker volume inspect myvolume
[
    {
        "CreatedAt": "2022-12-26T14:41:25Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/myvolume/_data",
        "Name": "myvolume",
        "Options": {},
        "Scope": "local"
    }
]

Driver는 볼륨이 사용하는 드라이버를, Label은 볼륨을 구분하는 라벨을 나타내며, Monthpoint는 해당 볼륨이 실제로 저장되는 호스트 디렉터리를 보여준다.

 

3-1. 볼륨 자동 생성

docker volume create 명령어를 별도로 실행하지 않아도 -v옵션을 입력할 때 자동으로 볼륨을 생성할 수 있다.

$ docker run -d -it \
--name other_container \ 
-v /root \
ubuntu:20.04

$ docker volume ls
DRIVER    VOLUME NAME
local     7787c85e050fcede9d7f1ee78bbf81c8898d17714273cf667954b12949808ee5
local     myvolume

other_container의 볼륨으로 16진수 형태의 이름을 가진 볼륨이 생성된 것을 확인할 수 있다.

docker container inspect 명령어를 사용해 컨테이너가 어떤 볼륨을 사용하는지 확인할 수 있다.

$ docker container inspect other_container

...
"Mounts": [
    {
        "Type": "volume",
        "Name": "7787c85e050fcede9d7f1ee78bbf81c8898d17714273cf667954b12949808ee5",
        "Source": "/var/lib/docker/volumes/7787c85e050fcede9d7f1ee78bbf81c8898d17714273cf667954b12949808ee5/_data",
		...
    }
],      
...

Mounts 내의 Source 항목에 정의된 디렉터리에 볼륨을 공유하는 것을 확인할 수 있다.

 

3-2. 사용하지 않는 볼륨 삭제

도커 볼륨을 사용하고 있는 컨테이너를 삭제해도 볼륨은 삭제되지 않기 때문에 사용하지 않는 불필요한 볼륨들이 남아있을 때가 있다.

이런 경우 docker volume prune 명령어를 사용해 사용하지 않는 볼륨을 한꺼번에 삭제할 수 있다.

$ docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
myvolume

Total reclaimed space: 22.53B

지금까지 볼륨을 활용하는 3가지 방법을 정리해 보았다.

컨테이너가 아닌 외부에 데이터를 저장하고 컨테이너는 그 데이터로 동작하도록 설계하는 것을 stateless, 반대로 컨테이너가 데이터를 저장하고 있어 상태가 있는 경우 stateful 하다고 말할 수 있다.

stateful 한 컨테이너 설계는 컨테이너 자체에서 데이터를 보관하므로 지양하는 것이 좋다.

 

반응형