[Docker 기본5] 볼륨을 활용한 데이터 관리

우리는 Container의 Writable Layer에 데이터를 디버깅할 수 있다는 것을 알고 있습니다. 그런데 여기에 몇 가지 문제가 있습니다.

  1. 컨테이너가 삭제되면 데이터도 같이 삭제됩니다. 또한, 다른 프로세스에서 컨테이너에 저장된 데이터를 사용하기 어렵습니다.
  2. Container의 Writable Layer에는 Container가 실행 중인 Host Machine과 함께 연결되게 됩니다. 따라서 데이터를 다른 곳으로 쉽게 포함할 수 없습니다.
  3. 컨테이너의 쓰기 가능 계층에 데이터를 저장하려면 파일 시스템을 관리하는 스토리지 드라이버가 필요합니다. 저장소 드라이버는 공용 파일 시스템을 사용하여 Linux를 사용합니다. 이 기능은 Host File System을 직접 사용하는 것 data volume보다 성능이 뛰어납니다.

Docker는 데이터를 안전하게 사용할 수 있는 방식으로 volume, bind mounts, tmpfs3가지 방식을 제공합니다(어떤 것을 사용할 지 모고 volume사용하기를 바랍니다). 아래는 컨테이너의 데이터 관리 방식과 사용 분야에서 자세히 살펴보는 부분입니다.

올바른 Mount 방식을 선택하는 방법

어떤 유형의 마운트를 사용하면, 데이터는 컨테이너 내에서 동일하게 위치, 컨테이너 파일 시스템의 폴더나 개별적인 파일에 표시됩니다. 올바른 Mount 유형을 사용하는 경우 기준이 volume, bind mounts, tmpfs mount가장 큰 차이점은 Data가 Docker Host 내에서 어디에 존재 하는지입니다.

Docker 출처: Docker Docs — 볼륨 사용

데이터 저장을 위한 최선의 선택

  • volume에서는 Docker(Linux /var/lib/docker/volume/)가 호스트 파일 시스템을 관리하는 부분에 데이터가 저장됩니다.
  • Docker가 아닌 프로세스들은 파일 시스템의 해당 부분을 수정해야 합니다.
  • Docker에서 데이터를 존속할 수 있는 Best한 방법 입니다.

Host의 File System 원하는 위치 저장

  • bind mount데이터가 호스트 시스템이 어디든 저장할 수 있습니다.
  • 저장되는 데이터는 시스템 파일이거나 디렉터리일 수 있습니다.
  • Docker 호스트 또는 Docker 컨테이너가 아닌 Docker 프로세서가 저장된 데이터를 저장할 수 있습니다.

호스트 시스템의 메모리 기록

  • tmpfs mount는 호스트 시스템의 메모리에만 데이터를 저장하고, 호스트의 파일 시스템에는 저장하지 않습니다.

마운트 유형

각 마운트에 대해 자세히 살펴보겠습니다.

용량

  • Docker가 생성하고 관리하는 방식입니다. docker volume create미스터리를 사용하여 볼륨을 생성하거나, 컨테이너나 서비스를 volume생성할 수 있습니다.
  • volume이 생성되면 Data는 Docker Host의 키예프에 저장됩니다. 해당 volume지역을 컨테이너에 마운트하면, 호스트의 카펫이 마운트됩니다. 이 volumeDocker에 의해 관리되고 Host System과 분리되는 것을 제외한다면, bind mount이와 동일하게 작동합니다.
  • 동시에 volume여러 컨테이너에 마운트할 수 있습니다.
  • 실행 중인 컨테이너를 volume사용하지 않고, volumeDocker에서 계속 사용할 수 없으며, 자동으로 삭제하지 않습니다.
  • docker volume prune사용하지 않고 volume정리할 수 있습니다.
  • volume을 마운트할 때, 이름을 기록으로 인증하여 사용할 수 있으며, 익명으로 사용할 수 있습니다.
  • volume고유한 것은 처음 Mount일 때 고유한 이름을 부여받은 것이므로, Docker는 Docker Host내에서 본질적인 고유의 이름을 해당에 부여 volume합니다.
  • 이름이 다른 방식과 관계없이 volume동일한 방식으로 작동합니다.
  • 또한, volume원격 호스트와 클라우드 공급자가 데이터를 디버깅할 수 있는 volume drivers사용을 지원하고 있습니다.

