[Docker] Volume & Bind Mount

GreenBean·2022년 1월 17일
0
post-thumbnail

Volume & Bind Mount

  • Docker 컨테이너(Container)에 쓰여진 데이터는 기본적으로 컨테이너가 삭제될 때 함께 사라지게 됨
    • 하지만 Docker에서 돌아가는 많은 애플리케이션은 컨테이너의 생명 주기와 관계없이 데이터를 영속적으로 저장을 해야함
    • 뿐만 아니라 많은 경우 여러 개의 Docker 컨테이너가 하나의 저장 공간을 공유해서 데이터를 읽거나 써야함
  • 이렇게 Docker 컨테이너의 생명 주기와 관계없이 데이터를 영속적으로 저장할 수 있도록 Docker는 두가지 옵션을 제공
    • 첫번째는 볼륨(Volume)
    • 두번째는 바인드 마운트(Bind Mount)

볼륨

볼륨 생성 및 조회

  • Docker에서 권장하는 방법인 볼륨(volume)
    • docker volume create 커맨드를 이용해서 볼륨 생성
    • 그 다음 docker volume ls 커맨드를 실행하면 생성한 볼륨을 확인할 수 있음
    • docker volume inspect 커맨드를 통해 해당 볼륨을 좀 더 상세한 정보를 확인해볼 수 있음
      • Mountpoint 항목을 보면 해당 볼륨이 컴퓨터의 어느 경로에 생성되었는지를 알 수 있음
$ docker volume create our-vol
our-vol

$ docker volume ls
DRIVER              VOLUME NAME
local               our-vol

$ docker volume inspect our-vol
[
    {
        "CreatedAt": "2020-05-09T17:03:46Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/our-vol/_data",
        "Name": "our-vol",
        "Options": {},
        "Scope": "local"
    }
]

볼륨을 컨테이너에 마운트하기

  • 컨테이너가 볼륨을 사용하기 위해서는 볼륨을 컨테이너에 마운트(mount)해줘야 함
    • docker run 커맨드로 컨테이너를 실행할 때 -v 옵션을 사용하면 되는데 콜론(:)을 구분자로 해서 앞에는 마운트할 볼륨명 뒤에는 컨테이너 내의 경로를 명시해주면 됨
      • 예를 들어, our-vol 볼륨을 one 컨테이너의 /app 경로에 마운트를 할 수 있음
      • touch /app/test.txt 커맨드를 실행하면 test.txt 파일이 our-vol 볼륨의 경로에도 남아있을 것
      • docker inspect 커맨드로 컨테이너의 상세 정보를 확인해보면 our-vol 볼륨이 volume 타입으로 마운트되어 있는 것을 확인할 수 있음
$ docker run -v our-vol:/app --name one busybox touch /app/test.txt

$ ls /var/lib/docker/volumes/our-vol/_data
test.txt

$ docker inspect one
(...생략...)
    "Mounts": [
        {
            "Type": "volume",
            "Name": "our-vol",
            "Source": "/var/lib/docker/volumes/our-vol/_data",
            "Destination": "/app",
            "Driver": "local",
            "Mode": "z",
            "RW": true,
            "Propagation": ""
        }
    ],
(...생략...)

볼륨을 다른 컨테이너에도 마운트하기

  • 같은 our-vol 볼륨을 two 컨테이너의 /app 경로에 마운트를 할 수 있음
  • ls /app 커맨드를 실행해보면 one 컨테이너가 볼륨에 생성해놓은 파일이 그대로 보이는 것을 알 수 있음
$ docker run -v our-vol:/app --name two busybox ls /app
test.txt
  • 이렇게 여러 개의 컨테이너가 하나의 볼륨에 접근할 수 있기 때문에 컨테이너 간 데이터 공유가 가능
  • 다시 말해, 어떤 볼륨에 데이터를 저장해두고 여러 컨테이너에 마운트만 해주면 해당 데이터를 모든 컨테이너에서 접근할 수 있게 됨

볼륨 삭제

  • docker volume rm 커맨드를 사용해서 our-vol 볼륨 제거 가능
$ docker volume rm our-vol
Error response from daemon: remove our-vol: volume is in use - [f73130c9dad14644ac46b89fe4018e561a7bcbfa4118d637949642d0d5d742e4, 666dda54f6be8ca852f3150b9741a9cab5a4659fa2e83fe6ca339550072c861ex]
  • 위와 같이 제거하려는 볼륨이 마운트되어 있는 컨테이너가 있을 때는 해당 볼륨이 제거가 되지않음
  • 그럴 때는 해당 볼륨이 마운트되어 있는 모든 컨테이너를 먼저 삭제하고 볼륨을 삭제해야 함
$ docker rm -f one two
one
two
$ docker volume rm our-vol
our-vol

볼륨 청소

  • docker volume prune 커맨드를 이용해서 마운트 되어 있지 않은 모든 볼륨을 한번에 제거할 수 있음
$ docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y

바인드 마운트

바인드 마운트란?

  • Docker 컨테이너에 데이터를 저장하기 위한 다른 방법으로 바인드 마운트(Bind Mount)라는 것도 있음
    • 바인드 마운트를 사용하면 호스트 파일 시스템의 특정 경로를 컨테이너로 바로 마운트할 수 있음
  • 바인드 마운트를 사용하는 방법은 docker run 커맨드를 실행할 때, -v 옵션의 콜론(:) 앞 부분에 마운트명 대신에 호스트의 경로를 지정
    • 예를 들어, 현재 경로에 test.txt 파일을 생성하고 해당 호스트 경로를 컨테이너의 /app 경로에 마운트 가능
    • 컨테이너에 터미널을 붙여서 ls /app 커맨드를 실행해보면 test.txt 파일이 컨테이너의 /app 경로에도 존재하는 것을 확인할 수 있음
    • 반대로 컨테이너의 /app 경로 상에서 test2.txt 파일을 실행해보면 호스트의 현재 경로에도 해당 파일이 보이는 것을 알 수 있음
    • docker inspect 커맨드로 해당 컨테이너의 상세 정보를 확인해보면 현재 경로(/root)가 bind 타입으로 마운트되어 있는 것을 확인할 수 있음
$ touch test.txt
$ docker run -v `pwd`:/app -it --name one busybox /bin/sh
/ # ls /app
test.txt

/ # touch /app/test2.txt
/ # exit
[node1] (local) root@192.168.0.18 ~
$ ls
test.txt   test2.txt

$ docker inspect one
(...생략...)
    "Mounts": [
        {
            "Type": "bind",
            "Source": "/root",
            "Destination": "/app",
            "Mode": "",
            "RW": true,
            "Propagation": "rprivate"
        }
    ],
(...생략...)

볼륨 VS 바인드 마운트

  • 볼륨(Volume)과 바인드 마운트(Bind Mount)의 가장 큰 차이점은 Docker가 해당 마운트 포인트를 관리해주느냐 안 해주느냐에 달려있음
    • 볼륨을 사용할 때는 우리가 스스로 볼륨을 생성하거나 삭제해야하는 불편함이 있지만, 해당 볼륨은 Docker 상에서 이미지(Image)나 컨테이너(Container), 네트워크(Network)와 비슷한 방식으로 관리가 되는 이점이 있음
    • 그래서 대부분의 상황에서는 볼륨을 사용하는 것이 권장되지만 컨테이너화된 로컬 개발 환경을 구성할 때는 바인드 마운트가 더 유리할 수 있음
  • 로컬에서 개발을 할 때는 일반적으로 현재 작업 디렉터리에 프로젝트 저장소를 git clone 받아놓고 코드를 변경
    • 따라서 바인드 마운트를 이용해서 해당 디렉터리를 컨테이너의 특정 경로에 마운트 해주면 코드를 변경할 때 마다 변경 사항을 실시간으로 컨테이너를 통해 확인할 수 있음
    • 반대로 컨테이너를 통해 변경된 부분도 현재 작업 디렉터리에도 반영이 되기 때문에 편리
profile
🌱 Backend-Dev | hwaya2828@gmail.com

0개의 댓글