Docker - Volume, Bind mounts

Gon Kim·2022년 11월 3일
0
post-thumbnail

docker run -v flag가 있어서 신기해서 테스트해봤더니, 정말 반영되더라. 격리된 환경을 느슨하게 하는 일이 어떻게 발생하는 것일지 궁금해서 찾아봤다. 느낌상 file system을 건드리는 일이나 i/o 작업이 엮이는 것들은 잘 못 쓰면 난처해지는 일이 생기기 쉬울 것 같아서 쓰지 않을 것이더라도 미리 찾아본 감이 있다.

volume, bind mounts라는 기능들이 있다.

어떻게 쓰는건지는 알겠는데, volume 관리는 누가 어떻게 해주는지 알고 싶었다.

Container와 Host의 filesystem 공유

bind mounts

내가 위해서 처음 테스트 했던 방법은 bind mounts였다. host, container의 절대 경로를 넣었었다.

  • host의 file이나 directory를 container에 mount 시키는 것을 말한다.
  • host의 절대 경로를 참조하게 된다.
  • 당연히 host의 filesystem, directory 구조에 굉장히 의존적이다.
docker run -d --name test \
--mount type=bind,source=/Users/gon/it_doenst_exist,target=/usr/src/app/this_directory_doesnt_exist gonnnn/node-test:0.1\

docker: Error response from daemon: invalid mount config for type "bind": bind source path does not exist: /host_mnt/Users/gon/it_doenst_exist.
See 'docker run --help'.

대부분 volume을 쓰기를 권장하지만 다음과 같은 상황에 쓸 수 있다고 한다. (링크)

  • config file을 host에 두고, 여러 container가 공유하도록 하고 싶을 때
  • dev 환경에서 source code나 build 관련된 부분들을 공유하고자 할 때

volume

  • bind mounts와 같지만, host 컴퓨터의 docker storage directory(Ubuntu 기준 /var/lib/docker/)에 새로운 directory를 만들고 이를 사용하게 된다.
  • Docker가 자체적으로 관리하기에 filesystem 등에 의존적이지 않다.
  • 공식문서에서 말하는 volume을 썼을 때의 장점을 대문짝만하게 박아뒀다. 그럼에도 불구하고 bind mounts를 쓰는 경우가 있기는 하더라
    • back up/migrate하기도 쉽다.
    • CLI도 제공
    • 운영체제에 독립적
    • 여러 container가 공유하기에도 안전하다. docker가 관리하니까.
    • remote host나 cloud에도 저장할 수 있도록 한다. 암호화 등을 할 수 있어 안전

사용법

  • bind mounts나 volume 모두 -v flag나 —mount를 사용해 다룰 수 있다. -v
  • —mount는 -v를 펼쳐놓은 것 정도로 생각하면 된다.
  • —mount를 더 권장한다.
-v [A]:[B]:[op]
--mount key1=value1,key2=value2,key3=value3

-v

  • A에는 host의 주소/볼륨이름이 들어간다. bind mounts의 경우 주소, volume을 쓰는 경우 볼륨 이름을 넣는다.
  • op에는 readonly 등 mounting 관련 옵션이 들어간다.

—mount

  • key, value 형식으로 들어간다. 순서 무관
  • key에는 source, destination, option들이 있다. 이정도는 문서 참고하자
  • host에 경로가 존재하지 않으면 에러를 띄운다. 아래 예시에서 source에 들어가는 부분의 경로는 host에 존재하지 않는다. 그럼에도 불구하고 -v flag를 썼을 때는 host에 해당 디렉토리를 생성해버린다. 이런 이유에서라도 개인적으로 실수 방지를 위해 -v를 안쓸 것 같기는 하다.
docker run -d --name test \
--mount type=bind,source=/Users/gon/it_doenst_exist,\
target=/usr/src/app/this_directory_doesnt_exist \
gonnnn/node-test:0.1

docker: Error response from daemon: invalid mount config for type "bind": bind source path does not exist: /host_mnt/Users/gon/it_doenst_exist.
See 'docker run --help'.
docker run -d --name test \
-v /Users/gon/it_doenst_exist:/usr/src/app/this_directory_doesnt_exist \
gonnnn/node-test:0.1
8b384c49808c00b0a435499829daa96066a7372d1e5659ecb3b04935207db995

간단한 Test

  • volume을 만들고
docker run -d --name test -v test:/usr/src/app/volume_test gonnnn/node-test:0.1
docker inspect test

  • container 실행 후 volume 연결 확인
docker exec -it test sh

내 생각

  • container가 날아가도 유지되어야하는 데이터의 경우 writable layer에 쓰게 두면 안되니, 위 방법들을 사용해 저장해야한다. 로그, db가 대표적이겠다.
  • 반대로 공용으로 읽어들이면 좋을 파일들을 host에 둬도 좋겠다. config 관련된 것들
  • mount시키는 공간을 readonly로 두는 등, 다양한 옵션이 있다. 접근/저장해야하는 곳의 데이터가 어떤 데이터인지 생각해보고 이런 옵션을 두면 더 안전하게 관리할 수 있겠다.
  • 궁금해서 확인해봤는데, 당연히 어느정도 잊어버릴 것이다. 어떤게 존재하는지는 알았으니 필요할 때 또 문서들을 살펴보자
  • 여러 컨테이너가 저런 공통된 부분에 접근하는 경우 어떻게 관리하나? 문제 없나? Container는 process인가? 어떻게 관리되지?
    • 답부터 말하자면 container는 process이다. 다음 글에서 적어본다.
profile
응애

0개의 댓글