티스토리 뷰

Container & K8S & Automation/Docker

05. Docker 볼륨

승어리(Won) 2021. 3. 29. 17:13

도커 이미지로 컨테이너를 생성하면 이미지는 읽기 전용이 되며 컨테이너의 변경 사항만 별도로 저장해서 각 컨테이너의 정보를 보존한다. 

 

이미 생성된 이미지는 어떠한 경우로도 변경되지 않으며, 컨테이너 계층에 원래 이미지에서 변경된 파일시스템을 저장

 

mysql 컨테이너를 삭제하면 컨테이너 계층에 저장돼 있던 데이터베이스의 정보도 삭제

 

도커의 컨테이너는 생성과 삭제가 매우 쉬우며, 실수로 컨테이너를 삭제하면 데이터를 복구할 수 없게 됨

 

이를 방지하기 위해 컨테이너의 데이터를 영속적(Persistent) 데이터로 활용할 수 있는 방법이 몇가지 있다.

 

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

 

 

[볼륨 활용 방법]

1. 호스트와 볼륨 공유

 

2. 볼륨 컨테이너 생성

 

3. 도커가 관리하는 볼륨 생성

 

 

 

 

 

 

1. 호스트 볼륨 공유

 

 

 

 

- 먼저 mysql 데이터베이스 컨테이너워드프레스 웹 서버 컨테이너 생성

 

# docker run -d --name wordpressdb_hostvolume -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=wordpress -v /home/wordpress_db:/var/lib/mysql mysql:5.7

# docker run -d -e WORDPRESS_DB_PASSWORD=password --name wordpress_hostvolume --link wordpressdb_hostvolume:mysql -p 80 wordpress

- 워드프레스 컨테이너에 -p 옵션으로 컨테이너의 80 포트를 외부에 노출했으므로 docker ps 명령어에서 확인한 wordpress_hostvolume 컨테이너의 호스트 포트로 워드프레스 컨테이너에 접속할 수 있다.

 

 

- '-v' 옵션으로 [호스트의 공유 디렉토리]:[컨테이너의 공유 디렉토리] 형태로 디렉토리 공유

ex) -v /home/wordpress_db:/var/lib/mysql

     > 호스트의 /home/wordpress_db 디렉토리와 컨테이너의 /var/lib/mysql 디렉토리를 공유

 

cf> 컨테이너의 /var/lib/mysql 디렉토리는 MySQL이 데이터베이스의 데이터를 저장하는 기본 디렉토리

cf> 미리 호스트에 /home/wordpress_db 디렉토리를 호스트에 생성하지 않았어도 도커는 자동으로 이를 생성

 

 

 

- 생성한 두개의 컨테이너를 삭제하고 사용한 데이터가 그대로 남아 있는지 확인

# docker stop wordpressdb_hostvolume wordpress_hostvolume

# docker rm wordpressdb_hostvolume wordpress_hostvolume

 

 

- /home/wordpress_db 디렉토리를 확인하면 mysql 컨테이너가 사용한 데이터가 그대로 남아 있음

 

 

결론) -v 옵션을 써서 컨테이너의 디렉토리를 호스트와 공유한다는 것은,

[호스트의 공유 디렉토리] 와 [컨테이너의 공유 디렉토리]가 동기화되는 것이 아니라 완전히 같은 디렉토리다.

 

 

 

추가) 디렉토리 단위의 공유뿐 아니라 단일 파일 단위의 공유도 가능하며, 동시에 여러개의 -v 옵션을 쓸 수 있음

 

# echo hello >> /home/hello && echo hello2 >> /home/hello2

- 호스트에 파일 hello, hello2를 생성한다.

 

 

# docker run -i -t --name file_volume -v /home/hello:/hello \ -v /home/hello2:/hello2 \ ubuntu:14.04

# ls

# cat hello && cat hello2

- '-v' 옵션을 사용하여 호스트의 파일을 컨테이너와 공유

