웹사이트 검색

Docker 컨테이너 간에 데이터를 공유하는 방법


소개

Docker는 실행에 필요한 모든 것을 포함하는 파일 시스템을 소프트웨어 애플리케이션에 제공하는 데 사용되는 널리 사용되는 컨테이너화 도구입니다. Docker 컨테이너를 사용하면 런타임 환경이 일관되기 때문에 소프트웨어가 배포된 위치에 관계없이 동일한 방식으로 작동합니다.

일반적으로 Docker 컨테이너는 일시적이며 컨테이너에서 실행된 명령이 완료되는 동안 실행됩니다. 그러나 경우에 따라 애플리케이션은 데이터에 대한 액세스를 공유하거나 컨테이너가 삭제된 후 데이터를 유지해야 합니다. 데이터베이스, 웹 사이트용 사용자 생성 콘텐츠 및 로그 파일은 Docker 이미지에 포함하는 것이 비실용적이거나 불가능하지만 애플리케이션이 액세스해야 하는 데이터의 몇 가지 예에 불과합니다. 데이터에 대한 지속적인 액세스는 Docker 볼륨과 함께 제공됩니다.

Docker 볼륨은 컨테이너를 생성하는 동일한 명령으로 생성 및 연결하거나 컨테이너와 독립적으로 생성하여 나중에 연결할 수 있습니다. 이 기사에서는 컨테이너 간에 데이터를 공유하는 네 가지 방법을 살펴보겠습니다.

전제 조건

이 문서를 따르려면 다음과 같은 Ubuntu 20.04 서버가 필요합니다.

  • sudo 권한이 있는 루트가 아닌 사용자. Ubuntu 20.04 가이드의 초기 서버 설정에서 이를 설정하는 방법을 설명합니다.
  • Ubuntu 20.04에서 Docker를 설치 및 사용하는 방법의 1단계 및 2단계 지침에 따라 Docker 설치

참고: 전제 조건에서 Ubuntu 20.04에 Docker를 설치하기 위한 지침을 제공하지만 이 문서의 Docker 데이터 볼륨에 대한 docker 명령은 Docker가 설치되어 있고 sudo 사용자가 있는 한 다른 운영 체제에서 작동해야 합니다. docker 그룹에 추가되었습니다.

1단계 - 독립 볼륨 생성

Docker의 1.9 릴리스에 도입된 docker volume create 명령을 사용하면 특정 컨테이너에 연결하지 않고도 볼륨을 생성할 수 있습니다. 이 명령을 사용하여 DataVolume1이라는 볼륨을 추가합니다.

  1. docker volume create --name DataVolume1

명령이 성공했음을 나타내는 이름이 표시됩니다.

Output
DataVolume1

볼륨을 사용하기 위해 --rm 플래그를 사용하여 Ubuntu 이미지에서 새 컨테이너를 생성하여 종료할 때 자동으로 삭제합니다. 또한 -v를 사용하여 새 볼륨을 마운트합니다. -v에는 볼륨 이름, 콜론, 컨테이너 내부에 볼륨이 나타나야 하는 절대 경로가 필요합니다. 경로의 디렉토리가 이미지의 일부로 존재하지 않는 경우 명령이 실행될 때 생성됩니다. 있는 경우 마운트된 볼륨은 기존 콘텐츠를 숨깁니다.

  1. docker run -ti --rm -v DataVolume1:/datavolume1 ubuntu

컨테이너에 있는 동안 볼륨에 일부 데이터를 작성해 보겠습니다.

  1. echo "Example1" > /datavolume1/Example1.txt

--rm 플래그를 사용했기 때문에 컨테이너는 종료 시 자동으로 삭제됩니다. 그러나 볼륨은 계속 액세스할 수 있습니다.

  1. exit

docker volume inspect를 사용하여 시스템에 볼륨이 있는지 확인할 수 있습니다.

  1. docker volume inspect DataVolume1
