如何在Docker容器中使用sudo?


258

通常,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/…–
Regan

Answers:


240

知道了 正如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 2015年

对于CentOS,您可以添加一个用户和组,然后在下创建一个碎片文件,/etc/sudoers.d/440对该文件设置权限。然后,用户将在CentOS 6和更高版本下具有sudo访问权限。5您必须#includedir /etc/sudoers.d/etc/sudoers
FilBot3

对我不起作用。我有那些错误:E:无法打开锁定文件/ var / lib / apt / lists /
lock-

1
这似乎
不适

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,以便使用来安装软件包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. Scott Ford

啊,谢谢!错过了。我认为sudoDockerfile中不允许这样做。
edesz

完美,正是我所需要的。
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更新或apt-获取“任何您想要的东西”

它与我合作,希望它对所有人有用


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已创建。
  • 用户foo被添加到foosudo组中。
  • uidgid被设置为值999
  • 主目录设置为/home/foo
  • 外壳设置为/bin/bash
  • sed命令对/etc/sudoers文件进行内联更新以允许fooroot用户无密码访问该sudo组。
  • sed命令禁用#includedir指令,该指令将允许子目录中的任何文件覆盖这些内联更新。

2

如果您有一个以root用户身份运行的容器,该容器运行需要访问该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),您可能需要删除-eecho。否则,它将出现在文件本身中,从而使其无法运行。
stiller_leser

这很简单,但是如果原始命令使用sudo选项(例如),则此方法将无效sudo -E ls。它将尝试执行-E ls
wisbucky

2

这可能不适用于所有图像,但是某些图像已经包含root用户,例如在jupyterhub / singleuser图像中。有了该图像,它就是:

USER root
RUN sudo apt-get update

0

公认的答案不同,我使用usermod改用了。

假设已经以root用户身份在docker中登录,并且“ fruit”是我要添加的新的非root用户名,只需运行以下命令:

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

记住在更新后保存图像。使用docker ps获得当前正在运行的码头工人的<容器ID>和<IMAGE>,然后运行docker commit -m "added sudo user" <CONTAINER ID> <IMAGE>以节省码头工人的形象。

然后测试:

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

0

使用别名。

alias sudo=''

简单高效。不要忘记将其附加到.bashrc,这样在重新打开外壳程序后它仍然可以工作。

nano ~/.bashrc
alias sudo=''

由于用户是Docker中的默认用户,因此“忽略” sudo命令是最简单的方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.