본문 바로가기
Docker

[Docker] 04. 도커 볼륨

by 별준 2021. 7. 12.

Contents

  • 호스트 볼륨 공유
  • 볼륨 컨테이너
  • 도커 볼륨
  • 볼륨 삭제

도커 이미지로 컨테이너를 생성하면 이미지는 읽기 전용으로 읽으며, 컨테이너의 변경 사항만을 별도로 저장하여 각 컨테이너의 정보를 보존합니다.

이미 생성된 이미지는 어떠한 경우에도 변경되지 않으며, 컨테이너 레이어에 원래 이미지에서 변경된 파일시스템 등을 저장합니다.

예를 들어(mysql + wordpress), 이미지에 mysql을 실행하는데 필요한 어플리케이션 파일이 들어있다면, 컨테이너 레이어에는 워드프레스에서 쓴 로그인 정보나 게시글 등과 같은 데이터베이스를 운영하면서 쌓이는 데이터가 저장됩니다.

 

여기에는 치명적인 단점이 존재하는데, mqsql 컨테이너를 삭제하면 컨테이너 레이어에 저장되어 있던 데이터베이스의 정보도 삭제된다는 것입니다.

도커의 컨테이너는 생성과 삭제가 매우 쉽기 때문에 실수로 컨테이너를 삭제하면 데이터를 복구할 수 없습니다.

이를 방지하기 위해 컨테이너의 데이터를 영구적인 데이터로 활용할 수 있는 방법이 몇 가지 존재합니다.

그 중에 가장 활용하기 쉬운 방법이 볼륨(Volume)을 활용하는 것 입니다.

 

볼륨을 활용하는 방법은 여러가지가 있는데, 호스트와 볼륨을 공유할 수도 있고, 볼륨 컨테이너를 활용할 수도 있으며, 도커가 관리하는 볼륨을 생성할 수도 있습니다.

 

1. 호스트 볼륨 공유


다음 커맨드를 통해서 mysql 데이터베이스 컨테이너와 워드프레스 웹 서버 컨테이너를 생성해봅시다.

# MySQL 컨테이너 생성
docker run -d --name wp-db \
    -e MYSQL_ROOT_PASSWORD=root_password \
    -e MYSQL_USER=user-mysql \
    -e MYSQL_PASSWORD=mysql_password \
    -e MYSQL_DATABASE=wp \
    -v /home/wordpress_db:/var/lib/mysql \
    mysql:5.7
 
# Wordpress Web Server 컨테이너 생성
docker run -d --name wp \
    -e WORDPRESS_DB_HOST=wp-db \
    -e WORDPRESS_DB_USER=user-mysql \
    -e WORDPRESS_DB_PASSWORD=mysql_password \
    -e WORDPRESS_DB_NAME=wp \
    --link wp-db:mysql \
    -p 8000:80 \
    wordpress

워드프레스 컨테이너에 -p 옵션으로 컨테이너의 80번 포트를 외부에 노출할 수 있도록 호스트의 8000번 포트를 바인딩하였습니다. 따라서, 외부에서 [Host의 IP]:[8000]으로 워드프레스 컨테이너에 접속할 수 있게 됩니다.

 

그리고, 호스트의 볼륨을 사용하기 위해서 -v 옵션을 추가했고, 그 값을 /home/wordpress_db:/var/lib/mysql로 설정했습니다.

이것은 호스트의 /home/wordpress_db 디렉토리와 컨테이너의 /var/lib/mysql 디렉토리를 공유하겠다는 의미입니다.

([호스트의 디렉토리]:[컨테이너의 디렉토리]의 형식으로 값을 적용합니다.)

만약 /home/wordpress_db 디렉토리가 없다면, 도커에서 자동으로 이 디렉토리를 생성합니다.

 

아래처럼 실제 해당 디렉토리에 데이터베이스 관련 파일이 생성된 것을 확인할 수 있으며, 이는 mysql을 구동하는데 필요한 각종 파일이며, 실제 데이터베이스에 대응됩니다.

 