바인드 마운트

  • bind mount는 Docker 시작부터 사용할 수 있는 방식으로 volume에 비해 기능이 제한적입니다.
  • bind mount사용하면, 호스트 시스템의 파일 또는 하늘이 컨테이너에 마운트됩니다.
  • 파일 또는 링크는 Host System의 전체 경로를 참조하여 미리 Docker Host에 필요한 것은 없습니다. 드리는 경우, 참조된 경로로 파일이 생성됩니다.
  • bind mount호스트 머신의 파일 시스템은 매우 불리하지만, 스탠드에 의존하고 있습니다.
  • Docker CLI 펌웨어로 bind mount관리할 수 없습니다.

tmfs 마운트

  • tmpfs mount는 Docker 호스트 또는 컨테이너내의 디스크에서 데이터를 유지합니다.
  • 비영구적인 상태 정보나 민감한 정보들은 비슷하게 컨테이너의 수명 주기와 비교하여 데이터를 회수하고자 할 때 사용할 수 있습니다.
  • 예를 들어, Docker Clusterin Swarm Service는 내부적으로 tmps mount비밀 정보를 사용하여 서비스의 컨테이너에 마운트하여 사용합니다.

bind mount및는 volume또는 플래그를 사용하여 컨테이너에 모두 마운트할 수 있지만, 각 삽입은 -v기존 --volume의 변형이 있습니다. tmpfs mount어떤 경우에는 --tmpfs플래그를 사용합니다. 그러나 Docker 17.06 이상에서는 바인딩 마운트, 볼륨, tmpfs 마운트에 대해 컨테이너와 서비스에 --mount플래그를 사용하는 것이 모두 더 많이이기 때문에 권장합니다.

마운트 유형별 사용 사례

볼륨 점유율

volumeDocker 컨테이너 및 서비스에서 데이터를 유지하는 기본 방법은 다음과 같은 경우에 volume사용합니다.

  • 여러 컨테이너를 실행하면서 데이터 공유가 필요한 경우
  • volume생성에 있지 않은 경우, 컨테이너에 처음 마운트될 때 생성됩니다.
  • 컨테이너가 중단 제거되고 생성된 volume것은 그대로 유지됩니다.
  • 여러 컨테이너가 같은 그룹 volume을 읽기/쓰기 또는 비교하면 동시에 마운트할 수 있습니다.
  • volume은폐적으로 블록 선언을 제거합니다.
  • Docker 호스트가 특정 파일 구조를 가질 수 없는 경우
  • volume은 Container Runtime에서 Docker Host의 설정을 분리하는 데 도움이 됩니다.
  • 외부의 원격 호스트 및 클라우드 제공업체에 컨테이너의 데이터 저장을 시도하는 경우
  • Docker 호스트에서 다른 Docker 호스트로 데이터를 백업하거나 복구하거나 마이그레이션을 하는 경우 volume를 사용하면 더 좋습니다.
  • volume컨테이너를 사용하여 중지한 다음 volume의 키예프(예: /var/lib/docker/volume/<volume-name>)를 백업할 수 있습니다.

바인드 마운트 보유자

일반적인 경우에는 가능하면 bind mount사용 volume하는 것이 좋습니다. 다음과 같은 경우를 bind mount사용합니다.

  • Host Machine에서 컨테이너로 파일을 설정해야 하는 경우
  • Docker는 Host Machine의 /etc/resolv.conf각 컨테이너에 대해 bind mountDNS 확인을 제공하고 있습니다.
  • Docker 호스트 개발 환경과 컨테이너 간 소스 코드 또는 빌드된 아티팩트를 공유
  • 예를 들어, Maven의 target/부스를 컨테이너에 마운트하고, Docker Host에서 Maven 프로젝트를 빌드할 때마다, 컨테이너가 재작성된 JAR/WAR에 접근할 수 있습니다.
  • 만약 이런 방식으로 개발을 진행한다면, Production Dockerfile은 bind mount에 의존하지 않고, Production-Ready 아티팩트를 이미지에 직접 복사할 수 있습니다.
  • Docker 호스트의 파일 또는 키예프 구조가 컨테이너가 바인드 마운트와 일치하는 경우를 요구하는 경우

볼륨 또는 바인드 마운트 사용 시, 의미사항

