Dockerコンテナー内でsudoを使用する方法は?


259

通常、Dockerコンテナはユーザーrootを使用して実行されます。別のユーザーを使用したいのですが、dockerの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/...
リーガン

回答:


242

ちょうどそれを得た。リーガンが指摘したように、ユーザーを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
エマド

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
これは、Ubuntu 18.04の
docker

100

コンテナーでsudoもapt-getも使用できない場合、コマンドを使用してrootユーザーとして実行中のコンテナーにジャンプすることもできます

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

これは、受け入れられた回答が要求された解決策を与えるとしても、OPがおそらく達成したいことのはるかに優れた解決策です。少なくとも、それは私が探していた答えです!
spikyjt

79

他の答えは私にはうまくいきませんでした。探し続けたところ、Dockerコンテナー内でroot以外のユーザーがどのように実行していたかを説明したブログ投稿が見つかりました。

これが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使用してパッケージをインストールするために、上記に1行追加しました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 2018

完璧、まさに私が必要としたもの。
Arin Ekandem

25

既に実行中のコンテナでこの問題が発生し、必ずしも再構築する必要がない場合は、次のコマンドでroot権限で実行中のコンテナに接続します。

docker exec -ti -u root container_name bash

次のようにして、名前ではなくIDを使用して接続することもできます。

docker ps -l

次にコンテナー(またはdocker-composeクラスター)を起動したときに変更が保存されるようにするには、次のように変更を保存します。

docker commit container_id image_name

実行されていないコンテナを起動してrootとして接続するには:

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 updateまたはapt-getを実行します。

それは私と一緒にうまくいきました


5

場合SUDOapt-getのは、コンテナ内にアクセス可能ではない、あなたは、コンテナを実行するにはオプションの下に、使用することができます。

docker exec -u root -it f83b5c5bf413 ash

f83b5c5bf413」は私のコンテナIDです。ここに私の端末からの作業例があります。

ここに画像の説明を入力してください


3

以下は、root以外のユーザーのベースイメージを設定する方法です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が作成されます。
  • ユーザーfoofoosudoグループの両方に追加されます。
  • uidgidの値に設定されています999
  • ホームディレクトリはに設定されてい/home/fooます。
  • シェルはに設定されてい/bin/bashます。
  • sedこのコマンドは、インラインに更新を行い/etc/sudoers許可するファイルfoorootへのユーザーパスワードなしのアクセス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
あなたは(私の場合のUbuntuで:18.04)を使用しているドッキングウィンドウの画像に応じて、削除する必要があるかもしれません-eからecho。それ以外の場合は、ファイル自体に存在し、機能しなくなります。
stiller_leser

きちんとしたアイデアですが、元のコマンドがなどのsudoオプションを使用している場合、これは機能しませんsudo -E ls。実行しようとし-E lsます。
wisbucky

2

これはすべてのイメージで機能するわけではありませんが、jupyterhub / singleuserイメージなど、一部のイメージにはすでにrootユーザーが含まれています。その画像では、それは単純です:

USER root
RUN sudo apt-get update

1

エイリアスを使用します。

alias sudo=''

シンプルですが効率的です。新しいシェルを開いた後に機能するように、〜/ .bash_aliasesに追加することを忘れないでください。

nano ~/.bash_aliases
alias sudo=''
#(Ctrl+X)

ユーザーはDockerのデフォルトルートであるため、sudoコマンドを「無視」するのが最も簡単な方法です。


0

受け入れられた回答とは異なり、usermod代わりに使用します。

dockerでrootとしてすでにログインしていて、「fruit」が追加したい新しい非rootユーザー名であると仮定して、次のコマンドを実行します。

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

更新後は必ず画像を保存してください。docker ps現在実行中のDockerの<CONTAINER ID>と<IMAGE>を取得するために使用し、docker commit -m "added sudo user" <CONTAINER ID> <IMAGE>Dockerイメージを保存するために実行します。

次に、以下を使用してテストします。

su fruit
sudo whoami

または、Dockerを起動するときに、その非rootユーザーとして直接ログイン(最初に画像を保存することを確認)でテストします。

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.