Docker 컨테이너 내부에 쓰인 데이터는 기본적으로 컨테이너가 삭제될 때 함께 사라진다. 따라서 Docker에서 수집한 데이터를 영속적으로 저장하기 위해서는 다른 방법이 필요하다. Docker 컨테이너의 생명 주기와 상관없이 데이터를 저장할 수 있도록 Docker는 두 가지 옵션을 제공한다. 첫 번째는 bind mount, 두 번째는 volume이다.
1. bind mount(바인드 마운트)
바인드 마운트는 호스트 시스템의 경로(파일 또는 폴더)가 컨테이너에 마운트 되는 형태이다. 경로가 존재하지 않으면 생성하여 마운트하고 호스트 시스템의 경로에 모두 접근할 수 있다. 사실 처음에 이 말만 들었을 때는 잘 이해가 안 됐는데 로컬에서 테스트해보니 이해가 되었다.
간단하게 코드를 통해 살펴보도록 하자.
data 폴더 내부 test.txt 텍스트 파일에 0부터 9까지 적는 코드이다. (main.py)
with open('./data/test.txt', 'a') as f:
for i in range(10):
f.write(str(i)+'\n')
이 코드를 Dockerfile을 정의해서 돌려보자.
FROM python:3.9
WORKDIR /app
COPY . /app
CMD ["python", "main.py"]
다음 명령어를 통해 docker 파일을 빌드하고 run 시킬 수 있다.
$ docker build . -t volume:test; docker run -d --name vol -p 8000:8080 volume:test
참고로 folder structure는 다음과 같다.
그냥 돌리면 아무 일도 일어나지 않는다. docker 내부에서는 data폴더 내부에 test.txt 파일이 생긴 후 데이터가 저장됐겠지만 코드가 종료되어 container 가 종료되는 순간 데이터도 같이 사라지게 된다.
이때 bind mount를 활용하여 로컬에 있는 data 폴더와 docker 내부에 있는 data 폴더를 마운트 시켜줄 수 있는 것이다!
🤔 bind mount 하는 방법
docker run 커맨드를 실행할 때, -v 옵션을 이용해 콜론 앞부분에 호스트의 경로를 지정해 주면 된다.
$ docker build . -t volume:test; docker run -v `pwd`/data/:/app/data/ -d --name vol -p 8000:8080 volume:test
즉, docker 가 실행됨에 따라 local에 있는 data 폴더 내부에 test.txt를 생성해서 그곳에 데이터를 저장한다. 즉 Host의 디렉터리에 직접 Access 한다. 사실 로컬에서 테스트할 때는 bind mount 로도 충분하다고 한다.
2. Volume
Volume의 경우 bind mount 보다 좀 더 좁은 범위의 마운트이며, 도커에 의해 관리되는 영역에 데이터가 저장된다.
위의 그림을 다시 가져와서 보면 bind mount의 경우 전체 Filesystem 이 컨테이너에 마운트 되는 형태였다면 volume의 경우 격리된 별도의 저장공간을 만든 후, 필요할 때 마운트 하는 형식이다.
Volume 방식이 Docker에서 더 권장하는 방식이다. 그럴 수밖에 없는 게 bind mount의 경우 사용자의 소유자와 권한 때문에 실행 및 수정에 문제가 있을 수 있어 보안에 취약하다. 위에서 보다시피 전체 File System에 접근하는 것만 봐도 그 이유를 알 수 있다.
그렇다면 이 Volume을 어떻게 생성하고 마운트 시키는지 알아보자.
볼륨 생성
$ docker volume create volume-test
볼륨 확인
$ docker volume ls
DRIVER VOLUME NAME
local volume-test
볼륨 마운트하기
$ docker build . -t volume:test; docker run -v volume-test:/app/data/ -d --name vol -p 8000:8080 volume:test
마운트 확인
$ docker inspect vol
"Mounts": [
{
"Type": "volume",
"Name": "volume-test",
"Source": "/var/lib/docker/volumes/volume-test/_data",
"Destination": "/app/data",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
]
/var/lib/docker/volumes/volume-test/_data에 source 가 잘 설정되어 있는 것을 볼 수 있다.
하지만 Mac에서 /var/lib/docker 내부로 들어가서 직접 확인하려고 하니
/var/lib/docker not found in mac 다음과 같은 에러가 발생했다. 이 부분에 대해선 다음에 다시 자세히 찾아보고 정리해 두도록 하겠습니다.
또한 볼륨의 경우 다른 컨테이너에서도 volume-test volume에 마운트가 가능하다. 따라서 데이터를 서로 공유할 수 있는 것이다.
볼륨 삭제
$ docker volume rm volume-test
오늘은 이전부터 계속 대충 개념만 알고 있던 docker의 마운트 개념에 대해서 학습해 보고 실습해 보았다. 확실히 실습을 해야 잘 와닿는 것 같다. 즉, 볼륨과 바인드 마운트의 공통점은 모두 지정한 위치에 파일을 생성할 수 있고, 공유할 수 있고, 수정할 수 있다는 것이다.
하지만 차이점이라고 한다면 볼륨으로 생성할 경우 Docker 가 관리하는 Directory 내에 생성이 된다는 것, 또한 바인드 마운트 같은 경우 파일 시스템에 직접 접근하기 때문에 보안상 문제가 있을 수 있다는 것, 따라서 간단한 로컬 테스트에서 사용하면 편하다는 것이다.
'Docker' 카테고리의 다른 글
[Docker] Volume 사용시 mac 에 /var/lib/docker 경로가 없는 이유 | LIM (0) | 2023.05.14 |
---|---|
[Python] 도커 파일에 Pipenv 로 패키지 설치하기 | LIM (0) | 2023.05.12 |
[Docker, GCP] docker push to artifact registry error 발생 및 해결 (0) | 2022.08.08 |
[Docker] 도커 내부에서 localhost 요청하기 | LIM (0) | 2022.07.19 |
댓글