volume또는 bind mount사용하는 경우, 다음의 사항에 대해 말씀드리겠습니다.

  • 파일 또는 디렉터리 있는 컨테이너를 보면 디렉터리에 비어 있는 volume것을 Mount, 해당 파일 또는 디렉터리가 volume으로 전달(복사)됩니다. 마찬가지로, 아직 존재하지 않고 특정 volume을 예비하고 컨테이너를 시작하면 비어있는 volume것이 생성됩니다. 다른 컨테이너에 필요한 데이터를 미리 알려줄 수 있는 좋은 방법입니다.
  • File 또는 Directory가 있는 컨테이너는 Directory에 bind mount또는 존재하지 않는 volume것을 Mount한다면, Linux Host에서 파일을 /mnt에 저장하고 외계인 USB 드라이브가 /mnt에 Mount되는 것처럼 기존에 존재하는 File 또는 Directory가 Mount를 가져오게 합니다. /mnt의 컨텐츠들은 USB 드라이브가 Unmount될 때까지, USB 드라이브의 컨텐츠들에 조치를 취합니다. 가려진 파일은 제거된 것을 대체하는 것입니다, bind mount또는 volume이 Mount되어 있는 동안은 접근할 수 없습니다.

tmpfs 마운트 보유자

tmpfs mount은 호스트 시스템이나 컨테이너 내에서 데이터를 유지하지 않을 때 가장 적합합니다. 보안 상의 이유가 있을 수도 있고, 애플리케이션이 많은 비영구적인 상태의 데이터를 작성해야 할 때, 컨테이너의 성능을 보호하기 위해 기다릴 수도 있습니다.

볼륨 마운트 하기

볼륨을 사용하기 전에, 볼륨을 마운트하기 위해 플래그를 보장합니다.

-v 또는 –mount 선택

원래는 컨테이너 형태로 -v--volumeDocker Clusterin Swarm Mode의 서비스가 --mount사용되었습니다. 하지만 Docker 17.06부터 면형 Container도 --mount사용할 수 있게 됩니다. 두 개의 플래그 사이에서 가장 큰 차이를 읽는 -v것은 모든 옵션을 하나의 Field에 따라 사용하고, --mount읽어들이는 옵션을 분리하여 사용합니다. 따라서, --mount가보다 더 많은 정보를 교환할 수 있습니다.

다음은 Flag별 플러그인입니다.

-v또는--volume

  • 콜론(:)으로 구분된 필드로 구성되어 있습니다. 필드의 약속을 지켜야 하며 각 필드의 의미는 없습니다.
  • 이름이 존재하는 volume경우, 첫 번째 필드는 volume의 이름이며, Host Machine에서 유일해야 합니다. 익명 volume의 경우, 스트 필드는 종료됩니다.
  • 터미널 필드는 파일 또는 디렉토리가 컨테이너에 마운트될 위치입니다.
  • 필드 필드는 선택사항이며, 콤표(,)로 구분된 옵션 목록(예: ro(읽기전용을 위한 옵션))입니다.

--mount

  • 쉼표(,)로 구분되고 각각의 여러 키-값으로 구성됩니다. --mount카드를 읽는 것은 -v또는 --volume보기 길지만, 열쇠의 짧은 시간은 중요하므로 플래그의 가치를 이해하기 쉽습니다.
  • type은( bind, volume, tmpfs는) Mount에서 출발합니다.
  • source의 volume이름입니다. 익명 volume을 사용하고자 하는 경우, 해당 필드를 이용하셔도 됩니다. source또는 src로 반대할 수 있습니다.
  • destination은 파일 또는 스키가 컨테이너에 마운트되어 출발합니다. destination, dst또는 target으로 반대할 수 있습니다.
  • readonly옵션이 있으면 컨테이너에 대해 알아보겠습니다.
  • 두 번 이상 해당할 수 있는 volume-opt옵션은 옵션 이름과 값으로 되어 키-값을 사용합니다.

-v와 –mount 사이의 동작 차이

bind mount와 달리, volume의 모든 옵션 --mount과 -v플래그를 사용할 수 있습니다. 단, 서비스를 volume사용하고자 하면 --mount지원이 이루어집니다.

볼륨 생성 및 삭제하기

docker volume create [OPTIONS] [VOLUME]로을 volume생성합니다.

docker volume ls [OPTIONS]로의 volume전체 목록을 확인합니다.

