code

도커의 호스트 디렉토리에 액세스할 때 사용 권한이 거부되었습니다.

starcafe 2023. 8. 11. 22:26
반응형

도커의 호스트 디렉토리에 액세스할 때 사용 권한이 거부되었습니다.

Docker에 호스트 디렉토리를 마운트하려고 하지만 액세스 권한이 양호한 것처럼 보이더라도 컨테이너 내에서 호스트 디렉토리에 액세스할 수 없습니다.

하고 있습니다

sudo docker run -i -v /data1/Downloads:/Downloads ubuntu bash

그리고 나서.

ls -al

다음과 같은 이점이 있습니다.

total 8892
drwxr-xr-x.  23 root root    4096 Jun 18 14:34 .
drwxr-xr-x.  23 root root    4096 Jun 18 14:34 ..
-rwxr-xr-x.   1 root root       0 Jun 18 14:34 .dockerenv
-rwx------.   1 root root 9014486 Jun 17 22:09 .dockerinit
drwxrwxr-x.  18 1000 1000   12288 Jun 16 11:40 Downloads
drwxr-xr-x.   2 root root    4096 Jan 29 18:10 bin
drwxr-xr-x.   2 root root    4096 Apr 19  2012 boot
drwxr-xr-x.   4 root root     340 Jun 18 14:34 dev
drwxr-xr-x.  56 root root    4096 Jun 18 14:34 etc
drwxr-xr-x.   2 root root    4096 Apr 19  2012 home

그리고 그런 대사들이 훨씬 더 많아요 (여기가 관련된 부분인 것 같아요).

내가 하면,

cd /Downloads
ls

결과는

ls: cannot open directory .: Permission denied

호스트는 Fedora 20이고 Docker 1.0.0 및 go 1.2.2입니다.

무엇이 잘못되고 있습니까?

자세한 내용은 볼륨SELinux에 대한 Project Atomic 블로그 게시물을 참조하십시오.

구체적으로:

Docker가 Docker-1.7에 표시될 패치를 최종적으로 병합한 이후 최근에 이것은 쉬워졌습니다(우리는 RHEL, CentOS 및 Fedora에서 Docker-1.6에 패치를 전달해 왔습니다).

이 패치는 볼륨 마운트(-v)의 옵션으로 "z" 및 "Z"에 대한 지원을 추가합니다.

예:

docker run -v /var/db:/var/db:z rhel7 /bin/sh

자동으로 실행됩니다.chcon -Rt svirt_sandbox_file_t /var/db맨 페이지에 설명되어 있습니다.

더 좋은 것은, 당신은 Z를 사용할 수 있습니다.

docker run -v /var/db:/var/db:Z rhel7 /bin/sh

한 MCS 됩니다. 으로 이 은 "MCS"를 실행합니다.chcon -Rt svirt_sandbox_file_t -l s0:c1,c2 /var/dbs0:c1,c2용기마다 다릅니다.

이것은 SELinux 문제입니다.

임시로 발급할 수 있습니다.

su -c "setenforce 0"

호스트에서 액세스하거나 실행하여 SELinux 규칙을 추가합니다.

chcon -Rt svirt_sandbox_file_t /path/to/volume

일반적으로 호스트 볼륨 마운트와 관련된 사용 권한 문제는 컨테이너 내부의 UID/GID가 호스트에 있는 파일의 UID/GID 사용 권한에 따라 파일에 액세스할 수 없기 때문입니다.하지만, 이 특정한 경우는 다릅니다.

문자열의 점, 권한문의끝있점는에자열▁the,▁at점,는,drwxr-xr-x.SELinux가 구성되었음을 나타냅니다.SELinux와 함께 호스트 마운트를 사용하는 경우 볼륨 정의 끝에 추가 옵션을 전달해야 합니다.

  • z옵션은 바인딩 마운트 콘텐츠가 여러 컨테이너 간에 공유됨을 나타냅니다.
  • Z옵션은 바인딩 마운트 콘텐츠가 비공개이고 공유되지 않음을 나타냅니다.

그러면 볼륨 마운트 명령은 다음과 같습니다.

sudo docker run -i -v /data1/Downloads:/Downloads:z ubuntu bash

이 Linux 레이블 구성에서 SELinux를 사용한 호스트 마운트대한 자세한 내용을 참조하십시오.


다른 사용자로 실행 중인 컨테이너에서 이 문제가 발생하는 다른 경우에는 컨테이너 내 사용자의 UID/GID에 호스트의 파일에 대한 사용 권한이 있는지 확인해야 합니다.프로덕션 서버에서 이 작업은 종종 파일에 액세스할 수 있는 호스트의 UID/GID와 일치하도록 이미지 빌드 프로세스에서 UID/GID를 제어함으로써 수행됩니다(또는 프로덕션에서 호스트 마운트를 사용하지 않음).

명명된 볼륨은 파일 소유권 및 사용 권한을 포함하여 이미지 디렉토리에서 볼륨 디렉토리를 초기화하기 때문에 마운트를 호스트하는 것보다 선호되는 경우가 많습니다.이 문제는 볼륨이 비어 있고 명명된 볼륨으로 컨테이너가 생성된 경우에 발생합니다.

이제 macOS 사용자는 mac 호스트와 컨테이너 간에 UID/GID를 자동으로 처리하는 OSXFS를 갖게 되었습니다.한 가지 도움이 되지 않는 것은 /var/lib/docker.sock과 같이 컨테이너에 마운트되는 내장된 VM 내부의 파일입니다.