Output
[ { "CreatedAt": "2018-07-11T16:57:54Z", "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/DataVolume1/_data", "Name": "DataVolume1", "Options": {}, "Scope": "local" } ]

참고: Mountpoint로 나열된 경로에서 호스트의 데이터를 볼 수도 있습니다. 그러나 응용 프로그램이나 컨테이너가 변경 사항을 인식하지 못하는 경우 데이터 손상이 발생할 수 있으므로 변경하지 않아야 합니다.

다음으로 새 컨테이너를 시작하고 DataVolume1을 연결해 보겠습니다.

  1. docker run --rm -ti -v DataVolume1:/datavolume1 ubuntu

내용 확인:

  1. cat /datavolume1/Example1.txt
Output
Example1

컨테이너를 종료합니다.

  1. exit

이 예에서는 볼륨을 만들어 컨테이너에 연결하고 지속성을 확인했습니다.

2단계 - 컨테이너 제거 시 지속되는 볼륨 생성

다음 예에서는 컨테이너와 동시에 볼륨을 생성하고 컨테이너를 삭제한 다음 볼륨을 새 컨테이너에 연결합니다.

docker run 명령을 사용하여 기본 Ubuntu 이미지를 사용하여 새 컨테이너를 생성합니다. -t는 터미널을 제공하고 -i는 터미널과 상호 작용할 수 있도록 합니다. 명확성을 위해 --name을 사용하여 컨테이너를 식별합니다.

-v 플래그를 사용하면 DataVolume2라고 하는 새 볼륨을 만들 수 있습니다. 콜론을 사용하여 이 이름을 컨테이너에 볼륨을 마운트해야 하는 경로와 구분합니다. 마지막으로 기본 Ubuntu 이미지를 지정하고 Ubuntu 기본 이미지의 Docker 파일인 bash의 기본 명령을 사용하여 셸에 진입합니다.

  1. docker run -ti --name=Container2 -v DataVolume2:/datavolume2 ubuntu

참고: -v 플래그는 매우 유연합니다. 구문을 약간만 조정하면 볼륨을 바인드마운트하거나 이름을 지정할 수 있습니다. 첫 번째 인수가 / 또는 ~/로 시작하면 bindmount를 생성하는 것입니다. 그것을 제거하면 볼륨의 이름이 지정됩니다. 예를 들어:

  • -v /path:/path/in/container는 호스트 디렉토리인 /path/path/in/container에 마운트합니다.
  • -v path:/path/in/container는 호스트와 관계가 없는 path라는 볼륨을 생성합니다.

호스트에서 디렉토리를 바인드마운트하는 방법에 대한 자세한 내용은 Docker 컨테이너와 호스트 간에 데이터를 공유하는 방법을 참조하세요.

컨테이너에 있는 동안 일부 데이터를 볼륨에 씁니다.

  1. echo "Example2" > /datavolume2/Example2.txt
  2. cat /datavolume2/Example2.txt
Output
Example2

컨테이너를 종료합시다.

  1. exit

컨테이너를 다시 시작하면 볼륨이 자동으로 마운트됩니다.

  1. docker start -ai Container2

볼륨이 실제로 마운트되었고 데이터가 아직 제자리에 있는지 확인하겠습니다.

  1. cat /datavolume2/Example2.txt
Output
Example2

마지막으로 종료하고 정리하겠습니다.

  1. exit

Docker는 컨테이너가 볼륨을 참조하는 경우 볼륨을 제거하도록 허용하지 않습니다. 시도할 때 어떤 일이 발생하는지 봅시다.

  1. docker volume rm DataVolume2

메시지는 볼륨이 아직 사용 중임을 알려주고 컨테이너 ID의 긴 버전을 제공합니다.

Output
Error response from daemon: unable to remove volume: remove DataVolume2: volume is in use - [d0d2233b668eddad4986313c7a4a1bc0d2edaf0c7e1c02a6a6256de27db17a63]

