简体   繁体   English

如何在 docker 容器内使用 sudo?

[英]How to use sudo inside a docker container?

Normally, docker containers are run using the user root .通常,docker 容器使用用户root运行。 I'd like to use a different user, which is no problem using docker's USER directive.我想使用不同的用户,使用 docker 的 USER 指令没问题。 But this user should be able to use sudo inside the container.但是这个用户应该能够在容器内使用sudo This command is missing.缺少此命令。

Here's a simple Dockerfile for this purpose:这是一个简单的 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

Running this container, I get logged in with user 'docker'.运行这个容器,我使用用户 'docker' 登录。 When I try to use sudo, the command isn't found.当我尝试使用 sudo 时,找不到该命令。 So I tried to install the sudo package inside my Dockerfile using所以我尝试在我的 Dockerfile 中安装sudo package

RUN apt-get install sudo

This results in Unable to locate package sudo这导致无法找到 package sudo

Just got it.刚刚得到它。 As regan pointed out, I had to add the user to the sudoers group.正如 regan 所指出的,我必须将用户添加到 sudoers 组。 But the main reason was I'd forgotten to update the repositories cache, so apt-get couldn't find the sudo package.但主要原因是我忘记更新存储库缓存,所以 apt-get 找不到 sudo package。 It's working now.它现在正在工作。 Here's the completed code:这是完成的代码:

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

When neither sudo nor apt-get is available in container, you can also jump into running container as root user using command当容器中 sudo 和 apt-get 均不可用时,您也可以使用命令以 root 用户身份跳转到正在运行的容器中

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

The other answers didn't work for me.其他答案对我不起作用。 I kept searching and found a blog post that covered how a team was running non-root inside of a docker container.我一直在搜索并找到一篇博客文章,其中介绍了团队如何在 docker 容器内以非 root 用户运行。

Here's the TL;DR version:这是 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 

I was using FROM node:9.3 for this, but I suspect that other similar container bases would work as well.我为此使用FROM node:9.3 ,但我怀疑其他类似的容器库也可以。

For anyone who has this issue with an already running container, and they don't necessarily want to rebuild, the following command connects to a running container with root privileges:对于已经运行的容器存在此问题并且不一定要重建的任何人,以下命令连接到具有 root 权限的正在运行的容器:

docker exec -ti -u root container_name bash

You can also connect using its ID, rather than its name, by finding it with:您还可以使用其 ID 而不是其名称进行连接,方法是通过以下方式找到它:

docker ps -l

To save your changes so that they are still there when you next launch the container (or docker-compose cluster) - note that these changes would not be repeated if you rebuild from scratch:要保存您的更改,以便下次启动容器(或 docker-compose 集群)时它们仍然存在 - 请注意,如果您从头开始重建,这些更改将不会重复:

docker commit container_id image_name

To roll back to a previous image version (warning: this deletes history rather than appends to the end, so to keep a reference to the current image, tag it first using the optional step):要回滚到以前的图像版本(警告:这会删除历史记录而不是追加到末尾,因此要保留对当前图像的引用,请首先使用可选步骤对其进行标记):

docker history image_name
docker tag latest_image_id my_descriptive_tag_name  # optional
docker tag desired_history_image_id image_name

To start a container that isn't running and connect as root:要启动未运行的容器并以 root 身份连接:

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

To copy from a running container:从正在运行的容器中复制:

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

To export a copy of the image:要导出图像的副本:

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

Which you can restore to another Docker install using:您可以使用以下命令恢复到另一个 Docker 安装:

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

It is much quicker but takes more space to not compress, using:它更快,但需要更多空间来不压缩,使用:

docker save container | dir/file.tar

And:和:

cat dir/file.tar | docker load

if you want to connect to container and install something如果你想连接到容器并安装一些东西
using apt-get使用 apt-get
first as above answer from our brother "Tomáš Záluský"首先是我们兄弟“Tomáš Záluský”的回答

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

then try to然后尝试

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

it worked with me hope it's useful for all它对我有用,希望对所有人有用

Here's how I setup a non-root user with the base image of ubuntu:18.04 :以下是我使用ubuntu:18.04的基本映像设置非 root 用户的方法:

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

What happens with the above code:上面的代码会发生什么:

  • The user and group foo is created.用户和组foo被创建。
  • The user foo is added to the both the foo and sudo group.用户foo被添加到foosudo组中。
  • The uid and gid is set to the value of 999 . uidgid设置为999的值。
  • The home directory is set to /home/foo .主目录设置为/home/foo
  • The shell is set to /bin/bash . shell 设置为/bin/bash
  • The sed command does inline updates to the /etc/sudoers file to allow foo and root users passwordless access to the sudo group. sed命令对/etc/sudoers文件进行内联更新,以允许fooroot用户无密码访问sudo组。
  • The sed command disables the #includedir directive that would allow any files in subdirectories to override these inline updates. sed命令禁用#includedir指令,该指令将允许子目录中的任何文件覆盖这些内联更新。

If SUDO or apt-get is not accessible inside the Container, You can use, below option in running container.如果容器内无法访问SUDOapt-get ,您可以在运行容器中使用以下选项。

docker exec -u root -it f83b5c5bf413 ash

" f83b5c5bf413" is my container ID & here is working example from my terminal: f83b5c5bf413”是我的容器 ID ,这是来自我的终端的工作示例:

在此处输入图像描述

