Docker에서 영구 저장소 (예 : 데이터베이스)를 처리하는 방법


992

사람들이 Docker 컨테이너의 영구 저장소를 어떻게 처리합니까?

현재이 접근법을 사용하고 있습니다 : 예를 들어 PostgreSQL의 이미지를 빌드 한 다음 컨테이너를 시작하십시오.

docker run --volumes-from c0dbc34fd631 -d app_name/postgres

IMHO, 그것은 단점이 있습니다. 우연히 컨테이너 "c0dbc34fd631"을 삭제해서는 안됩니다.

또 다른 아이디어는 컨테이너에 호스트 볼륨 "-v"를 장착하는 것입니다, 그러나, 사용자 ID 컨테이너 내에서 반드시 일치하지 않는 사용자 ID를 호스트에서 다음 사용 권한이 엉망이 될 수 있습니다.

참고 : 대신 --volumes-from 'cryptic_id'당신은 또한 사용할 수있는 --volumes-from my-data-containermy-data-container은 데이터 전용 용기에 할당 된 이름입니다, 예를 들어 docker run --name my-data-container ...(허용 대답을 참조)


죄송합니다. 그 말을 잘못 표현했습니다. 해당 이미지의 모든 미래 인스턴스는 해당 컨테이너에 따라 다릅니다. 실수로 해당 컨테이너를 삭제하면 문제가 있습니다.
juwalter

@AntonStrogonoff-그렇습니다, 문구 오류-나는 말할 것입니다 : 나는 (아마도) 오래된 컨테이너를 삭제하지 않도록해야합니다. 왜냐하면 "지속적인"저장소도 사라질
것이기

이어야합니다 --name. 당신은-name
Shammel Lee

답변:


986

도커 1.9.0 이상

볼륨 API 사용

docker volume create --name hello
docker run -d -v hello:/container/path/for/volume container_image my_command

이는 새로운 볼륨을 위해 데이터 전용 컨테이너 패턴을 포기해야한다는 것을 의미합니다.

실제로 볼륨 API는 데이터 컨테이너 패턴을 달성하는 더 좋은 방법 일뿐입니다.

-v volume_name:/container/fs/pathDocker 로 컨테이너를 만들면 다음을 수행 할 수있는 명명 된 볼륨이 자동으로 생성됩니다.

  1. 를 통해 나열 docker volume ls
  2. 를 통해 식별 docker volume inspect volume_name
  3. 일반 디렉토리로 백업
  4. --volumes-from연결을 통해 이전과 같이 백업

새로운 볼륨 API는 매달려있는 볼륨을 식별 할 수있는 유용한 명령을 추가합니다.

docker volume ls -f dangling=true

그런 다음 이름을 통해 제거하십시오.

docker volume rm <volume name>

@mpugach가 주석에서 밑줄을 긋 듯이 멋진 원 라이너로 모든 매달려있는 볼륨을 제거 할 수 있습니다.

docker volume rm $(docker volume ls -f dangling=true -q)
# Or using 1.13.x
docker volume prune

도커 1.8.x 이하

프로덕션에 가장 적합한 방법은 데이터 전용 컨테이너 를 사용하는 것 입니다.

데이터 전용 컨테이너는 베어 본 이미지에서 실행되며 실제로 데이터 볼륨을 노출하는 것 외에는 아무 것도 수행하지 않습니다.

그런 다음 다른 컨테이너를 실행하여 데이터 컨테이너 볼륨에 액세스 할 수 있습니다.

docker run --volumes-from data-container some-other-container command-to-execute
  • 여기서 다른 용기를 배열하는 방법에 대한 좋은 그림을 얻을 수 있습니다.
  • 여기에 볼륨의 작동 방법에 대한 좋은 통찰력이있다.

에서는 블로그 게시물 소위 잘 설명가 볼륨 패턴 용기 갖는 요점 명확히 데이터 만 용기 .

Docker 설명서에는 컨테이너에 대한 명확한 설명이 볼륨 / 패턴으로 표시되어 있습니다.

다음은 Docker 1.8.x 이하의 백업 / 복원 절차입니다.

지원:

sudo docker run --rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
  • --rm : 컨테이너가 나올 때 컨테이너를 제거합니다
  • --volumes-from DATA : DATA 컨테이너가 공유하는 볼륨에 연결
  • -v $ (pwd) : / backup : 컨테이너에 현재 디렉토리를 바인드 마운트합니다. tar 파일을
  • busybox : 작고 간단한 이미지-빠른 유지 보수에 적합
  • tar cvf /backup/backup.tar / data : / data 디렉토리에있는 모든 파일의 압축되지 않은 tar 파일을 만듭니다.