UID/될 수 개발 의 경우, UID/GID와 UID/GID를 사용하는 입니다. 제가 선호하는 솔루션은 진입점을 루트로 실행하여 컨테이너 내부의 사용자 UID/GID를 호스트 볼륨 UID/GID와 일치하도록 수정한 다음 사용하는 것입니다.gosu루트에서 컨테이너 사용자로 이동하여 컨테이너 내부에서 응용프로그램을 실행합니다.이를 위한 중요한 스크립트는 다음과 같습니다.fix-perms다음 사이트에서 찾을 수 있는 내 기본 이미지 스크립트: 브랜든 미첼의 도커 기본 이미지

에서 .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

하면 컨테이너 에서 를 호출합니다.usermodUID를 조정합니다.마지막으로 UID를 변경하지 않은 파일을 수정하기 위해 재귀적인 검색을 수행합니다.나는 이것이 컨테이너를 운영하는 것보다 더 좋습니다.-u $(id -u):$(id -g)위의 진입점 코드는 각 개발자가 컨테이너를 시작하기 위해 스크립트를 실행할 필요가 없으며 사용자가 소유한 볼륨 외부의 모든 파일은 권한이 수정되기 때문에 플래그가 지정됩니다.


또한 Docker가 바인딩 마운트를 수행하는 명명된 볼륨을 사용하여 이미지에서 호스트 디렉토리를 초기화하도록 할 수도 있습니다.이 디렉터리는 이미 존재해야 하며 상대 경로일 수 있는 합성 파일의 호스트 볼륨과 달리 호스트 디렉터리에 대한 절대 경로를 제공해야 합니다.또한 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가 이동되기 때문에 호스트 볼륨에 사용 권한 문제가 있다는 것을 알 수 있습니다.이 시나리오에서는 호스트 볼륨을 피하고 명명된 볼륨만 사용하는 것이 가장 쉬울 것입니다.

경고: 이 솔루션에는 보안 위험이 있습니다.

컨테이너를 권한이 있는 것으로 실행해 보십시오.

sudo docker run --privileged=true -i -v /data1/Downloads:/Downloads ubuntu bash

다른 옵션(시도하지 않은 경우)은 권한 있는 컨테이너를 만든 다음 그 안에 권한 없는 컨테이너를 만드는 것입니다.

access.redhat.com 에서:공유_데이터_교차_컨테이너:

호스트 볼륨 설정은 호스트 종속적이며 다른 시스템에서 작동하지 않을 수 있으므로 이동할 수 없습니다.이러한 이유로 컨테이너에 호스트 디렉토리를 마운트하기 위한 Docker 파일이 없습니다.또한 호스트 시스템에는 컨테이너 SELinux 정책에 대한 지식이 없습니다.따라서 SELinux 정책이 적용되는 경우 rw 설정에 관계없이 마운트된 호스트 디렉토리는 컨테이너에 쓸 수 없습니다.현재 적절한 SELinux 정책 유형을 호스트 디렉토리에 할당하여 이 문제를 해결할 수 있습니다."

chcon -Rt svirt_sandbox_file_t host_dir

여기서 host_dir는 컨테이너에 마운트된 호스트 시스템의 디렉토리 경로입니다.

이것은 단지 해결책인 것처럼 보이지만, 저는 노력했고 효과가 있습니다.

나는 확인했습니다.chcon -Rt svirt_sandbox_file_t /path/to/volume작동하므로 권한 있는 컨테이너로 실행할 필요가 없습니다.

실행 시간:

  • 도커 버전 0.11.1-dev, 빌드 02d20af/0.11.1
  • SELinux가 활성화된 호스트 및 컨테이너로 CentOS 7.

해라docker volume create.

mkdir -p /data1/Downloads
docker volume create --driver local --name hello --opt type=none --opt device=/data1/Downloads --opt o=uid=root,gid=root --opt o=bind
docker run -i -v hello:/Downloads ubuntu bash

문서 도커 볼륨 생성을 확인합니다.

저도 비슷한 문제가 있었습니다.내 항목은 호스트의 UID와 컨테이너 사용자의 UID가 일치하지 않아 발생했습니다.수정은 사용자의 UID를 인수로 전달하는 것이었습니다.docker build명령을 실행하여 동일한 UID를 가진 컨테이너의 사용자를 생성합니다.

도커 파일에서:

ARG UID=1000
ENV USER="ubuntu"
RUN useradd -u $UID -ms /bin/bash $USER

빌드 단계에서:

docker build <path/to/Dockerfile> -t <tag/name> --build-arg UID=$UID

그 후, OP에 따라 컨테이너와 명령어를 실행해보니 예상되는 결과가 나왔습니다.

이 문제는 시스템에서 SELinux가 사용되도록 설정되어 있기 때문입니다.아래를 확인하고 사용하지 않도록 설정합니다.

[root@nfs-server ~]# getenforce
Enforcing
[root@nfs-server ~]# setenforce 0
[root@nfs-server ~]# getenforce
Permissive

SELinux를 사용하지 않으려면 --security-opt label:disable 플래그를 사용하여 이 작업을 수행할 수 있습니다.

docker run --security-opt label:disable -v /run/docker.sock:/run/docker.sock POWERFULLCONTAINER

저는 데이터 컨테이너를 사용하여 그 문제를 해결했습니다.이는 또한 애플리케이션 계층에서 데이터를 분리할 수 있는 이점이 있습니다.다음과 같이 실행할 수 있습니다.

docker run --volumes-from=<container-data-name> ubuntu

자습서에서는 데이터 컨테이너의 사용에 대해 잘 설명합니다.

내 상황에서는 문제가 달랐습니다.이유는 모르겠지만 호스트의 디렉토리에chmod 777그것 위에서 실행, 도커 컨테이너 안에서 그것은 볼 수 있었습니다.755.

에서 실행 중sudo chmod 777 my_volume_dir고쳤습니다.

언급URL : https://stackoverflow.com/questions/24288616/permission-denied-on-accessing-host-directory-in-docker

반응형