이 ID를 사용하여 컨테이너를 제거할 수 있습니다.

  1. docker rm d0d2233b668eddad4986313c7a4a1bc0d2edaf0c7e1c02a6a6256de27db17a63
Output
d0d2233b668eddad4986313c7a4a1bc0d2edaf0c7e1c02a6a6256de27db17a63

컨테이너를 제거해도 볼륨에 영향을 주지 않습니다. docker volume ls로 볼륨을 나열하면 시스템에 여전히 존재하는 것을 볼 수 있습니다.

  1. docker volume ls
Output
DRIVER VOLUME NAME local DataVolume2

그리고 docker volume rm을 사용하여 제거할 수 있습니다.

  1. docker volume rm DataVolume2

이 예에서는 컨테이너를 생성함과 동시에 빈 데이터 볼륨을 생성했습니다. 다음 예에서는 이미 데이터가 포함된 컨테이너 디렉토리로 볼륨을 생성할 때 어떤 일이 발생하는지 살펴보겠습니다.

3단계 - 데이터가 있는 기존 디렉토리에서 볼륨 생성

일반적으로 docker volume create를 사용하여 독립적으로 볼륨을 생성하는 것과 컨테이너를 생성하는 동안 볼륨을 생성하는 것은 한 가지 예외를 제외하고 동일합니다. 컨테이너를 생성하는 것과 동시에 볼륨을 생성하고 기본 이미지에 데이터가 포함된 디렉토리의 경로를 제공하면 해당 데이터가 볼륨에 복사됩니다.

예를 들어 컨테이너를 만들고 기본 이미지의 데이터가 포함된 디렉터리인 /var에 데이터 볼륨을 추가합니다.

  1. docker run -ti --rm -v DataVolume3:/var ubuntu

기본 이미지의 /var 디렉토리에 있는 모든 콘텐츠가 볼륨으로 복사되고 해당 볼륨을 새 컨테이너에 마운트할 수 있습니다.

현재 컨테이너를 종료합니다.

  1. exit

이번에는 기본 이미지의 기본 bash 명령에 의존하지 않고 쉘에 들어가지 않고 볼륨의 내용을 표시하는 자체 ls 명령을 실행합니다.

  1. docker run --rm -v DataVolume3:/datavolume3 ubuntu ls datavolume3

이제 datavolume3 디렉토리에 기본 이미지의 /var 디렉토리 콘텐츠 사본이 있습니다.

Output
backups cache lib local lock log mail opt run spool tmp

이런 방식으로 /var/를 마운트하고 싶지 않을 것 같지만, 자체 이미지를 만들고 데이터를 쉽게 보존할 수 있는 방법을 원하는 경우 이 방법이 도움이 될 수 있습니다. 다음 예에서는 여러 컨테이너 간에 볼륨을 공유하는 방법을 보여줍니다.

4단계 - 여러 Docker 컨테이너 간에 데이터 공유

지금까지 한 번에 하나의 컨테이너에 볼륨을 연결했습니다. 종종 우리는 여러 컨테이너가 동일한 데이터 볼륨에 연결되기를 원할 것입니다. 이 작업은 비교적 간단하지만 한 가지 중요한 주의 사항이 있습니다. 현재 Docker는 파일 잠금을 처리하지 않습니다. 여러 컨테이너가 볼륨에 기록되어야 하는 경우 데이터 손상을 방지하기 위해 해당 컨테이너에서 실행되는 애플리케이션이 공유 데이터 저장소에 기록하도록 반드시 설계되어야 합니다.

Container4 및 DataVolume4 생성

docker run을 사용하여 데이터 볼륨이 연결된 Container4라는 새 컨테이너를 만듭니다.

  1. docker run -ti --name=Container4 -v DataVolume4:/datavolume4 ubuntu

