多用户环境中的 rootless Docker

在使用 rootless Docker 几个月后,我想我找到了一种方法,可以以一种感觉恰到好处的便捷方式实现 rootless Docker,并希望在这篇简短的教程中与大家分享。

何必呢?

尽管在 rootless 模式下安装 Docker 守护进程非常简单,但如果需要为多个用户工作,事情就会变得很麻烦。

因为我希望我的团队将其作为新的默认设置,只有在绝对必要时才使用有权限的容器,所以解决方案必须尽可能少地给他们带来麻烦。

对于单人管理的服务器也很有用。

方法

  1. 当然是安装 Docker。
  2. 创建一个运行 rootless Docker 的专用用户。
  3. 安装 rootless 守护进程。

到目前为止,这些要点显而易见。问题是什么?

如果我们保持原样,用户就需要明确指定 ${DOCKER_HOST},并以其他用户身份运行 cli。既容易出错,又不方便。

该死的,要是能有类似 kubeconfig 上下文的东西就好了…

这就是特殊成分发挥作用的地方–Docker contexts。我觉得自己像个白痴,因为直到一周前,我脑子里突然冒出上述想法时,我才知道它们的存在🫠。

不过,用户还是无法访问已安装的守护进程的插座。授权他们在专用用户的 $HOME (默认情况下插座位于此)中自由工作有点不妥。

  1. 将守护进程配置为使用单独的套接字位置。
  2. 为那些必须能够创建和管理无权限容器的用户创建一个 rootlesskit 组。
  3. 设置套接字及其目录的访问权限。
  4. 在用户的 docker cli 配置中添加新的上下文。

配置

前提条件

首先需要安装以下设备:

  • Docker(包括 docker-ce-rootless-extras 软件包)
  • systemd-container
  • uidmap
  • dbus-user-session
  • acl

以下解决方案要求使用支持系统的 Linux 发行版。

 

守护进程本身

  1. 创建用户。
    #useradd -m cr -s $(which nologin)
  2. 创建组。
    #groupadd -U j_doe,e_alderson rootlesskit

    -U选项是最近才添加的,是在2020年,所以您的发行版可能还没有这个选项。

  3. 启用已创建用户的linger功能。
    #loginctl enable-linger cr
  4. 安装守护进程。
    #machinectl shell cr@ /bin/bash -c 'dockerd-rootless-setuptool.sh install'
  5. 允许特权端口(可选)。
    #setcap cap_net_bind_service=ep $(which rootlesskit)

    每次更新 docker-ce-rootless-extras 软件包后,你都需要重新启用这些功能。我相信有更好的方法,但找不到。

  6. 为包含套接字的目录创建模板。
    cat >> END > /usr/lib/tmpfiles.d/rootless.conf
    D /run/rootlesskit 1700 cr cr - - -
    a+ /run/rootlesskit - - - - g:rootlesskit:r-x,default:g:rootlesskit:rw-
    END

    ☝️ 用于告诉 systemd 在启动时创建 /run/rootlesskit 目录。点击此处了解更多。

    由于我们不希望 rootlesskit 组中的任何人删除套接字,因此在目录上设置了一个粘性位。

    以 a+ 开头的 ACL 行确保人们可以读写该目录,但不能删除它。

  7. 覆盖守护进程服务以更改套接字路径。
    1. 打开覆盖文件进行编辑。
      machinectl shell cr@ /bin/bash -c 'systemctl --user edit docker'
    2. 添加以下内容 👇.
      # ExecStart is specified twice to reset the previous value first.
      
      [Service]
      ExecStart=
      ExecStart=/usr/bin/dockerd-rootless.sh -H unix:///run/rootlesskit/docker.socket
  8. 重新启动服务器以使更改生效。
    systemctl reboot

 

Docker Context

现在,为 rootlesskit 组中的每个用户添加一个新的上下文。

docker context create rootless --docker host=unix:///run/rootlesskit/docker.socket

自动化

我最近开始为 Linux 开发一个 Ansible 集合,其中包含一个用于自动执行此设置的角色。目前,它还很原始,没有文档,而且只支持 Ubuntu,但随着时间的推移,情况会越来越好。

一旦我添加了至少一些文档,该版本库就会公开。敬请期待!

关于 Systemd 资源控制的说明

问题所在

如果你需要限制每个容器的资源使用量,最好知道在某些系统中,非 root 用户需要手动配置。

我在 Ubuntu 虚拟机上测试网站部署时就遇到了这个问题。默认情况下,没有创建用于 CPU 管理的委托控制器。

错误信息如下:

NanoCPUs can not be set, as your kernel does not support CPU cfs period/quota or the cgroup is not mounted

如何解决

为 user@ systemd 服务创建覆盖,并指定要创建委托控制器的资源。

一般来说,应用覆盖后注销并重新登录即可。对于长期运行的后台进程,重启更为简单。

点击此处了解有关 systemd 资源控制的更多信息。

手动操作

  1. 打开 user@ 服务覆盖文件。
    systemctl edit user@.service
  2. 👇 添加以下内容。
    [Service]
    Delegate=memory pids cpu cpuset

Using Ansible

- name: Enable Systemd Resource Control Delegation
  hosts: all

  tasks:
  - name: Ensure systemd User Service Override Dir Present
    become: true
    ansible.builtin.file:
      state: directory
      path: /etc/systemd/system/user@.service.d/
      mode: '0755'

  - name: Delegate Resource Management
    become: true
    register: delegate_override
    ansible.builtin.copy:
      content: |
        [Service]
        Delegate=memory pids cpu cpuset
      dest: /etc/systemd/system/user@.service.d/override.conf
      mode: '0644'

  - name: Restart Server
    become: true
    when: delegate_override.changed
    ansible.builtin.reboot:

结果

现在,我们有了一种使用 Docker 管理有权限和无权限容器的便捷方法。

该解决方案还具有可扩展性,因为要让新用户管理服务器上的非特权容器,只需将他们添加到一个组,并创建一个上下文🎉。

vagrant@ubuntu-jammy:~$ docker context use rootless
rootless
Current context is now "rootless"
vagrant@ubuntu-jammy:~$ docker context ls
NAME         DESCRIPTION                               DOCKER ENDPOINT                         ERROR
default      Current DOCKER_HOST based configuration   unix:///var/run/docker.sock
rootless *                                             unix:///run/rootlesskit/docker.socket
vagrant@ubuntu-jammy:~$ docker compose ls
NAME                STATUS              CONFIG FILES
observability       running(3)          /var/lib/compose_projects/observability/compose.yml
vagrant@ubuntu-jammy:~$ docker --context default compose ls
NAME                STATUS              CONFIG FILES
httpd               running(1)          /var/lib/compose_projects/httpd/compose.yml
vagrant@ubuntu-jammy:~$

感谢您的阅读,祝您度过愉快的一天!(^ ~ ^ )

如果您有任何问题/建议,或发现错误,请联系我!

本文文字及图片出自 Rootless Docker in a Multi-user Environment — It's All About Context

你也许感兴趣的:

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注