도커 컨테이너 내부에서 sudo를 사용하는 방법은 무엇입니까?


259

일반적으로 docker 컨테이너는 사용자 root를 사용하여 실행됩니다 . 도커의 USER 지시문을 사용하는 데 아무런 문제가없는 다른 사용자를 사용하고 싶습니다. 그러나이 사용자는 컨테이너 내부에서 sudo 를 사용할 수 있어야합니다 . 이 명령이 없습니다.

이 목적을위한 간단한 Dockerfile이 있습니다.

FROM ubuntu:12.04

RUN useradd docker && echo "docker:docker" | chpasswd
RUN mkdir -p /home/docker && chown -R docker:docker /home/docker

USER docker
CMD /bin/bash

이 컨테이너를 실행하면 'docker'사용자로 로그인됩니다. sudo를 사용하려고하면 명령을 찾을 수 없습니다. 그래서 Dockerfile 안에 sudo 패키지 를 설치하려고했습니다.

RUN apt-get install sudo

이로 인해 패키지 sudo를 찾을 수 없습니다


sudo 그룹을 사용자에게 제공하십시오. askubuntu.com/questions/7477/…
— Regan

답변:


242

알았어 regan이 지적했듯이 sudoers 그룹에 사용자를 추가해야했습니다. 그러나 주된 이유는 리포지토리 캐시를 업데이트하지 않았기 때문에 apt-get이 sudo 패키지를 찾을 수 없었습니다. 지금 작동하고 있습니다. 완성 된 코드는 다음과 같습니다.

FROM ubuntu:12.04

RUN apt-get update && \
      apt-get -y install sudo

RUN useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo

USER docker
CMD /bin/bash

8
centos에서는 작동하지 않습니다. 이 adduser명령은useradd
— Emad

CentOS의 경우 사용자 및 그룹을 추가 한 다음 샤드 파일을 작성하고 해당 파일에 /etc/sudoers.d/대한 권한을 설정할 440수 있습니다. 그러면 사용자는 CentOS, 6 이상에서 sudo 액세스 권한을 갖게됩니다. 5에 #includedir /etc/sudoers.d지시문 을 추가해야 합니다./etc/sudoers
— FilBot3

나를 위해 작동하지 않습니다. 이러한 오류가 있습니다. E : 잠금 파일 / var / lib / apt / lists / lock을 열 수 없음-열림 (13 : 권한 거부) E : / var / lib / apt / lists / 디렉토리를 잠글 수 없음
— Marosinho

1
이것은 우분투 18.04 도커 이미지에서 작동하지 않는 것 같습니다
— viggy

100

컨테이너에서 sudo 또는 apt-get을 사용할 수 없으면 명령을 사용하여 루트 사용자로 컨테이너를 실행할 수도 있습니다.

docker exec -u root -t -i container_id /bin/bash

수락 된 답변이 요청 된 솔루션을 제공하더라도 OP가 달성하고자하는 것에 대한 훨씬 더 나은 솔루션입니다. 적어도 내가 찾던 대답입니다!
— spikyjt

79

다른 답변은 저에게 효과적이지 않았습니다. 나는 계속 검색하고 팀이 도커 컨테이너 내부에서 루트가 아닌 방식으로 실행되는 방법을 다루는 블로그 게시물 을 찾았습니다 .

TL; DR 버전은 다음과 같습니다.

RUN apt-get update \
 && apt-get install -y sudo

RUN adduser --disabled-password --gecos '' docker
RUN adduser docker sudo
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

USER docker

# this is where I was running into problems with the other approaches
RUN sudo apt-get update 

나는 FROM node:9.3이것을 위해 사용 하고 있었지만 다른 유사한 컨테이너베이스도 효과가 있다고 생각합니다.


사용하고 ubuntu:bionic-20180724.1있습니다. 이 방법을 사용했지만 위의 후에 다른 패키지를 설치할 수 없습니다. Dockerfile패키지를 다음과 같이 설치하기 위해 위의 한 줄을 추가했습니다 RUN apt-get install -y tree. 그러나이 오류 메시지가 나타납니다.Step xxxx/xxxx : RUN apt-get install -y tree ---> Running in j5e6gsvwfafa Reading package lists... E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied) E: Unable to lock directory /var/lib/apt/lists/
— edesz

1
@WR 나는 당신이 읽도록 그 줄을 바꿔야한다고 생각한다 RUN sudo apt-get install -y tree. 을 설정 한 후 USER이외에 root, 당신은 사용해야합니다 sudo필요한 모든 명령에 대한 root권한을.
— M. 스콧 포드

아 고마워! 그것을 놓쳤다. sudoDockerfile에서 허용 되지 않았다고 생각 했습니다.
— edesz

완벽, 내가 필요한 것.
— Arin Ekandem

25

이미 실행중인 컨테이너에서이 문제가 있고 반드시 다시 빌드하지 않으려는 경우 다음 명령은 루트 권한으로 실행중인 컨테이너에 연결합니다.

docker exec -ti -u root container_name bash

다음과 같이 찾아서 이름 대신 ID를 사용하여 연결할 수도 있습니다.

docker ps -l

다음에 컨테이너 (또는 docker-compose cluster)를 시작할 때 변경 사항이 저장되도록 변경 사항을 저장하려면 다음을 수행하십시오.

docker commit container_id image_name

실행 중이 아닌 컨테이너를 시작하고 루트로 연결하려면

docker run -ti -u root --entrypoint=/bin/bash image_id_or_name -s

실행중인 컨테이너에서 복사하려면

docker cp <containerId>:/file/path/within/container /host/path/target

이미지 사본을 내보내려면

