컨테이너 파일시스템과 데이터 저장을 위한 마운트

정민교·2024년 5월 10일
0

Docker

목록 보기
3/10
post-thumbnail

📒목표

컨테이너의 데이터를 DB로 영구 저장하기

📒컨테이너 파일시스템

컨테이너는 각각 독립된 파일 시스템을 가지며, 이는 이미지의 레이어들을 기반으로 구성됩니다.

컨테이너가 실행될 때마다 그 이미지의 레이어를 사용하여 자신만의 공간(스크래치 공간)을 생성합니다. 이 공간에서 파일을 만들거나 변경하거나 삭제할 수 있습니다.

한 컨테이너에서 파일을 추가하거나 수정하는 경우, 같은 이미지를 사용하더라도 다른 컨테이너에는 영향을 주지 않습니다.

이는 각 컨테이너가 완전히 독립적으로 동작한 다는 것을 잘 보여주는 하나의 예로 볼 수 있습니다.

✔️예시로 확인해보기

컨테이너 실행

alpine 컨테이너를 실행하고 컨테이너에서 파일 하나를 생성합니다.

새로운 컨테이너 실행

새로운 컨테이너를 실행하면서 greeting.txt 파일 내용을 출력해봅시다.

docker run alpine cat greeting.txt

greeting.txt 파일이 없다는 에러 메시지가 출력됩니다.

이처럼 같은 이미지를 사용해서 컨테이너를 띄워도, 각 컨테이너는 독립적인 환경에서 동작하기 때문에 한 컨테이너의 변경사항은 다른 컨테이너에 영향을 미치지 않습니다.

📒컨테이너 볼륨(볼륨 마운트)

컨테이너는 파일을 생성, 삭제, 변경할 수 있습니다. 하지만 컨테이너를 제거하면 이 파일들이 모두 사라집니다.

하지만 볼륨을 사용하면 컨테이너가 삭제되어도 파일들을 보존할 수 있습니다.

볼륨은 컨테이너와 호스트 간에 파일을 공유할 수 있는 방법을 제공합니다. 이를 통해 컨테이너를 삭제해도 데이터를 유지할 수 있습니다.

컨테이너 내의 디렉토리를 호스트의 파일시스템과 연결하면 컨테이너 내에서 이루어진 변경사항(저장 및 수정한 데이터)을 호스트에도 저장할 수 있습니다.

이렇게 해서 컨테이너를 재실행하거나, 다른 컨테이너를 실행할 때에도 호스트에 저장한 데이터를 계속 사용할 수 있습니다.

✔️볼륨 마운트 사용하기

이전 todo 앱에서 다시 시작해볼 겁니다.

📌볼륨 생성하기

docker volume create todo-db

📌컨테이너 실행하기

docker run -dp 127.0.0.1:3000:3000 --mount type=volume,src=todo-db,target=//etc/todos --name getting-started getting-started

저는 Windows 환경에서 git bash를 사용중이어서 //를 사용했습니다.(자세한 정보)

📌todo 앱에 리스트 추가해보기

컨테이너에서 실행한 앱에 접속해서 todo 리스트를 추가합니다.

📌컨테이너 삭제하고 새컨테이너 실행하기

삭제

docker stop getting-started
docker rm getting-started

새 컨테이너 실행

docker run -dp 127.0.0.1:3000:3000 --mount type=volume,src=todo-db,target=//etc/todos --name getting-started getting-started

다시 컨테이너를 실행해도 투두 리스트가 유지되어 있습니다.

체크를 진행하고 과정을 반복해봅시다.


마찬가지로 유지되어 있습니다.

✔️volume 확인하기

$ docker volume inspect todo-db
[
    {
        "CreatedAt": "2024-05-10T03:16:02Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/todo-db/_data",
        "Name": "todo-db",
        "Options": null,
        "Scope": "local"
    }
]

docker volume inspect <volume-name>을 명령을 통해 volume을 사용할 때 Docker가 어디에 데이터를 저장하고 있는지 확인할 수 있습니다.

📒바인드 마운트

바인드 마운트는 호스트의 파일 시스템에 있는 디렉토리를 컨테이너에 연결하여, 호스트에서 파일을 변경할 때 컨테이너에서도 즉시 변경사항을 볼 수 있게 해줍니다.

이는 개발 중에 매우 유용하며, 소스 코드를 컨테이너에 마운트하여 실시간으로 코드 수정사항을 반영할 수 있습니다.

이를 통해 파일을 저장하는 즉시 컨테이너에서 코드 변경 사항을 볼 수 있습니다. 이는 파일 시스템의 변경을 감시하고 그에 반응하는 컨테이너 내 프로세스를 실행할 수 있다는 의미입니다.

✔️바인드 마운트 사용해보기

📌바인드 마운트로 컨테이너 실행하기

docker run -it --mount type=bind,src="/$(pwd)",target=/src ubuntu bash

저는 windows에서 git bash를 사용중이어서 src에 /를 붙였습니다.

실행 후 확인해보면 현재 프로젝트 파일들이 컨테이너의 /src 경로에 마운트 되어있는 것을 확인할 수 있습니다.

📌컨테이너에서 파일 생성 및 확인

컨테이너에서 myfile.txt를 만들고 컨테이너와 호스트에서 각각 확인해봅시다.

📌호스트에서 파일 삭제 및 확인

이번엔 호스트에서 myfile.txt를 삭제하고 컨테이너와 호스트에서 각각 확인해봅시다.

이 과정을 통해 호스트와 컨테이너 간에 파일이 어떻게 공유되고 변경사항이 양쪽에 즉시 반영되는지를 확인할 수 있습니다. 이제 바인드 마운트를 사용하여 소프트웨어 개발에 활용할 수 있습니다.

✔️바인드 마운트 사용해서 로컬 개발 환경 구성하기

📌개발 컨테이너에서 앱 실행하기

Docker CLI 또는 Docker Desktop을 사용해서 바인드 마운트와 함께 컨테이너를 실행할 수 있습니다.

여기서는 CLI로 해보겠습니다.

docker run -dp 127.0.0.1:3000:3000 \
   -w //app --mount type=bind,src="/$(pwd)",target=/app \
   node:18-alpine \
   sh -c "yarn install && yarn run dev"

마찬가지로 git bash에서 사용하는 명령어입니다.

  • -w 플래그는 working directory를 설정하는 플래그입니다.
  • --mount type=bind,src="/$(pwd)",target=/app 명령을 사용해서 호소트의 현재 경로를 컨테이너의 /app 디렉토리에 바인드 마운트를 진행합니다.
  • node:18-alpine 이미지를 앱을 실행할 기본 이미지로 사용합니다.
  • sh -c "yarn install && yarn run dev" alpine 버전은 bash가 없어서 sh로 쉘을 사용할 수 있습니다.
    패키지를 설치하고, yarn run dev로 앱을 실행합니다.
    👉 -c 플래그는 "command"의 약자로, 쉘(shell)에게 문자열로 된 명령을 실행하라고 지시합니다. 이 플래그는 명령줄(command line)에서 단일 명령이나 여러 명령의 조합을 실행할 때 사용됩니다.

📌컨테이너 로그 확인하기

docker logs -f 9caefa43ae1216773d0171daef61fb987562a986e9c4ec27e61c779fd85f177e

-f 플래그를 사용하면 컨테이너에서 새로운 로그가 생성될 때마다 즉시 터미널에 표시되어, 컨테이너의 현재 상태를 지속적으로 모니터링 할 수 있습니다.

yarn install v1.22.19
[1/4] Resolving packages...
warning sqlite3 > node-gyp > make-fetch-happen > cacache > @npmcli/move-file@1.1.2: This functionality has been moved to @npmcli/fs
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
Done in 53.00s.
yarn run v1.22.19
$ nodemon -L src/index.js
[nodemon] 2.0.22
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node src/index.js`
Using sqlite database at /etc/todos/todo.db
Listening on port 3000

✔️개발 컨테이너 실시간 변경사항 적용하기

호스트 머신에서 소스 코드를 변경하고 변경 사항을 적용하면, 바인트 마운트 덕분에 컨테이너에서도 파일 변경을 감지합니다.

이 프로젝트에서는 nodemon으로 서버를 실행중이므로 변경사항을 감지할 때 nodemon이 서버를 자동으로 재시작합니다.

변경사항을 적용하니 컨테이너에서 실행중인 앱이 재시작 되었습니다.

변경사항을 웹 브라우저에서 확인해봅시다.

변경사항이 잘 적용되었습니다.

📒바인드 마운트와 네임드 볼륨의 차이점

네임드 볼륨 (Named Volumes)

  • 호스트 위치: Docker가 볼륨 데이터를 저장할 위치를 자동으로 관리하며, 대개 /var/lib/docker/volumes/ 아래에 위치합니다.
  • 새 볼륨에 컨테이너 내용 채우기: 볼륨을 처음 생성할 때 컨테이너의 해당 경로에 이미 존재하는 데이터를 볼륨에 복사합니다. 이는 볼륨을 초기 상태로 설정하는 데 유용합니다.
  • 볼륨 드라이버 지원: 네트워크 스토리지와 같은 외부 스토리지 솔루션을 사용할 수 있게 해주는 볼륨 드라이버를 사용할 수 있습니다.

바인드 마운트 (Bind Mounts)

  • 호스트 위치: 사용자가 정확한 경로를 지정하여 호스트 시스템의 특정 파일이나 디렉토리를 컨테이너에 직접 마운트합니다.
  • 새 볼륨에 컨테이너 내용 채우기: 바인드 마운트는 기존에 호스트에 있는 데이터를 사용하므로, 볼륨을 생성할 때 컨테이너의 데이터를 복사하지 않습니다.
  • 볼륨 드라이버 지원: 볼륨 드라이버를 지원하지 않으며, 로컬 파일 시스템에 직접 접근합니다.

📒정리

https://docs.docker.com/storage/
https://docs.docker.com/reference/cli/docker/

profile
백엔드 개발자

0개의 댓글