program tip

Docker의 사용자 파일 소유권 이해 : 연결된 볼륨의 권한 변경을 방지하는 방법

radiobox 2020. 11. 25. 07:50
반응형

Docker의 사용자 파일 소유권 이해 : 연결된 볼륨의 권한 변경을 방지하는 방법


다음과 같은 사소한 Dockerfile을 고려하십시오.

FROM debian:testing
RUN  adduser --disabled-password --gecos '' docker
RUN  adduser --disabled-password --gecos '' bob 

아무것도없는 작업 디렉토리에 있습니다. Docker 이미지를 빌드하십시오.

docker build -t test .

그런 다음 컨테이너에서 bash 스크립트를 실행하여 작업 디렉토리를 bob의 홈 디렉토리에있는 새 하위 디렉토리에 연결합니다.

docker run --rm -it -v $(pwd):/home/bob/subdir test 

subdir컨테이너 의 내용물은 누가 소유 합니까? 컨테이너에서 다음을 실행합니다.

cd /home/bob/subdir
ls -l

우리가 보는 광고 :

-rw-rw-r-- 1 docker docker 120 Oct 22 03:47 Dockerfile

이런 담배! docker콘텐츠를 소유합니다! 컨테이너 외부의 호스트 컴퓨터로 돌아 가면 원래 사용자가 여전히 Dockerfile. bob의 홈 디렉토리 소유권을 수정 해 보겠습니다 . 컨테이너에서 다음을 실행합니다.

chown -R bob:bob /home/bob
ls -l 

그리고 우리는 :

-rw-rw-r-- 1 bob bob 120 Oct 22 03:47 Dockerfile

하지만 기다려! 컨테이너 외부에서 이제ls -l

-rw-rw-r-- 1 1001 1001 120 Oct 21 20:47 Dockerfile

우리는 더 이상 우리 자신의 파일을 소유하지 않습니다. 끔찍한 소식!


위의 예에서 사용자를 한 명만 추가했다면 모든 것이 더 원활하게 진행되었을 것입니다. 어떤 이유로 Docker는 처음 접하는 루트가 아닌 사용자가 소유 한 홈 디렉토리를 만드는 것으로 보입니다 (해당 사용자가 이전 이미지에서 선언 된 경우에도). 마찬가지로이 첫 번째 사용자는 내 홈 사용자와 동일한 소유권 권한에 해당하는 사용자입니다.

질문 1 맞습니까? 누군가가 이것에 대한 문서를 알려줄 수 있습니까? 위의 실험을 기반으로 추측하고 있습니다.

질문 2 : 아마도 이것은 둘 다 커널에서 동일한 숫자 값을 가지고 있기 때문에 가정 사용자가 ID가 아닌 시스템에서 테스트하면 1000모든 경우에 권한이 변경됩니까?

질문 3 : 진짜 질문은 당연히 '어떻게해야합니까?'입니다. 주어진 호스트 컴퓨터 bob에서로 로그인 한 경우 bob컨테이너를로 실행할 수 있어야 bob하며 호스트 계정에서 파일 권한이 변경되지 않아야합니다. 실제로 그는 docker자신의 계정이 변경되지 않도록 컨테이너를 사용자 실행해야합니다 .

나는 당신이 물어 듣고 내가 왜 그런 이상한 Dockerfile 어쨌든해야합니까? . 나도 가끔 궁금해. 다른 사용자가 로그인 할 수 있도록 허용하는 웹 앱 (RStudio-server) 용 컨테이너를 작성 중입니다.이 컨테이너는 Linux 시스템의 사용자 이름과 자격 증명을 유효한 사용자 이름으로 사용합니다. 이로 인해 여러 사용자를 만들고 싶은 비정상적인 동기가 부여됩니다. 런타임에만 사용자를 생성하여이 문제를 해결할 수 있으며 모든 것이 좋습니다. 그러나 단일 docker사용자를 추가 한 기본 이미지를 사용하여 루트로 실행하지 않고도 대화 형으로 사용할 수 있습니다 (우수 사례에 따라). 이 사용자가 처음 이 되었기 때문에 모든 것을 파괴합니다.사용자가 모든 것을 소유하게되므로 다른 사용자로 로그온하려는 시도가 실패합니다 (쓰기 권한이 없기 때문에 앱을 시작할 수 없음). 시작 스크립트를 chown먼저 실행 하면이 문제가 해결되지만 연결된 볼륨의 권한 변경 비용이 발생합니다 (볼륨을 연결하는 경우에만 문제가 됨).


그 맞습니까? 누군가가 이것에 대한 문서를 알려줄 수 있습니까? 위의 실험을 기반으로 추측하고 있습니다.

아마도 이것은 둘 다 커널에서 동일한 숫자 값을 가지고 있기 때문에 가정 사용자가 ID 1000이 아닌 시스템에서 테스트하면 모든 경우에 권한이 변경됩니까?

info coreutils 'chown invocation'파일 권한 / 소유권이 어떻게 작동하는지 더 잘 이해할 수 있는을 읽어보십시오 .

기본적으로 컴퓨터의 각 파일에는 권한과 소유권을 정의하는 비트 세트가 있습니다. chown파일 일 ,이 비트를 설정하는 것입니다.

때 당신은 chown사용자 이름 또는 그룹 이름을 사용하여 특정 사용자 / 그룹에 파일 chown의 모양 /etc/passwd사용자 이름과 /etc/group아이디에 이름을 매핑하려고 시도하는 그룹. 해당 파일에 사용자 이름 / 그룹 이름이 없으면 chown실패합니다.

root@dc3070f25a13:/test# touch test
root@dc3070f25a13:/test# ll
total 8
drwxr-xr-x  2 root root 4096 Oct 22 18:15 ./
drwxr-xr-x 22 root root 4096 Oct 22 18:15 ../
-rw-r--r--  1 root root    0 Oct 22 18:15 test
root@dc3070f25a13:/test# chown test:test test
chown: invalid user: 'test:test'

그러나 chown컴퓨터에 해당 ID가있는 사용자 / 그룹이 있는지 여부에 관계없이 원하는대로 (물론 일부 양의 정수 범위 내에서) ID를 사용하여 파일을 만들 수 있습니다 .

root@dc3070f25a13:/test# chown 5000:5000 test
root@dc3070f25a13:/test# ll
total 8
drwxr-xr-x  2 root root 4096 Oct 22 18:15 ./
drwxr-xr-x 22 root root 4096 Oct 22 18:15 ../
-rw-r--r--  1 5000 5000    0 Oct 22 18:15 test

The UID and GID bits are set on the file itself, so when you mount those files inside your docker container, the file has the same owner / group UID as it does on the host, but is now mapped to /etc/passwd in the container, which is probably going to be a different user unless it's owned by root (UID 0).

The real question is, of course, 'what do I do about this?' If bob is logged in as bob on the given host machine, he should be able to run the container as bob and not have file permissions altered under his host account. As it stands, he actually needs to run the container as user docker to avoid having his account altered.

It seems like, with your current set-up, you'll need to make sure your UIDs > usernames in /etc/passwd on your host match up to your UIDs > usernames in your containers /etc/passwd if you want to interact with your mounted user directory as the same user that's logged in on the host.

You can create a user with a specific user id with useradd -u xxxx. Buuuut, that does seem like a messy solution...

You might have to come up with a solution that doesn't mount a host users home directory.


Two options I've found:

CHOWN all the things (after doing your work)

I've done docker run -v `pwd`/shared:/shared image, and the container has created files within pwd/shared that are how owned by the docker process. However, /shared is still owned by me. So within the docker process, I do

chown -R `stat -c "%u:%g" /shared` /shared

stat -c "%u:%g" /shared returns 1000:1000 in my case, being the uid:gid of my user. Even though there is no user 1000 within the docker conatainer, the id is there (and stat /shared just says "unknown" if you ask for the username).

Anyway, chown obediently transfers ownership of the contents of /shared to 1000:1000 (which, as far as it is concerned, doesn't exist, but outside the container, it's me). So I now own all the files. The container can still modify things if it wants to, because from its perspective, it's root.

And all is well with the world.

docker run -u so all files created will automatically have the right owner

Another way to do this is the -u flag on docker run.

docker run -v `pwd`/shared:/shared -u `stat -c "%u:%g" /shared` ubuntu bash

This way, the docker user inside the container is youruid:yourgid.

However: this means giving up your root authority within the container (apt-get install, etc.). Unless you create a user with that new uid and add it to the root group.


So, I ended up in this post looking on how to restore ownership of all the files (owned by root) that came out of a docker container running as root, to my non-privileged user in the host.

I needed the process inside the container to run as root, so I can't use -u on docker run.

I'm not proud of what I did, but at the end of my bash script, I added this:

docker run --rm -it \
    --entrypoint /bin/sh \
    -e HOST_UID=`id -u` \
    -v ${HOST_FOLDER_OWNED_BY_ROOT}:/tmp \
    alpine:latest \
    -c 'chown -R ${HOST_UID}:${HOST_UID} /tmp/'

Let's break some of the lines down:

  • Run /bin/sh inside the container:

--entrypoint /bin/sh

  • Pass the current user's uid as an environment variable to the container:

-e HOST_UID=`id -u`

  • Mount whatever folder you want to re-own back to your user (filled with files owned by root, output-ed by the previous container that ran as root), under this new container's /tmp:

-v ${HOST_FOLDER_OWNED_BY_ROOT}:/tmp

  • Run chown recursively with the host user's uid over the target directory (mounted inside the container in /tmp):

-c 'chown -R ${HOST_UID}:${HOST_UID} /tmp/'

So, with this, I got the files owned back to my current user without having to "escalate" privileges to root or to sudo.

It's dirty, but it worked. Hope I helped.

참고URL : https://stackoverflow.com/questions/26500270/understanding-user-file-ownership-in-docker-how-to-avoid-changing-permissions-o

반응형