복원:

# Create a new data container
$ sudo docker run -v /data -name DATA2 busybox true
# untar the backup files into the new container᾿s data volume
$ sudo docker run --rm --volumes-from DATA2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
data/
data/sven.txt
# Compare to the original container
$ sudo docker run --rm --volumes-from DATA -v `pwd`:/backup busybox ls /data
sven.txt

다음은 컨테이너 및 데이터 컨테이너에 동일한 이미지를 사용하는 것이 좋은 이유를 설명 하는 우수한 Brian Goff 의 멋진 기사입니다 .


8
다른 요구에 대한 다른 도구입니다. --volumes-from디스크 공간 --link을 공유하면 서비스를 공유 할 수 있습니다.
tommasop

3
이런 종류의 일을 위해 특별히 고안된 작품에 다른 프로젝트가 있습니까? 아마도이 답변 에이 시계를 참조로 추가 할 수 있습니까? github.com/ClusterHQ/flocker
Andre

9
데이터 컨테이너는 의미가 없으며 실제로 나쁜 생각입니다! 컨테이너는 프로세스가 실행 중일 때만 무언가를 의미하며, 그렇지 않으면 호스트 파일 시스템 일뿐입니다. 유일하고 최상의 옵션 인 -v를 사용하여 볼륨을 마운트 할 수 있습니다. 사용하는 파일 시스템 및 물리 디스크를 제어 할 수 있습니다.
Boynux

11
그러나 Docker 1.9부터는 Volumes API ( docker volume create --name mydata)로 명명 된 볼륨을 생성 하는 것이 데이터 볼륨 컨테이너보다 선호됩니다. Docker 직원 "데이터 볼륨 컨테이너 가 더 이상 권장되는 패턴으로 간주되지 않습니다 ", " 명명 된 볼륨은 대부분의 경우에 데이터 전용 볼륨을 대체 할 수 있어야합니다 "및 " 사용할 이유가 없다 "고 제안 합니다. 데이터 전용 컨테이너
Quinn Comendant

8
@coding, 나는 당신이 슬프다. 슬프다. 부분적으로 당신은 3 년의 지연으로 답을 판단하기 때문이며 부분적으로 그 답은 모든 역사에서 옳기 때문이다. 당신은 어떤 조언이 있다면 내가 대답을 통합 할 수 있습니다 도움 사람들이 슬퍼하지 않는 것이 너무 의견을 주시기 바랍니다
tommasop

75

에서 부두 노동자 릴리스 V1.0 , A는 주어진 명령을 수행 할 수있는 호스트 컴퓨터에있는 파일이나 디렉토리의 마운트 바인딩 :

$ docker run -v /host:/container ...

위의 볼륨은 Docker를 실행하는 호스트에서 영구 저장소로 사용될 수 있습니다.


3
이 순간에 더 많은 표를 가지고있는 볼륨 컨테이너 접근 방식보다 훨씬 덜 복잡 이것은 권장 대답해야한다
insitusec

2
이 볼륨 마운트 명령을 사용할 때 host-uid : container-uid 및 host-gid : container-gid 매핑을 지정하는 플래그가 있었으면합니다.
rampion

35

Docker Compose 1.6부터 Docker Compose의 데이터 볼륨에 대한 지원이 개선되었습니다. 다음 작성 파일은 상위 컨테이너를 다시 시작하거나 제거 할 때까지 지속되는 데이터 이미지를 작성합니다.

블로그 발표는 다음과 같습니다. Compose 1.6 : 네트워크 및 볼륨을 정의하기위한 새로운 Compose 파일

다음은 작성 파일의 예입니다.

version: "2"

services:
  db:
    restart: on-failure:10
    image: postgres:9.4
    volumes:
      - "db-data:/var/lib/postgresql/data"
  web:
    restart: on-failure:10
    build: .
    command: gunicorn mypythonapp.wsgi:application -b :8000 --reload
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    links:
      - db

volumes:
  db-data:

내가 이해할 수있는 한 : 이것은 db_data재시작 할 때까지 지속되는 데이터 볼륨 컨테이너 ( )를 만듭니다 .

다음을 실행 docker volume ls하면 볼륨이 표시됩니다.

