docker run -v flag가 있어서 신기해서 테스트해봤더니, 정말 반영되더라. 격리된 환경을 느슨하게 하는 일이 어떻게 발생하는 것일지 궁금해서 찾아봤다. 느낌상 file system을 건드리는 일이나 i/o 작업이 엮이는 것들은 잘 못 쓰면 난처해지는 일이 생기기 쉬울 것 같아서 쓰지 않을 것이더라도 미리 찾아본 감이 있다.
volume, bind mounts라는 기능들이 있다.
어떻게 쓰는건지는 알겠는데, volume 관리는 누가 어떻게 해주는지 알고 싶었다.
Container와 Host의 filesystem 공유
![](https://velog.velcdn.com/images/gonnnnn/post/eedeba4a-7c4e-4d02-a793-2106f4ee320c/image.png)
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
![](https://velog.velcdn.com/images/gonnnnn/post/ced30792-6adc-4715-8d50-94e0270512bc/image.png)
간단한 Test
![](https://velog.velcdn.com/images/gonnnnn/post/c8a6c257-e4d8-40c5-8811-1847a857f9f2/image.png)
docker run -d --name test -v test:/usr/src/app/volume_test gonnnn/node-test:0.1
docker inspect test
![](https://velog.velcdn.com/images/gonnnnn/post/c3106078-6526-44d6-b2e6-163991d12e5b/image.png)
- container 실행 후 volume 연결 확인
docker exec -it test sh
![](https://velog.velcdn.com/images/gonnnnn/post/3f87c7c2-cdb0-4ad8-bc81-41638d178436/image.png)
내 생각
- container가 날아가도 유지되어야하는 데이터의 경우 writable layer에 쓰게 두면 안되니, 위 방법들을 사용해 저장해야한다. 로그, db가 대표적이겠다.
- 반대로 공용으로 읽어들이면 좋을 파일들을 host에 둬도 좋겠다. config 관련된 것들
- mount시키는 공간을 readonly로 두는 등, 다양한 옵션이 있다. 접근/저장해야하는 곳의 데이터가 어떤 데이터인지 생각해보고 이런 옵션을 두면 더 안전하게 관리할 수 있겠다.
- 궁금해서 확인해봤는데, 당연히 어느정도 잊어버릴 것이다. 어떤게 존재하는지는 알았으니 필요할 때 또 문서들을 살펴보자
- 여러 컨테이너가 저런 공통된 부분에 접근하는 경우 어떻게 관리하나? 문제 없나? Container는 process인가? 어떻게 관리되지?
- 답부터 말하자면 container는 process이다. 다음 글에서 적어본다.