docker save container | gzip > /dir/file.tar.gz

다음을 사용하여 다른 Docker 설치로 복원 할 수 있습니다.

gzcat /dir/file.tar.gz | docker load

다음을 사용하여 훨씬 빠르지 만 압축하지 않는 데 더 많은 공간이 필요합니다.

docker save container | dir/file.tar

과:

cat dir/file.tar | docker load

17

컨테이너에 연결하고 위의
apt-get을 사용하여 무언가 를 설치하려면
형제 "Tomáš Záluský"의 답변

docker exec -u root -t -i container_id /bin/bash

그런 다음 시도

apt-get 업데이트 또는 apt-get '원하는 것'을 실행하십시오.

그것은 나에게 도움이되기를 바랍니다.


5

경우 SUDO 또는 apt-get을이 컨테이너 내부에 액세스 할 수 없습니다, 당신은 용기를 실행에 옵션 아래에 사용할 수 있습니다.

docker exec -u root -it f83b5c5bf413 ash

" f83b5c5bf413"은 내 컨테이너 ID 이며 여기 내 터미널에서 작동하는 예제입니다.

여기에 이미지 설명을 입력하십시오


3

기본 이미지를 사용하여 루트가 아닌 사용자를 설정하는 방법은 다음과 같습니다 ubuntu:18.04.

RUN \
    groupadd -g 999 foo && useradd -u 999 -g foo -G sudo -m -s /bin/bash foo && \
    sed -i /etc/sudoers -re 's/^%sudo.*/%sudo ALL=(ALL:ALL) NOPASSWD: ALL/g' && \
    sed -i /etc/sudoers -re 's/^root.*/root ALL=(ALL:ALL) NOPASSWD: ALL/g' && \
    sed -i /etc/sudoers -re 's/^#includedir.*/## **Removed the include directive** ##"/g' && \
    echo "foo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \
    echo "Customized the sudoers file for passwordless access to the foo user!" && \
    echo "foo user:";  su - foo -c id

위의 코드는 어떻게됩니까?

  • 사용자와 그룹 foo이 생성됩니다.
  • 사용자 foo는 그룹 foo과 sudo그룹 모두에 추가됩니다 .
  • uid과는 gid값으로 설정된다 999.
  • 홈 디렉토리가로 설정되어 /home/foo있습니다.
  • 쉘이로 설정되어 /bin/bash있습니다.
  • sed명령은 인라인 업데이트를 수행 /etc/sudoers할 수 있도록 파일 foo및 root받는 사용자가 암호없이 액세스 sudo그룹.
  • 이 sed명령은 #includedir하위 디렉토리의 모든 파일이 이러한 인라인 업데이트를 재정의 할 수 있도록 하는 지시문을 비활성화 합니다.

2

sudo명령에 액세스해야하는 스크립트 (변경할 수 없음)를 실행하는 루트로 실행되는 컨테이너가있는 경우 전달 된 명령을 호출 하는 새 sudo스크립트를 만들면 $PATH됩니다.

예를 들어 Dockerfile에서 :

RUN if type sudo 2>/dev/null; then \ 
     echo "The sudo command already exists... Skipping."; \
    else \
     echo -e "#!/bin/sh\n\${@}" > /usr/sbin/sudo; \
     chmod +x /usr/sbin/sudo; \
    fi

1
(내 경우 우분투 : 18.04) 사용중인 고정 표시기 이미지에 따라, 당신은을 제거 할 필요가있을 수 있습니다 -e으로부터 echo. 그렇지 않으면 파일 자체에 존재하여 작동하지 않게됩니다.
— stiller_leser

깔끔한 아이디어이지만 원래 명령이과 같은 sudo 옵션을 사용하는 경우 작동하지 않습니다 sudo -E ls. 실행을 시도합니다 -E ls.
— wisbucky

2

일부 이미지에는 작동하지 않을 수 있지만 일부 이미지에는 jupyterhub / singleuser 이미지와 같은 루트 사용자가 이미 포함되어 있습니다. 그 이미지를 보면 다음과 같습니다.

USER root
RUN sudo apt-get update

1

별명을 사용하십시오.

alias sudo=''

간단하고 효율적입니다. 쉘을 다시 연 후에도 여전히 작동하므로 .bashrc 에 추가하는 것을 잊지 마십시오 .

nano ~/.bashrc
alias sudo=''

Docker에서 사용자는 기본 루트 이므로 sudo 명령을 '무시'하는 것이 가장 쉬운 방법입니다.


0

허용 된 답변 과 달리 , 나는usermod 대신 합니다.

docker에서 이미 루트로 로그인했다고 가정하고 "fruit"는 내가 추가하려는 새로운 비 루트 사용자 이름이며 간단히 다음 명령을 실행하십시오.

apt update && apt install sudo
adduser fruit
usermod -aG sudo fruit

업데이트 후 이미지를 저장하십시오. 사용은 docker ps현재 실행중인 고정 표시기의 <컨테이너 ID>를 얻을 수 및 <이미지>를 실행docker commit -m "added sudo user" <CONTAINER ID> <IMAGE> 고정 표시기 이미지를 저장합니다.

그런 다음 테스트하십시오.

su fruit
sudo whoami

또는 도커를 시작할 때 루트가 아닌 사용자로 직접 로그인하여 이미지를 먼저 저장하십시오.

docker run -it --user fruit <IMAGE>
sudo whoami

sudo -k비밀번호 프롬프트 타임 스탬프를 재설정 하는 데 사용할 수 있습니다 .

sudo whoami # No password prompt
sudo -k # Invalidates the user's cached credentials
sudo whoami # This will prompt for password
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.