이제 컨테이너를 삭제해 데이터베이스의 데이터가 보존되는지 확인해봅시다.

docker stop wp wp-db
docker rm wp wp-db
ls /home/wordpress_db

mysql 컨테이너가 사용한 데이터가 그대로 남은 것을 확인할 수 있습니다.

(ibtmp1 이라는 파일은 삭제되었습니다.. (?))

 

정리해보면, 위 경우에는 호스트에 /home/wordpress_db 디렉토리가 존재하지 않았고, -v 옵션으로 인해 호스트에 /home/wordpress_db 디렉토리가 생성되면서, 이 디렉토리가 공유된 것입니다.

즉, 컨테이너의 파일이 호스트로 복사된 것이라고 생각하면 될 것 같습니다.

 

-v 옵션으로 컨테이너의 디렉토리를 호스트와 공유한 것을 표현하면 다음과 같습니다.

컨테이너의 디렉토리가 호스트의 디렉토리와 동기화되는 것이 아니라 완전히 같은 디렉토리로 취급된다는 점에 유의해야합니다.

 

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

+) 호스트에 이미 디렉토리와 파일이 존재하고 컨테이너에도 파일이 존재할 때, 두 디렉토리를 공유하게 된다면 컨테이너의 디렉토리 자체가 덮어씌여집니다. (호스트의 파일이 삭제됨)

 

2. 볼륨 컨테이너


볼륨을 사용하는 두 번째 방법은 -v 옵션으로 볼륨을 사용하는 컨테이너를 다른 컨테이너와 공유하는 것입니다.

컨테이너를 생성할 때 --volumes-from 옵션을 설정하면 -v나 --volume 옵션을 적용한 컨테이너의 볼륨 디렉토리를 공유할 수 있습니다.(직접 공유하는 것이 아닌 -v 옵션을 적용한 컨테이너를 통해 공유하는 것입니다.)

 

아래의 커맨드로 ubuntu 20.04 컨테이너를 생성하면, 생성된 컨테이너는 1에서 생성한 wp-db 컨테이너의 볼륨을 공유합니다.

docker run -i -t \
    --name volumes_from_container \
    --volumes-from wp-db \
    ubuntu:20.04

'ls /var/lib/mysql' 커맨드를 입력해보면, wp-db에 존재하는 디렉토리가 공유된 것을 확인할 수 있습니다.

--volumes-from 옵션을 적용한 컨테이너와 볼륨 컨테이너 사이의 관계를 나타내면 다음과 같이 나타낼 수 있습니다.

여러 개의 컨테이너가 동일한 컨테이너 --volumes-from 옵션을 사용하여 볼륨을 공유할 수도 있습니다.

이러한 구조를 활용하면 호스트에서 볼륨만 공유하고 별도의 역할을 담담하지 않는 '볼륨 컨테이너'로서 활용하는 것이 가능합니다.

(ex, wp-db의 볼륨을 공유받는 volumes_from_container2 등의 컨테이너 생성)

 

3. 도커 볼륨


볼륨을 활용하는 세 번째 방법은 docker volume 커맨드를 사용하는 것입니다. 즉, 도커 자체에서 제공하는 볼륨 기능을 사용합니다.

# 도커 볼륨 생성
docker volume create --name myvolume
# 생성된 볼륨 확인
docker volume ls

wp로 인해서 생성된 볼륨과 방금 생성한 myvolume이라는 이름을 가진 볼륨을 확인할 수 있습니다.

 

생성된 볼륨을 공유하려면 -v 옵션을 다음과 같은 형식으로 입력해야 합니다.

-v [볼륨의 이름]:[컨테이너의 공유 디렉토리]
docker run -i -t --name myvolume_1 \
	-v myvolume:/root/ \
    ubuntu:20.04

