code

Docker Swarm은 볼륨 공유를 어떻게 구현합니까?

codestyles 2020. 11. 2. 08:00
반응형

Docker Swarm은 볼륨 공유를 어떻게 구현합니까?


Docker Swarm은 볼륨 및 바인딩의 두 가지 유형의 스토리지를 관리 할 수 ​​있습니다. Docker Documentation에서 bind는 작업에 대한 로컬 디렉터리 (각 웜 노드의) 사이에 바인딩을 생성하기 때문에 제안하지 않지만 볼륨 메서드 구현은 언급되지 않았으므로 작업간에 볼륨이 공유되는 방식을 이해하지 못합니다.

Docker Swarm은 노드간에 볼륨을 어떻게 공유합니까? 볼륨은 어디에 저장됩니까 (관리자에? 그리고 둘 이상의 관리가있는 경우?)?

다른 네트워크의 다른 컴퓨터에서 실행되는 경우 노드간에 문제가 없습니까? VPN을 생성합니까?


당신이 묻는 것은 일반적인 질문입니다. 볼륨 데이터와 해당 볼륨이 수행 할 수있는 기능은 볼륨 드라이버에서 관리합니다. 당신이 같은 다른 네트워크 드라이버를 사용할 수있는 것처럼 overlay, bridge또는 host, 당신은 다른 볼륨 드라이버를 사용할 수 있습니다.

Docker 및 Swarm은 기본 local드라이버 와 함께 제공됩니다 . Swarm을 인식하지 못하며 서비스 작업이 예약 된 노드에 데이터에 대한 새 볼륨을 생성합니다. 이것은 일반적으로 원하는 것이 아닙니다.

Swarm을 인식하고 서비스 작업을 위해 생성 한 볼륨을 적시에 올바른 노드에서 사용할 수있는 타사 드라이버 플러그인을 원합니다. 옵션에는 "Docker for AWS / Azure"및 포함 된 CloudStor 드라이버 또는 인기있는 오픈 소스 REX-Ray 솔루션 사용이 포함됩니다.

Docker Store 에서 찾을 수있는 타사 볼륨 드라이버가 많이 있습니다 .


Swarm 모드 자체는 볼륨에 대해 다른 작업을 수행하지 않으며 컨테이너가 실행중인 노드에서 제공하는 모든 볼륨 마운트 명령을 실행합니다. 볼륨 마운트가 해당 노드에 로컬이면 데이터가 해당 노드에 로컬로 저장됩니다. 노드간에 데이터를 자동으로 이동하는 기본 제공 기능이 없습니다.

GlusterFS와 같은 일부 소프트웨어 기반 분산 스토리지 솔루션이 있으며 Docker에는 아직 GA되지 않은 Infinit이라는 솔루션이 있으며 EE의 Kubernetes 통합으로 뒷자리를 차지한 개발이 있습니다.

일반적인 결과는 애플리케이션 내에서 스토리지 복제를 관리해야하거나 (예 : etcd 및 기타 뗏목 기반 알고리즘) 외부 스토리지 시스템에서 마운트를 수행해야합니다 (자신의 HA를 사용하여). 외부 스토리지 시스템 마운트에는 블록 또는 파일 기반의 두 가지 옵션이 있습니다. 블록 기반 스토리지 (예 : EBS)는 일반적으로 더 높은 성능을 제공하지만 단일 노드에만 마운트되도록 제한됩니다. 이를 위해 일반적으로 해당 블록 스토리지에 대한 도커 노드 액세스를 제공하기 위해 타사 볼륨 플러그인 드라이버가 필요합니다. 파일 기반 저장소 (예 : EFS)는 성능이 낮지 만 이식성이 더 높으며 여러 노드에 동시에 마운트 할 수 있으므로 복제 된 서비스에 유용합니다.

가장 일반적인 파일 기반 네트워크 저장소는 NFS (EFS에서 사용하는 것과 동일한 프로토콜)입니다. 타사 플러그인 드라이버 없이도 마운트 할 수 있습니다. 유감스럽게도 docker와 함께 제공되는 "local"볼륨 플러그인 드라이버는 드라이버 옵션을 사용하여 mount 명령에 원하는 값을 전달할 수있는 옵션을 제공하며 옵션없이 기본적으로 docker 디렉토리 / var / lib /에 볼륨을 저장합니다. 도커 / 볼륨. 옵션을 사용하면 NFS 매개 변수를 전달할 수 있으며 NFS 호스트 이름 (일반적으로 NFS에는없는 것)에 대한 DNS 조회도 수행합니다. 다음은 로컬 볼륨 드라이버를 사용하여 NFS 파일 시스템을 마운트하는 다양한 방법의 예입니다.

  # create a reusable volume
  $ docker volume create --driver local \
      --opt type=nfs \
      --opt o=nfsvers=4,addr=192.168.1.1,rw \
      --opt device=:/path/to/dir \
      foo

  # or from the docker run command
  $ docker run -it --rm \
    --mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=nfs,\"volume-opt=o=nfsvers=4,addr=192.168.1.1\",volume-opt=device=:/host/path \
    foo

  # or to create a service
  $ docker service create \
    --mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=nfs,\"volume-opt=o=nfsvers=4,addr=192.168.1.1\",volume-opt=device=:/host/path \
    foo

  # inside a docker-compose file
  ...
  volumes:
    nfs-data:
      driver: local
      driver_opts:
        type: nfs
        o: nfsvers=4,addr=192.168.1.1,rw
        device: ":/path/to/dir"
  ...

작동하는 AWS EFS 용 솔루션 :

  1. EFS 생성 (보안 그룹에서 NFS 포트 2049를 여는 것을 잊지 마십시오)
  2. nfs-common 패키지를 설치합니다.

    sudo apt-get install -y nfs-common

  3. Check if your efs works:

    mkdir efs-test-point
    sudo chmod go+rw efs-test-point
    sudo mount -t nfs -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport [YOUR_EFS_DNS]:/ efs-test-point
    touch efs-test-point/1.txt
    sudo umount efs-test-point/
    ls -la efs-test-point/

    directory must be empty

    sudo mount -t nfs -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport [YOUR_EFS_DNS]:/ efs-test-point

    ls -la efs-test-point/

    file 1.txt must exists

  4. Configure docker-compose.yml file:

    services:
      sidekiq:
        volumes:
          - uploads_tmp_efs:/home/application/public/uploads/tmp
      ...
    volumes:
      uploads_tmp_efs:
        driver: local
        driver_opts:
          type: nfs
          o: addr=[YOUR_EFS_DNS],nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2
          device: [YOUR_EFS_DNS]:/


After searching in the documentation and in the docker discussions I was able to find the following information regarding this problem:

  • bind mounting a host-directory in a container (docker run -v /some/host/dir/:/container/path/) uses the files that are present on the host. If the host-directory doesn't exist, a new, empty directory is created on the host and mounted in the container (this will change in future, and an error is shown instead)
  • using a "nameless" volume (docker run -v /container/path) will create a new volume, and copy the contents of /container/path into that volume
  • using a "named" volume (docker run -v somename:/container/path) will create a new volume, named "somename", or use the existing "somename" volume, and use the files that are present inside that volume. If the volume is newly created, it will be empty.

Source: Discussion on Github

The reason for all this is:

It's not a bug, it acted as that because it should do that. For the anonymous volume, docker knows that the volumes is fully controlled by itself, so docker can do anythings it thinks correct(Here is copying files in image to the volume). But the named volume is designed for the volume plugin, so docker does not know what it should do, and does nothing.

Source: Related discussion on Github

So you have to use a Volume driver which supports that which indeed can be found at the docker store

참고URL : https://stackoverflow.com/questions/47756029/how-does-docker-swarm-implement-volume-sharing

반응형