389

通常,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

这导致Unable to locate package sudo

4

11 回答 11

320

刚刚得到它。正如 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
于 2014-09-18T08:51:30.117 回答
247

当容器中 sudo 和 apt-get 均不可用时,您也可以使用命令以 root 用户身份跳转到正在运行的容器中

docker exec -u root -t -i container_id /bin/bash
于 2018-03-28T08:46:06.693 回答
118

其他答案对我不起作用。我一直在搜索并找到一篇博客文章,其中介绍了团队如何在 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为此使用,但我怀疑其他类似的容器底座也可以使用。

于 2018-01-18T19:39:40.177 回答
68

对于已经运行的容器存在此问题并且不一定要重建的任何人,以下命令连接到具有 root 权限的正在运行的容器:

docker exec -ti -u root container_name bash

您还可以使用其 ID 而不是其名称进行连接,方法是通过以下方式找到它:

docker ps -l

要保存您的更改,以便下次启动容器(或 docker-compose 集群)时它们仍然存在 - 请注意,如果您从头开始重建,这些更改将不会重复:

docker commit container_id image_name

要回滚到以前的图像版本(警告:这会删除历史记录而不是追加到末尾,因此要保留对当前图像的引用,请首先使用可选步骤对其进行标记):

docker history image_name
docker tag latest_image_id my_descriptive_tag_name  # optional
docker tag desired_history_image_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
于 2019-02-16T18:45:44.587 回答
19

如果您想连接到容器并首先
使用 apt-get安装一些东西
,如我们兄弟“Tomáš Záluský”的回答

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

然后尝试

运行 apt-get update 或 apt-get 'anything you want'

它对我有用,希望对所有人有用

于 2018-04-29T10:10:59.827 回答
10

以下是我使用以下基本映像设置非 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允许用户无密码访问该组。foorootsudo
  • sed命令禁用#includedir允许子目录中的任何文件覆盖这些内联更新的指令。
于 2019-09-29T02:57:54.613 回答
9

如果容器内无法访问SUDOapt-get,您可以在运行容器中使用以下选项。

docker exec -u root -it f83b5c5bf413 ash

f83b5c5bf413”是我的容器 ID,这是来自我的终端的工作示例:

在此处输入图像描述

于 2019-12-06T12:32:40.973 回答
8

接受的答案不同,我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
于 2020-06-02T15:20:56.037 回答
4

这可能不适用于所有图像,但某些图像已经包含 root 用户,例如在 jupyterhub/singleuser 图像中。使用该图像很简单:

USER root
RUN sudo apt-get update
于 2019-10-09T17:38:55.243 回答
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
于 2018-08-01T23:51:17.720 回答
0

没有关于如何在 CentOS 上执行此操作的答案。在 Centos 上,您可以将以下内容添加到 Dockerfile

RUN echo "user ALL=(root) NOPASSWD:ALL" > /etc/sudoers.d/user && \
    chmod 0440 /etc/sudoers.d/user
于 2020-10-01T19:00:21.633 回答