Docker와 공유되는 호스트 볼륨에 NFS 디렉터리를 마운트합니다.

Docker와 공유되는 호스트 볼륨에 NFS 디렉터리를 마운트합니다.

다음 Docker 컨테이너를 고려해보세요.

docker run --rm -it -v /tmp:/mnt/tmp alpine sh

그러면 호스트 디렉터리 /tmp가 알파인 컨테이너 내부의 /mnt/tmp에 마운트됩니다.

이제 호스트 시스템에서 NFS 볼륨을 /tmp 디렉터리에 마운트합니다.

mkdir /tmp/nfs
mount -t nfs4 192.168.1.100:/data /tmp/nfs

설치가 호스트 시스템에서 실행되고 다음이 표시됩니다.

# ls /tmp/nfs
file1 file2 file3
#

하지만 Docker 컨테이너에는 빈 디렉터리가 있습니다.

# ls /mnt/tmp/nfs
#

Docker 컨테이너에 직접 마운트하면 이 문제를 해결할 수 있다는 것을 알고 있습니다. 하지만 마운트가 호스트 컨테이너에서는 작동하지만 Docker 컨테이너에서는 작동하지 않는 이유를 정말로 알고 싶습니다.

답변1

이는 볼륨이 private마운트 전파를 사용하고 있기 때문에 발생합니다. 즉, 마운트가 발생하면 소스 측(예: Docker의 "호스트" 측)에서 발생하는 모든 변경 사항이 마운트 아래에 표시되지 않습니다.

이 문제를 처리하는 방법에는 여러 가지가 있습니다.

  1. NFS를 먼저 마운트한 후 컨테이너를 시작합니다. 마운트는 컨테이너에 전파되지만 이전과 마찬가지로 마운트에 대한 변경 사항(마운트 해제 포함)은 컨테이너에 표시되지 않습니다.

  2. "하위" 전파를 사용합니다. 즉, 마운트가 생성되면 소스(Docker 호스트)에 대한 모든 변경 사항이 대상(컨테이너)에 표시됩니다. 중첩 설치를 수행하는 경우 rslave( r재귀)를 사용하는 것이 좋습니다.

"공유" 통신도 있습니다. 이 모드를 사용하면 마운트 지점 변경 사항이 컨테이너 내부에서 호스트로 또는 그 반대로 전파됩니다. 귀하의 사용자는 그러한 변경을 수행할 권한조차 없기 때문에(CAP_SYS_ADMIN을 추가하지 않는 한) 이는 아마도 귀하가 원하는 것이 아닐 것입니다.

다음과 같이 설치를 생성할 때 전파 모드를 설정할 수 있습니다.

$ docker run -v /foo:/bar:private

또 다른 옵션은 호스트 마운트 대신 볼륨을 사용하는 것입니다. 다음을 수행할 수 있습니다.

$ docker volume create \
    --name mynfs \
    --opt type=nfs \
    --opt device=:<nfs export path> \
    --opt o=addr=<nfs host> \
    mynfs
$ docker run -it -v mynfs:/foo alpine sh

이렇게 하면 특정 방식으로 호스트를 설정하거나 마운트 전파를 처리하지 않고도 항상 컨테이너에 마운트가 수행됩니다.
노트: :장치 경로 앞부분이 필수인데 nfs 커널 모듈이 좀 이상하네요.
노트: Docker는 현재 <nfs host>DNS 이름을 확인할 수 없으므로(1.13에 있을 예정임) 여기에 IP 주소를 제공해야 합니다.

"공유 하위 트리" 설치에 대한 자세한 내용:https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt

답변2

볼륨 매개변수 끝에 :shared 플래그를 추가하여 볼륨에서 공유 마운트 전파를 활성화합니다.

docker run --rm -it -v /tmp:/mnt/tmp:shared alpine sh

Docker가 패키지 관리자 또는 systemd 설치 스크립트를 통해 설치된 경우 MountFlags 데몬 매개변수를 조정해야 할 수도 있습니다. 이렇게 하려면 docker.service 파일을 찾으세요.

$ sudo find /etc -name "docker.service"

내 Ubuntu 16.04에서는 /etc/systemd/system/multi-user.target.wants/docker.service에 있습니다. vi 또는 nano를 사용하여 이 파일을 편집하고 MountFlags 옵션이 다음과 같은지 확인하십시오.

MountFlags=shared

파일을 저장하고 데몬 매개변수를 다시 로드한 후 Docker를 다시 시작합니다.

$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

이제 "docker run"을 사용할 때 볼륨에 공유 마운트 전파 플래그를 설정할 수 있습니다.

답변3

docker 17.06부터 런타임은 추가 기능 없이 NFS 공유를 컨테이너에 직접 마운트할 수 있습니다.

export NFS_VOL_NAME=mynfs NFS_LOCAL_MNT=/mnt/mynfs NFS_SERVER=my.nfs.server.com NFS_SHARE=/my/server/path NFS_OPTS=vers=4,soft

docker run --mount \
  "src=$NFS_VOL_NAME,dst=$NFS_LOCAL_MNT,volume-opt=device=:$NFS_SHARE,\"volume-opt=o=addr=$NFS_SERVER,$NFS_OPTS\",type=volume,volume-driver=local,volume-opt=type=nfs" \
  busybox ls $NFS_LOCAL_MNT

또는 컨테이너보다 먼저 볼륨을 생성할 수 있습니다.

docker volume create --driver local \
  --opt type=nfs --opt o=addr=$NFS_SERVER,$NFS_OPTS \
  --opt device=:$NFS_SHARE $NFS_VOL_NAME

docker run --rm -v $NFS_VOL_NAME:$NFS_LOCAL_MNT busybox ls $NFS_LOCAL_MNT

팁을 얻다 https://github.com/moby/moby/issues/28809

관련 정보