- 컨테이너에서 'hello' 와 'hello2' 파일을 수정하면 호스트에서도 변경

- 반대로 호스트에서 'hello' 와 'hello2'  파일을 수정하면 컨테이너에서도 변경

 

 

 

 

 

 

 

2. 볼륨 컨테이너

 

 

- '-v' 옵션으로 볼륨을 사용하는 컨테이너를 다른 컨테이너와 공유하는 것

- 컨테이너를 생성할 때 -volumes-from 옵션을 설정하면 -v 또는 --volume 옵션을 적용한 컨테이너의 볼륨 디렉토리를 공유할 수 있음

- 그러나 이는 직접 볼륨을 공유하는 것이 아닌 -v 옵션을 적용한 컨테이너를 통해 공유

 

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

- 이러한 구조를 활용하면 호스트와 연결되고 볼륨만 공유하며 별도의 역할을 담당하지 않는 '볼륨 컨테이너'로서 활용하는 것도 가능

 

결론) 볼륨을 사용하려는 컨테이너에 -v 옵션 대신 --volumes-from 옵션을 사용함으로써 볼륨 컨테이너에 연결해 데이터를 간접적으로 공유받는 방식

 

# docker run -i -t --name volumes_from_container --volumes-from 볼륨컨테이너명 ubuntu:14.04

 

 

 

 

 

 

3. 도커 볼륨

 

- 마지막으로, Docker volume 명령어 사용하는 방법

- 도커 자체에서 제공하는 볼륨 기능을 활용해 데이터를 보존할 수 있음

- docker volume create 명령어로 볼륨 생성

 

 

# docker volume create --name myvolume
# docker volume ls

 

 

# docker run -i -t --name myvolume_1 -v myvolume:/root/ ubuntu:14.04

- '-v' [볼륨의 이름]:[컨테이너의 공유 디렉토리]

 

 

 

 

# echo hello, volume! >> /root/volume

- 컨테이너 내부에서 /root/volume 파일 생성

 

 

 

 

# docker run -i -t --name myvolume_2 -v myvolume:/root/ ubuntu:14.04

# cat /root/volume

- 동일한 Docker 볼륨을 사용하는 컨테이너 생성

- 위에서 만든 volume 파일을 그대로 불러올 수 있다.

 

 

 

 

# docker inspect --type volume myvolume

- 볼륨은 디렉터리 하나에 상응하는 단위로서, 도커 엔진에서 관리

- 도커 볼륨도 호스트 볼륨 공유와 마찬가지로 호스트에 저장함

- docker inspect 명령어를 사용하면 myvolume 볼륨이 실제로 어디에 저장되는지 알 수 있음

- 정보를 확인할 종류를 명시하기 위해 --type 옵션에 image, volume 등을 입력하는 것이 좋음

 

 

# docker run -i -t --name volume_auto -v /root ubuntu:14.04

- 컨테이너에서 공유할 디렉터리의 위치를 -v 옵션에 입력하면 해당 디렉터리에 대한 볼륨을 자동으로 생성

 

 

 

# docker container inspect volume_auto | grep Name

- 자동으로 생성된 볼륨은 이름이 무작위의 16진수 형태로 생성됨

- docker container inspect 명령어로 해당 볼륨의 이름을 확인할 수 있음

 

 

 

 

 

# docker volume prune

- 현재 사용되지 않는 볼륨들이 많이 보임

- 사용하지 않는 볼륨들을 삭제하려면 docker volume prune 명령어로 삭제

 

 

 

결론) 

1. 스테이트리스(stateless) : 컨테이너가 아닌 외부에 데이터를 저장하고 컨테이너는 그 데이터로 동작하게 설계하는 것

2. 스테이트풀(stateful) : 컨테이너가 데이터를 저장하고 있음

 

>> 스테이트풀한 컨테이너 설계는 컨테이너 자체에서 데이터를 보관하므로 지양하는 것이 좋음