local               mypthonapp_db-data
...

데이터 볼륨에 대한 자세한 내용을 얻을 수 있습니다.

docker volume inspect mypthonapp_db-data
[
  {
    "Name": "mypthonapp_db-data",
    "Driver": "local",
    "Mountpoint": "/mnt/sda1/var/lib/docker/volumes/mypthonapp_db-data/_data"
  }
]

일부 테스트 :

# Start the containers
docker-compose up -d

# .. input some data into the database
docker-compose run --rm web python manage.py migrate
docker-compose run --rm web python manage.py createsuperuser
...

# Stop and remove the containers:
docker-compose stop
docker-compose rm -f

# Start it back up again
docker-compose up -d

# Verify the data is still there
...
(it is)

# Stop and remove with the -v (volumes) tag:

docker-compose stop
docker=compose rm -f -v

# Up again ..
docker-compose up -d

# Check the data is still there:
...
(it is).

노트:

  • volumes블록 에서 다양한 드라이버를 지정할 수도 있습니다 . 예를 들어 db_data에 Flocker 드라이버를 지정할 수 있습니다.

    volumes:
      db-data:
        driver: flocker
    
  • Docker Swarm과 Docker Compose 간의 통합을 개선하고 Flocker를 Docker 에코 시스템에 통합하기 시작할 수 있습니다 (Docker가 Flocker를 구입했다는 소문을 들었습니다).

면책 조항 : 이 접근법은 유망하며 개발 환경에서 성공적으로 사용하고 있습니다. 아직 프로덕션 환경에서이 제품을 사용하는 것이 좋습니다!



17

Docker 1.9부터 선택한 답변의 업데이트 5에서 명확하지 않은 경우 특정 컨테이너와 연결되지 않고 존재할 수있는 볼륨을 생성 할 수 있으므로 "데이터 전용 컨테이너"패턴이 더 이상 사용되지 않습니다.

docker 1.9.0에서 더 이상 사용되지 않는 데이터 전용 컨테이너를 참조하십시오 . # 17798 .

Docker 관리자는 데이터 전용 컨테이너 패턴이 약간 냄새가 났으며 볼륨을 관련 컨테이너없이 존재할 수있는 별도의 엔티티로 만들기로 결정했다고 생각합니다.


13

이것은 여전히 약간의 작업이 필요한 Docker의 일부이지만 VOLUME 명령으로 볼륨을 Dockerfile에 넣어야 하므로 다른 컨테이너에서 볼륨을 복사 할 필요가 없습니다.

그러면 컨테이너의 상호 의존성이 줄어들고 한 컨테이너가 다른 컨테이너에 영향을 미치는 것을 삭제할 필요가 없습니다.


반대측 주장은 "데이터 전용"컨테이너가 데이터 볼륨에 대한 마지막 리조트 참조가된다는 것입니다 (Docker는 해당 볼륨을 참조하는 마지막 컨테이너가로 볼륨을 제거하면 데이터 볼륨을 삭제합니다 docker rm)
WineSoaked

2
Docker의이 oficial 안내서는 다음과 같이 제안합니다. docs.docker.com/userguide/dockervolumes/… "데이터 볼륨은 컨테이너의 수명주기에 관계없이 데이터를 유지하도록 설계되었으므로 컨테이너를 제거 할 때 볼륨이 자동으로 삭제되지 않습니다. "컨테이너가 더 이상 참조하지 않는"가비지 수집 "볼륨
Alex

12

사용하는 경우 도커 작성을 간단하게 예를 들어, 명명 된 볼륨을 첨부 :

version: '2'
services:
  db:
    image: mysql:5.6
    volumes:
      - db_data:/var/lib/mysql:rw
    environment:
      MYSQL_ROOT_PASSWORD: root
volumes:
  db_data:

9

@tommasop의 대답은 훌륭하며 데이터 전용 컨테이너를 사용하는 메커니즘에 대해 설명합니다. 그러나 처음에 데이터 컨테이너가 어쩌면 볼륨을 호스트에 바인드 할 수있을 때 바보라고 생각한 사람 (몇 가지 다른 대답에서 제안한 것처럼) 이제 실제로 데이터 전용 컨테이너가 매우 깔끔하다는 것을 알고 있습니다. 이 주제에 대한 블로그 게시물 : Docker 데이터 컨테이너 (볼륨!)가 좋은 이유