Unlike accepted answer , I use usermod instead.接受的答案不同,我使用usermod代替。

Assume already logged-in as root in docker, and "fruit" is the new non-root username I want to add, simply run this commands:假设已经在 docker 中以 root 身份登录,并且“fruit”是我要添加的新的非 root 用户名,只需运行以下命令:

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

Remember to save image after update.更新后记得保存图片。 Use docker ps to get current running docker's <CONTAINER ID> and <IMAGE>, then run docker commit -m "added sudo user" <CONTAINER ID> <IMAGE> to save docker image.使用docker ps获取当前正在运行的 docker 的 <CONTAINER ID> 和 <IMAGE>,然后运行docker commit -m "added sudo user" <CONTAINER ID> <IMAGE>以保存 Z05B6053C41ABDACE40 Z05B6053C41AB240

Then test with:然后测试:

su fruit
sudo whoami

Or test by direct login(ensure save image first) as that non-root user when launch docker:或者在启动 docker 时以非 root 用户身份直接登录(确保先保存图像)进行测试:

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

You can use sudo -k to reset password prompt timestamp:您可以使用sudo -k重置密码提示时间戳:

sudo whoami # No password prompt
sudo -k # Invalidates the user's cached credentials
sudo whoami # This will prompt for password

This may not work for all images, but some images contain a root user already, such as in the jupyterhub/singleuser image.这可能不适用于所有图像,但某些图像已经包含 root 用户,例如在 jupyterhub/singleuser 图像中。 With that image it's simply:使用该图像很简单:

USER root
RUN sudo apt-get update

If you have a container running as root that runs a script (which you can't change) that needs access to the sudo command, you can simply create a new sudo script in your $PATH that calls the passed command.如果您有一个以 root 身份运行的容器,该容器运行需要访问sudo命令的脚本(您无法更改),您可以简单地在$PATH中创建一个新的sudo脚本来调用传递的命令。

eg In your Dockerfile:例如在您的 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

There is no answer on how to do this on CentOS. CentOS 上没有关于如何执行此操作的答案。 On Centos, you can add following to Dockerfile在 Centos 上,您可以将以下内容添加到 Dockerfile

RUN echo "user ALL=(root) NOPASSWD:ALL" > /etc/sudoers.d/user && \
    chmod 0440 /etc/sudoers.d/user

An example Dockerfile for Centos7. Centos7 的示例 Dockerfile。 In this example we add prod_user with privilege of sudo.在此示例中,我们添加了具有 sudo 权限的 prod_user。

FROM centos:7

RUN yum -y update && yum clean all

RUN yum -y install openssh-server  python3 sudo

RUN adduser -m prod_user && \
    echo "MyPass*49?" | passwd prod_user --stdin && \
    usermod -aG wheel prod_user && \
    mkdir /home/prod_user/.ssh && \
    chown prod_user:prod_user -R  /home/prod_user/ && \
    chmod 700 /home/prod_user/.ssh

RUN echo "prod_user ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \
    echo "%wheel ALL=(ALL) ALL" >> /etc/sudoers

RUN echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config

RUN systemctl enable sshd.service

VOLUME [ "/sys/fs/cgroup" ]

ENTRYPOINT ["/usr/sbin/init"]

I'm using an Ubuntu image, while using the docker desktop had faced this issue.我使用的是 Ubuntu 映像,而使用 docker 桌面时遇到了这个问题。

The following resolved the issue:以下解决了该问题:

  1. apt-get update apt-get 更新
  2. apt-get install sudo apt-get 安装 sudo

The main idea is that you need to create user that is a root user according to the container.主要思想是您需要根据容器创建root用户。

Main commands:主要命令:

RUN echo "bot:bot" | chpasswd
RUN adduser bot sudo

the first sends the literal string bot:bot to chpasswd which creates the user bot with the password bot , chpasswd does:第一个将文字字符串bot:bot发送到chpasswd ,它使用密码bot创建用户 bot , chpasswd 执行以下操作:

The chpasswd command reads a list of user name and password pairs from standard input and uses this information to update a group of existing users. Each line is of the format:

user_name:password

By default the supplied password must be in clear-text, and is encrypted by chpasswd. Also the password age will be updated, if present.

The second command I assume adds the user bot as sudo.我假设的第二个命令将用户机器人添加为 sudo。

Full docker container to play with:完整的 docker 容器可以玩:

FROM continuumio/miniconda3
# FROM --platform=linux/amd64 continuumio/miniconda3

MAINTAINER Brando Miranda "me@gmail.com"

RUN apt-get update \
  && apt-get install -y --no-install-recommends \
    ssh \
    git \
    m4 \
    libgmp-dev \
    opam \
    wget \
    ca-certificates \
    rsync \
    strace \
    gcc \
    rlwrap \
    sudo

# https://github.com/giampaolo/psutil/pull/2103

RUN useradd -m bot
# format for chpasswd user_name:password
RUN echo "bot:bot" | chpasswd
RUN adduser bot sudo

WORKDIR /home/bot
USER bot
#CMD /bin/bash

You can use docker without sudo by adding the user to the sudoers group.通过将用户添加到 sudoers 组,您可以在不使用sudo的情况下使用 docker。 It is explained here in more detail.这里有更详细的解释。

sudo groupadd docker
sudo usermod -aG docker $USER

Replace the $USER with the name of the user you want to use it with.将 $USER 替换为您要使用它的用户的名称。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM