当前位置: 首页 > 知识库问答 >
问题:

用sudo priviledges在Docker中添加用户的干净方法是什么?

丰俊艾
2023-03-14

我试图理解如何在docker中正确添加非root用户,并给他们sudo权限。假设我当前的Ubuntu 18.04系统中janedoe是sudo用户。我想创建一个docker映像,在其中我想添加janedoe作为非root用户,在需要时可以拥有sudo权限。由于我和Docker都是Linux系统新手,我通常希望有人通过一个例子来解释如何做到这一点。

我理解的是,每当我在Dockerfile中发出命令“USER janedoe”时,该行之后的许多命令都不能由janedoe的权限执行。我假设在构建容器时,我们必须将janedoe添加到sudo“组”,就像管理员向系统添加新用户时一样。

我一直在尝试寻找一些演示Dockerfile来解释这个例子,但找不到它。

共有2个答案

慕容兴贤
2023-03-14

我认为您正在寻找这个问题的答案:如何将用户添加到docker容器中

RUN useradd -ms /bin/bash janedoe <-- this command adds the user
usermod -aG sudo janedoe <-- this command tells the container to put the user janedoe inside the SUDO group

然后,如果您想在脚本的其余部分切换到该用户,请使用:

USER janedoe <-- all lines after this now use the janedoe user to execute them
WORKDIR /home/janedoe <-- this tells your script from this line on to use paths relative to janedoe's home folder

由于容器本身运行linux模块,因此大多数(如果不是全部)linux命令也应该在容器内工作。如果您有静态用户(即可以预测哪些用户),您应该能够在用于创建图像的Dockerfile中创建它们。现在,每次从上述图像运行容器时,都应该将janedoe用户放在其中。

索嘉石
2023-03-14

通常,您应该将Docker容器视为单个进程的包装器。如果你问这个关于其他过程的问题,这真的没有意义。(如何使用sudo权限将用户添加到PostgreSQL server?如何将用户添加到Web浏览器?)

在Docker中,你几乎不需要sudo,原因有三:在大多数情况下切换用户很简单;您通常不会在容器中获得交互式shell(如何从cron守护进程中获得目录列表?);如果你可以运行任何docker命令,你就可以很容易地找到整个主机的根<代码>sudo也很难编写脚本,而且很难在Docker中有效地维护用户密码(在易于检索的纯文本文件中编写与根等效的密码不是安全最佳做法)。

在您的问题中,如果您已经切换到一些非root用户,并且需要运行一些管理命令,请使用用户切换回root。

USER janedoe
...
USER root
RUN apt-get update && apt-get install -y some-package
USER janedoe

由于容器与主机系统有一定的隔离,因此通常不需要容器与主机系统具有相同的用户名或用户ID。例外情况是当使用绑定装载与主机共享文件时,但最好在启动容器时指定此详细信息。

我习惯的典型做法是:

>

  • 在您的Dockerfile中,创建一些非root用户。它可以有任何名称。它不需要密码、登录shell、主目录或任何其他详细信息。将其视为“系统”用户很好。

     FROM ubuntu:18.04
     RUN adduser --system --group --no-create-home appuser
    

    仍然在您的Dockerfile中,以root身份执行几乎所有操作。这包括安装您的应用程序。

     RUN apt-get update && apt-get install ...
     WORKDIR /app
     COPY requirements.txt .
     RUN pip install -r requirements.txt
     COPY . .
    

    当您描述运行容器的默认方式时,只有切换到非root用户。

     EXPOSE 8000
     USER appuser
     CMD ["./main.py"]
    

    理想情况下,这就是故事的结尾:您的代码内置在您的映像中,它将所有数据存储在外部的某个地方,例如数据库,因此它根本不关心主机用户空间(默认情况下不应该有docker run-v或Docker Compose卷:选项)。

    如果文件权限真的很重要,您可以指定启动容器时要使用的数字主机用户ID。用户不需要特别存在于容器的/etc/passwd文件中。

     docker run \
       --name myapp \
       -d \
       -p 8000:8000 \
       -v $PWD:/data \
       -u $(id -u) \
       myimage
    

  •  类似资料:
    • 问题内容: 我想在字典中的所有键上映射一个函数。我希望可以执行以下操作,但是过滤器无法直接应用于字典。实现这一目标的最干净的方法是什么? 在此示例中,我尝试将每个值加1。但这对于示例来说是偶然的-主要目的是弄清楚如何将map()应用于字典。 问题答案: 迅捷4+ 好消息!Swift 4包含一种方法,该方法使用相同的键但值不同来构造字典的副本。它还包含一个重载函数,该重载函数返回a 和,并使用初始值

    • 问题内容: 我需要使用$ resource 发送带有我的DELETE请求的请求正文 我可以看到的唯一方法是更改​​: https://github.com/angular/angular.js/blob/master/src/ngResource/resource.js 从 至 有没有更好的方法来覆盖此?就像您更改内容类型标头时一样,您可以执行以下操作: 或类似的东西…我已经用谷歌搜索了一下,但也

    • 问题内容: 我有一个DOM元素,应用了以下一些/全部效果: 我正在编写一个调整此元素大小的jQuery插件,我需要暂时禁用这些效果,以便可以平滑地调整其大小。 临时禁用这些效果(然后重新启用它们)的最优雅的方法是什么,因为它们可能是由父母应用的,也可能根本没有应用。 问题答案: 简短答案 使用此CSS: 加上这个JS(没有jQuery)… 或者这个带有jQuery的JS … …或使用您正在使用的任

    • 我能想到的唯一解决方案是在启动度量服务时将描述存储在某个地方。然后围绕increment方法创建一个包装器。现在,当用户调用包装器时,调用register方法(使用存储的描述),然后调用increment方法。afaik,register方法创建一个新的度量,如果它不存在,否则返回现有的度量。 同样的问题在Prometheus中可以很容易地解决,因为他们有一个寄存器方法,允许您设置所有的标签(即仅

    • 问题内容: 我找不到确切的答案。据我所知,类中不能有多个功能。那么我该如何解决这个问题呢? 假设我有一个Cheese用属性调用的类。我如何有两种创建奶酪对象的方式… 有很多这样的漏洞: 还有一个不带参数而只是随机化属性的参数: 我只能想到一种执行此操作的方法,但这似乎很笨拙: 你说什么?还有另一种方法吗? 问题答案: 对于“魔术”值,实际上要好得多: 现在,如果你想完全自由地添加更多参数: 为了更

    • 我试过这种格式 但这似乎不起作用。