일반적으로 호스트 볼륨 마운트와 관련된 권한 문제는 컨테이너 내의 uid / gid가 호스트에있는 파일의 uid / gid 권한에 따라 파일에 액세스 할 수 없기 때문입니다. 그러나이 특정 사례는 다릅니다.
권한 문자열의 끝에있는 점 drwxr-xr-x.
은 SELinux가 구성되었음을 나타냅니다. SELinux와 함께 호스트 마운트를 사용하는 경우 볼륨 정의 끝에 추가 옵션을 전달해야합니다.
- 그만큼
z
옵션은 바인드 마운트 컨텐츠가 여러 컨테이너간에 공유됨을 나타냅니다.
- 이
Z
옵션은 바인드 마운트 컨텐츠가 개인용이며 공유되지 않음을 나타냅니다.
그러면 볼륨 마운트 명령은 다음과 같습니다.
sudo docker run -i -v /data1/Downloads:/Downloads:z ubuntu bash
SELinux를 사용한 호스트 마운트에 대한 자세한 내용은 https://docs.docker.com/storage/#configure-the-selinux-label을 참조하십시오.
다른 사용자로 실행중인 컨테이너에서이 문제가 발생하는 다른 사용자의 경우 컨테이너 내부 사용자의 uid / gid에 호스트의 파일에 대한 권한이 있는지 확인해야합니다. 프로덕션 서버에서는 이미지 빌드 프로세스에서 uid / gid를 제어하여 파일에 액세스 할 수있는 호스트의 uid / gid와 일치 시키거나 프로덕션 환경에서 호스트 마운트를 사용하지 않는 경우가 종종 있습니다.
명명 된 볼륨은 파일 소유권 및 권한을 포함하여 이미지 디렉토리에서 볼륨 디렉토리를 초기화하므로 마운트를 호스트하는 것이 선호됩니다. 이것은 볼륨이 비어 있고 명명 된 볼륨으로 컨테이너가 생성 될 때 발생합니다.
MacOS 사용자는 이제 OSXFS를 습니다 Mac 호스트와 컨테이너 사이에서 자동으로 uid / gid를 처리하는 를 . 도움이되지 않는 곳은 /var/lib/docker.sock과 같이 컨테이너에 마운트 된 내장 VM 내부의 파일입니다.
호스트 uid / gid가 개발자마다 변경 될 수있는 개발 환경의 경우 선호되는 솔루션은 루트로 실행되는 진입 점으로 컨테이너를 시작하고 컨테이너 내 사용자의 uid / gid를 호스트 볼륨 uid / gid와 일치하도록 수정하는 것입니다. 그런 다음 gosu
루트에서 컨테이너 사용자에게 드롭하여 컨테이너 내부에서 애플리케이션을 실행하십시오. 이것에 대한 중요한 스크립트는 fix-perms
내 기본 이미지 스크립트에 있으며 https://github.com/sudo-bmitch/docker-base에 있습니다.
fix-perms
스크립트 에서 중요한 부분 은 다음과 같습니다.
# update the uid
if [ -n "$opt_u" ]; then
OLD_UID=$(getent passwd "${opt_u}" | cut -f3 -d:)
NEW_UID=$(stat -c "%u" "$1")
if [ "$OLD_UID" != "$NEW_UID" ]; then
echo "Changing UID of $opt_u from $OLD_UID to $NEW_UID"
usermod -u "$NEW_UID" -o "$opt_u"
if [ -n "$opt_r" ]; then
find / -xdev -user "$OLD_UID" -exec chown -h "$opt_u" {} \;
fi
fi
fi
컨테이너 내 사용자의 uid와 파일의 uid를 가져오고 일치하지 않으면 usermod
uid를 조정하기 위해 호출 합니다. 마지막으로 uid를 변경하지 않은 파일을 수정하기 위해 재귀 찾기를 수행합니다. -u $(id -u):$(id -g)
위의 엔트리 포인트 코드는 각 개발자가 컨테이너를 시작하기 위해 스크립트를 실행할 필요가 없으며 사용자가 소유 한 볼륨 외부의 파일은 권한이 수정되므로 플래그 로 컨테이너를 실행하는 것보다 낫습니다 .
바인드 마운트를 수행하는 명명 된 볼륨을 사용하여 이미지에서 docker가 호스트 디렉토리를 초기화하도록 할 수도 있습니다. 이 디렉토리는 미리 존재해야하며 상대 경로 일 수있는 작성 파일의 호스트 볼륨과 달리 호스트 디렉토리의 절대 경로를 제공해야합니다. 도 커가 디렉토리를 초기화하려면 디렉토리도 비어 있어야합니다. 바인드 마운트에 이름 지정된 볼륨을 정의하는 세 가지 옵션은 다음과 같습니다.
# create the volume in advance
$ docker volume create --driver local \
--opt type=none \
--opt device=/home/user/test \
--opt o=bind \
test_vol
# create on the fly with --mount
$ docker run -it --rm \
--mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=none,volume-opt=o=bind,volume-opt=device=/home/user/test \
foo
# inside a docker-compose file
...
volumes:
bind-test:
driver: local
driver_opts:
type: none
o: bind
device: /home/user/test
...
마지막으로, 사용자 네임 스페이스를 사용하려고하면 컨테이너의 uid / gid가 이동되므로 호스트 볼륨에 권한 문제가있는 것을 알 수 있습니다. 이 시나리오에서는 호스트 볼륨을 피하고 명명 된 볼륨 만 사용하는 것이 가장 쉬운 방법입니다.