docker volume inspect [OPTIONS] VOLUME [VOLUMES...]로 생성한 volume의 상세 정보를 확인합니다.

docker volume rm [OPTIONS] VOLUME [VOLUME...]로 생성을 volume삭제합니다.

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

--mount컨테이너를 사용하여 플래그를 사용하세요. 시, volume을 마운트합니다.

생성된 컨테이너의 상세 정보를 확인합니다. Mounts Field에서 volume에 대한 상세정보를 교환할 수 있습니다. 마운트 형식은 volume소스 및 대상의 경로를 해결할 수 있고, 읽기/쓰기가 가능한 모든 것을 가능하게 할 수 있습니다.

컨테이너를 중지하고 생성한 컨테이너를 volume제거합니다.

Docker Cluster인 Swarm Mode의 Service도 컨테이너와 동일한 방식을 volume사용할 수 있습니다. 서비스를 시작하고 volume정의하면, 각 서비스 컨테이너는 자체적으로 volume사용됩니다. 위치 volume driver를 사용하는 경우, 컨테이너 중 어느 것도 해당 데이터를 공유할 수 없는 일부 volume driver는 공유 스토리지를 지원합니다. AWS용 Docker와 Azure용 Docker는 모두 Cloudstor를 사용하여 영구 전원을 지원합니다.

컨테이너로 볼륨에 데이터를 기록하기

컨테이너를 해당할 때 새로 volume생성하고, 컨테이너에 마운트할 디렉터리 내에 파일 또는 디렉터리가 있으면(예: /app/) 디렉터리의 내용이 volume으로 복사됩니다. 컨테이너는 volume을 Mount하여 사용하고, 다른 컨테이너도 예전에 volume컨턴츠에 접근할 수 있습니다.

먼저 컨테이너를 검색할 때, destination을 /usr/share/nginx/html로 충전하여, 해당 디렉토리의 내용으로 새로운 nginx-vol이름의 volume에 데이터를 충전질할 수 있도록 설장합니다. 해당 디렉토리는 Nginx의 기본 HTML 컨텐츠를 저장하는 장소입니다.

생성된 컨테이너의 상세 정보를 확인합니다. Mounts Field에서 volume에 대한 상세정보를 교환하실 수 있습니다.

컨테이너를 중지하고 생성한 컨테이너를 volume제거합니다.

읽기전용 볼륨 Mount하기

애플리케이션의 경우, Container가 Docker Host로 변경된 사항을 일부 다시 개발할 수 있도록 하여 bind mount사용하시기 바랍니다. 현재, 다른 컨테이너는 단지 데이터를 읽기만 하고 있고, 수정하지 못해야 할 수 있습니다. 즉, 여러 컨테이너가 동일한 volume것을 마운트할 수 있으며, 일부 컨테이너는 읽기/쓰기로, 그 외부 컨테이너는 읽기전용으로 마운트하여 사용할 수도 있습니다.

--mount에 readonly옵션을 추가하여 컨테이너와 볼륨을 생성합니다.

생성된 컨테이너의 상세 정보를 확인합니다. Mounts Field에서 volume에 대한 상세정보를 교환할 수 있습니다. readonly옵션이 적용되어, RWKey의 가치가 false로 되어있는 것을 받으실 수 있습니다.

컨테이너를 중지하고 생성한 컨테이너를 volume제거합니다.

이렇게 volume사용함으로써, 컨테이너의 데이터를 영구적으로 존속시킬 수 있습니다. 또한 NFS 또는 AWS의 S3와 같은 외부 스토리지 시스템과의 수집을 통해 Docker Machine 내부에서 데이터를 공유할 수 있는 다양한 드라이버가 있습니다. 이 때, volume driver스토리지 시스템을 추상화하여 사용하기 때문에 애플리케이션을 변경하지 않고도 데이터를 유지할 수 있습니다.

컨테이너란 무엇인가라는 주제부터 시작해서 볼륨을 활용한 컨테이너 데이터 관리까지, 애플리케이션이 컨테이너화하여 어떤 식으로 동작하고, 무엇을 할 것인지에 맞는 항목을 확인했습니다. 현재까지 모든 항목은 단일 Docker Machine 환경으로 제한적으로 생각됩니다. 다음에는 Docker Cluster인 Swarm을 구성하여 이러한 컨테이너를 어떤 방식으로 오케스트레이션할 수 있는지 알아볼게요.