다음으로 파일을 만들고 텍스트를 추가합니다.

  1. echo "This file is shared between containers" > /datavolume4/Example4.txt

그런 다음 컨테이너를 종료합니다.

  1. exit

이렇게 하면 Container4에서 데이터 볼륨을 탑재하는 새 컨테이너를 만들 호스트 명령 프롬프트로 돌아갑니다.

Container5 생성 및 Container4에서 볼륨 마운트

Container5를 생성하고 Container4에서 볼륨을 마운트할 것입니다.

  1. docker run -ti --name=Container5 --volumes-from Container4 ubuntu

데이터 지속성을 확인해 보겠습니다.

  1. cat /datavolume4/Example4.txt
Output
This file is shared between containers

이제 Container5에서 일부 텍스트를 추가해 보겠습니다.

  1. echo "Both containers can write to DataVolume4" >> /datavolume4/Example4.txt

마지막으로 컨테이너를 종료합니다.

  1. exit

다음으로 데이터가 여전히 Container4에 있는지 확인합니다.

Container5에서 변경된 사항 보기

Container4를 다시 시작하여 Container5에 의해 데이터 볼륨에 기록된 변경 사항을 확인합니다.

  1. docker start -ai Container4

변경 사항을 확인합니다.

  1. cat /datavolume4/Example4.txt
Output
This file is shared between containers Both containers can write to DataVolume4

이제 두 컨테이너가 데이터 볼륨에서 읽고 쓸 수 있음을 확인했으므로 컨테이너를 종료합니다.

  1. exit

다시 말하지만, Docker는 파일 잠금을 처리하지 않으므로 애플리케이션은 반드시 파일 잠금을 고려해야 합니다. :ro를 추가하여 컨테이너에 읽기 전용 액세스가 필요할 때 실수로 데이터 손상이 발생하지 않도록 Docker 볼륨을 읽기 전용으로 마운트할 수 있습니다. 이것이 어떻게 작동하는지 살펴보겠습니다.

컨테이너 6 시작 및 볼륨 읽기 전용 마운트

볼륨이 컨테이너에 마운트되면 일반적인 Linux 파일 시스템에서와 같이 볼륨을 마운트 해제하는 대신 원하는 방식으로 마운트된 새 컨테이너를 생성하고 필요한 경우 이전 컨테이너를 제거할 수 있습니다. 볼륨을 읽기 전용으로 만들기 위해 컨테이너 이름 끝에 :ro를 추가합니다.

  1. docker run -ti --name=Container6 --volumes-from Container4:ro ubuntu

예제 파일을 제거하여 읽기 전용 상태를 확인합니다.

  1. rm /datavolume4/Example4.txt
Output
rm: cannot remove '/datavolume4/Example4.txt': Read-only file system

마지막으로 컨테이너를 종료하고 테스트 컨테이너와 볼륨을 정리합니다.

  1. exit

이제 완료되었으므로 컨테이너와 볼륨을 정리하겠습니다.

  1. docker rm Container4 Container5 Container6
  2. docker volume rm DataVolume4

이 예제에서는 데이터 볼륨을 사용하여 두 컨테이너 간에 데이터를 공유하는 방법과 데이터 볼륨을 읽기 전용으로 마운트하는 방법을 보여주었습니다.

결론

이 자습서에서는 컨테이너 삭제를 통해 데이터를 유지할 수 있는 데이터 볼륨을 만들었습니다. 데이터 손상을 방지하기 위해 파일 잠금을 처리하도록 응용 프로그램을 설계해야 한다는 경고와 함께 컨테이너 간에 데이터 볼륨을 공유했습니다. 마지막으로 공유 볼륨을 읽기 전용 모드로 마운트하는 방법을 보여 주었습니다. 컨테이너와 호스트 시스템 간의 데이터 공유에 대해 알아보려면 Docker 컨테이너와 호스트 간에 데이터를 공유하는 방법을 참조하세요.