참조 : 내 대답 질문에 "이 도커 공유 볼륨에 대한 사용 권한을 관리 할 수있는 (가장 좋은) 방법은 무엇입니까? "호스트와의 권한과 UID / GID 매핑 등의 문제를 방지하기 위해 데이터 컨테이너를 사용하는 방법의 예를 들어.

OP의 원래 관심사 중 하나를 해결하려면 데이터 컨테이너를 삭제해서는 안됩니다. 데이터 컨테이너가 삭제 된 경우에도 컨테이너에 해당 볼륨에 대한 참조가있는 한 데이터 자체는 손실되지 않습니다. 즉,를 통해 볼륨을 마운트 한 컨테이너입니다 --volumes-from. 따라서 모든 관련 컨테이너가 중지되고 삭제되지 않는 한 (이것은 우연한 것으로 간주 될 수 있음 rm -fr /) 데이터는 안전합니다. 다음을 수행하여 항상 데이터 컨테이너를 다시 만들 수 있습니다--volumes-from해당 볼륨에 대한 참조가있는 .

항상 그렇듯이 백업하십시오!

업데이트 : Docker에는 이제 컨테이너와 독립적으로 관리 할 수있는 볼륨이있어 관리가 더 쉽습니다.


9

필요에 따라 여러 수준의 영구 데이터 관리가 있습니다.

  • 호스트에 저장
    • -v host-path:container-path컨테이너 디렉토리 데이터를 호스트 디렉토리에 유지 하려면 플래그 를 사용하십시오 .
    • 백업 / 복원은 동일한 디렉토리에 마운트 된 백업 / 복원 컨테이너 (예 : tutumcloud / dockup)를 실행하여 발생합니다.
  • 데이터 컨테이너를 작성하고 볼륨을 애플리케이션 컨테이너에 마운트하십시오.
    • 데이터 볼륨을 내보내는 컨테이너를 만들고 --volumes-from 해당 데이터를 애플리케이션 컨테이너에 마운트하는 데 하십시오.
    • 위의 솔루션과 동일하게 백업 / 복원합니다.
  • 외부 / 타사 서비스를 지원하는 Docker 볼륨 플러그인 사용
    • Docker 볼륨 플러그인을 사용하면 어디서나 데이터 소스를 가져올 수 있습니다 (NFS, AWS (S3, EFS 및 EBS)).
    • 플러그인 / 서비스에 따라 단일 또는 여러 컨테이너를 단일 볼륨에 연결할 수 있습니다.
    • 서비스에 따라 백업 / 복원이 자동으로 수행 될 수 있습니다.
    • 이 작업은 수동으로 수행하기가 번거로울 수 있지만 Rancher 와 같은 일부 오케스트레이션 솔루션 은 구워서 사용하기 간단합니다.
    • Convoy 는이 작업을 수동으로 수행하는 가장 쉬운 솔루션입니다.

8

볼륨을 옮기려면 Flocker 도 살펴 보십시오 .

읽어보기에서 :

Flocker는 데이터 볼륨 관리자 및 다중 호스트 Docker 클러스터 관리 도구입니다. 이를 통해 Linux에서 ZFS의 기능을 활용하여 상태 비 저장 응용 프로그램에 사용하는 것과 동일한 도구를 사용하여 데이터를 제어 할 수 있습니다.

즉, Docker에서 데이터베이스, 대기열 및 키 값 저장소를 실행하고 나머지 응용 프로그램처럼 쉽게 이동할 수 있습니다.


1
고마워요 ClusterHQ에서 일하고 ZFS 기반 스토리지만을 넘어 섰다는 점에 주목하고 싶었습니다. 이제 Amazon EBS 또는 Google 영구 디스크와 같은 스토리지에서 Flocker를 사용할 수 있습니다. 여기에 스토리지 옵션의 전체 목록은 다음과 같습니다 docs.clusterhq.com/en/latest/supported/...
ferrantim

1
Flocker는 종료되었으며 사용해서는 안됩니다 portworx.com/…
jesugmz

5

시나리오에 따라 다르지만 (실제로 프로덕션 환경에는 적합하지 않음) 한 가지 방법이 있습니다.

MySQL Docker 컨테이너 생성

이것의 요지는 데이터 지속성을 위해 호스트의 디렉토리를 사용하는 것입니다.