/root/ 디렉토리를 myvolume이라는 볼륨과 공유하는 우분투 컨테이너를 생성하고, 아래 커맨드를 입력하여 /root 디렉토리에 volume이라는 파일을 생성해봅시다.

echo hello, volume! >> /root/volume

 

그리고, myvolume 볼륨을 사용하는 또 다른 컨테이너를 생성해봅시다. 동일한 볼륨을 사용하기 때문에, 이 컨테이너에도 volume이라는 파일이 존재할 것입니다. exit로 컨테이너를 빠져나와서 새로운 컨테이너를 생성하여 확인합니다.

docker run -i -t --name myvolume_2 \
    -v myvolume:/root/ \
    ubuntu:20.04

같은 파일인 volume이 새롭게 생성한 컨테이너에서도 존재하는 것을 확인할 수 있습니다.

 

docker volume 커맨드로 생성한 볼륨은 아래와 같은 구조로 활용됩니다. 이러한 도커 볼륨도 여러 개의 컨테이너에 공유되어 활용될 수 있습니다.

도커 볼륨도 호스트 볼륨 공유와 마찬가지로 호스트에 저장하여 데이터를 보존하지만, 파일이 실제로 어디에 저장되는지 사용자는 알 필요가 없습니다.

docker inspect 커맨드를 사용하면 myvolume이 실제로 어디에 저장되어 있는지 알 수는 있습니다. --type 옵션으로 확인할 정보의 종류를 명시하는데, 사용하지 않아도 됩니다. (docker volume inspect myvolume으로도 확인 가능)

docker inspect --type volume myvolume

  • Driver : 볼륨이 사용하는 드라이버
  • Label : 볼륨을 구분하는 라벨(메타데이터)
  • Mountpoint : 해당 볼륨이 실제로 저장된 장소

실제 저장된 디렉토리를 살펴보면, 컨테이너에서 사용했던 파일이 남아있는 것을 확인할 수 있습니다.

 

+) docker volume create 커맨드를 별도로 사용하지 않아도 -v 옵션을 사용할 때 자동으로 볼륨이 생성되도록 할 수도 있습니다.

docker run -i -t --name volume-auto \
	-v /root \
    ubuntu:20.04

무작위의 16진수의 이름을 가진 볼륨이 자동으로 생성된 것을 확인할 수 있습니다.(2d58d17146...)

 

생성된 volume-auto 컨테이너가 위의 2d58d17146.. 볼륨을 사용하는지 확인하는 방법은 docker container inspect 커맨드를 사용하면 됩니다.

docker container inspect volume-auto

"Mounts" - "Source"에 해당 볼륨이 마운트되어 있다는 것을 확인할 수 있습니다.

 

4. 볼륨 삭제


도커 볼륨을 생성하고 삭제하다 보면 불필요한 볼륨들이 남아있을 때가 많습니다. 도커 볼륨을 사용하고 있는 컨테이너를 삭제해도 볼륨은 자동으로 삭제되지 않기 때문입니다.

사용되지 않는 볼륨을 한꺼번에 삭제하려면 docker volume prune 커맨드를 사용하면 됩니다.(사용 중인 볼륨은 삭제되지 않습니다.)

특정 볼륨을 삭제하려면 docker volume rm 커맨드를 사용하면 됩니다.

 

다음 커맨드는 생성된 모든 컨테이너를 삭제하고, 모든 볼륨을 삭제하는 커맨드입니다.

docker rm -f $(docker ps -a -q)
docker volume prune

 

'Docker' 카테고리의 다른 글

[Docker] 06. 컨테이너 로깅(logging)  (0) 2021.07.13
[Docker] 05. 도커 네트워크  (0) 2021.07.13
[Docker] 03. 도커 컨테이너  (0) 2021.07.11
[Docker] 02. 도커 엔진 설치  (0) 2021.07.11
[Docker] 01. 도커(Docker)란  (3) 2021.07.11

댓글