6
그러나 감사합니다 벤-이 접근법으로 볼 수있는 문제 중 하나 : 파일 시스템 리소스 (디렉토리, 파일)는 docker / lxc 컨테이너 (게스트) 내에서 uid가 소유합니다-uid와 충돌 할 수있는 것 호스트에 ...
juwalter

1
나는 루트로 실행되기 때문에 꽤 안전하다고 생각하지만 그것이 로컬 개발자 / 임시 통합 테스트에 적합하다는 것은 해킹에 동의합니다. 이것은 분명히 더 많은 패턴 / 사고가 나타나기를 바라는 영역입니다. 당신은 / 체크 아웃 고정 표시기-dev에 구글 그룹이 질문에 게시한다
벤 슈워츠

벤,이 솔루션에 감사드립니다! 나는 그것을 해킹이라고 부르지 않을 것이다. 그것은 컨테이너 보다 볼륨 보다 훨씬 신뢰할 만하다 . 컨테이너에서만 데이터를 사용하는 경우 단점이 있습니까? (이 경우 UID는 중요하지 않습니다)
johndodo



0

내 해결책은 new를 사용하는 것입니다. docker cp이는 데이터 실행 여부와 상관없이 컨테이너에서 데이터를 복사하고 데이터베이스 응용 프로그램이 컨테이너 내부에서 데이터베이스 파일을 생성하는 정확한 위치와 호스트 볼륨을 공유 할 수 있습니다. . 이 이중 솔루션은 원래 데이터베이스 컨테이너에서 직접 데이터 전용 컨테이너없이 작동합니다.

그래서 systemd init 스크립트는 데이터베이스를 호스트의 아카이브로 백업하는 작업을 수행합니다. 파일을 다시 쓰지 않기 위해 파일 이름에 타임 스탬프를 넣었습니다.

ExecStartPre에서 수행하고 있습니다.

ExecStartPre=-/usr/bin/docker cp lanti-debian-mariadb:/var/lib/mysql /home/core/sql
ExecStartPre=-/bin/bash -c '/usr/bin/tar -zcvf /home/core/sql/sqlbackup_$$(date +%%Y-%%m-%%d_%%H-%%M-%%S)_ExecStartPre.tar.gz /home/core/sql/mysql --remove-files'

그리고 ExecStopPost에서도 동일한 작업을 수행합니다.

ExecStopPost=-/usr/bin/docker cp lanti-debian-mariadb:/var/lib/mysql /home/core/sql
ExecStopPost=-/bin/bash -c 'tar -zcvf /home/core/sql/sqlbackup_$$(date +%%Y-%%m-%%d_%%H-%%M-%%S)_ExecStopPost.tar.gz /home/core/sql/mysql --remove-files'

또한 호스트의 폴더를 볼륨으로 데이터베이스가 저장된 정확한 위치에 노출했습니다.

mariadb:
  build: ./mariadb
  volumes:
    - $HOME/server/mysql/:/var/lib/mysql/:rw

내 VM에서 잘 작동합니다 (자신을 위해 LEMP 스택을 작성합니다) : https://github.com/DJviolin/LEMP

그러나 나는 그것이 당신의 삶이 실제로 그것에 의존 할 때 (예 : 가능한 밀리 초 단위의 거래가있는 웹샵) "방탄"솔루션인지 모르겠습니다.

이 공식 Docker 기조 연설 비디오에서 20 분 20 초에 발표자는 데이터베이스와 동일한 작업을 수행합니다.

Docker 시작하기

"데이터베이스에는 볼륨이 있으므로 데이터베이스가 올라가거나 내려갈 때 데이터베이스 컨테이너가 중지 될 때 데이터를 잃지 않도록 할 수 있습니다."


"... get use ..."은 무슨 뜻 입니까? 그리고 "... 가능한 모든 밀리 초 단위의 트랜잭션" ?
피터 Mortensen

0

Docker 컨테이너 관리 및 예약 도구 인 Kubernetes의 PVC (Persistent Volume Claim)를 사용하십시오.

영구 볼륨

이 목적으로 Kubernetes를 사용하면 다음과 같은 이점이 있습니다.

  • NFS 또는 다른 스토리지와 같은 스토리지를 사용할 수 있으며 노드가 다운 된 경우에도 스토리지가 필요하지 않습니다.
  • 또한 이러한 볼륨의 데이터는 컨테이너 자체가 파괴 된 후에도 유지되도록 구성 할 수 있으므로 필요한 경우 다른 컨테이너에서 데이터를 회수 할 수 있습니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.