在实例启动时,通过Rootless Docker启动compose.yml

总结

我看了一些使用Rootless模式运行Docker的文章。

    • 内容が古くなっている記事が多い。

 

    systemd に compose.yml を登録するところまでやっている記事が探した限り無い。

所以,我总结了截至2023年8月的最新简化步骤。

只需使用以下方案以执行本文章的步骤:

通过在启动时启动无根模式的 Docker 引擎服务。
同时启动 Docker 引擎服务,并开始任意的 compose.yml 配置。

这样就可以实现。

我们将使用AWS EC2的Debian 12实例作为基础。

您也可以使用VirtualBox。在这种情况下,请在使用VirtualBox创建的虚拟机上安装Debian 12,并安装Docker引擎。

我们将基本按照以下的官方文件进行实施。

    • https://docs.docker.com/engine/install/debian/

 

    https://docs.docker.com/go/rootless/

首先安装Docker引擎。

    1. 我要在AWS上创建根用户并注册信用卡。

 

    1. 使用AWS的根用户创建IAM账户并授予PowerUserAccess角色。

 

    1. 在IAM账户中使用30GB存储容量的Debian 12创建t2.micro实例。

在创建实例之前,请先创建一个安全组,其中包括“允许传入的端口22”。在创建实例时指定该安全组。
在创建实例之前,请先创建一个密钥对。创建密钥对时自动下载私钥。在创建实例时指定该密钥对。

确认能够使用admin用户通过SSH登录到实例。
在Debian 12上安装Docker引擎。https://docs.docker.com/engine/install/debian/

在官方文档的最后执行sudo docker run hello-world,但在本文的步骤中不需要在此时执行。

安装无根模式的 Docker

我们将 Docker 以 Rootless 模式启动。 https://docs.docker.com/go/rootless/

通常情况下,停止安装的 Docker 引擎。

首先,停止以常规安装状态启动的 Docker 引擎。

如果在AWS EC2上的Debian 12上已正常安装了Docker引擎,那么可以使用admin用户。

sudo systemctl disable --now docker.service docker.socket

执行。

需要额外安装必要的软件包。

如果是Debian 12的话

sudo apt-get install uidmap

执行。

对于Ubuntu来说,应该也是一样的(未经验证)。

根据参考的官方文件,提到了”如果没有安装 dbus-user-session,则进行安装”,但是在AWS EC2的Debian 12上,它已经默认安装了。

创建无根用户

创建一个新的无根用户。

这是因为在 AWS EC2 上的 Debian 12,默认用户 admin 可以无需密码就执行 sudo 命令,这会造成安全风险。为了降低风险,我们想要使用一个无法执行 sudo 命令的用户。

以admin用户的状态下,执行以下操作。

sudo useradd -m rootless             # ホームディレクトリ有りでユーザーを新規に作成する
sudo chsh -s /bin/bash rootless      # シェルをbashに変更する(必須ではない)
sudo passwd -l rootless              # 新規で作成した rootless ユーザーのパスワードを無効化する(ログインは ssh のみ)

如果rootless用户可以创建,那么可以以管理员用户的状态创建。

sudo su - rootless

作为无根用户,创建一个.ssh目录并将公钥写入到”authorized_keys”文件中。

我会确认与相应私钥匹配的rootless用户能否通过ssh登录。

免安装 Rootless 模式

使用SSH登录到非root用户。

dockerd-rootless-setuptool.sh check
dockerd-rootless-setuptool.sh install

执行

如果你按照官方文档的步骤安装了 Docker 引擎的话,那么 dockerd-rootless-setuptool.sh 应该已经被安装了。

如果不通过SSH登录,则在dockerd-rootless-setuptool.sh内部执行的systemctl –user show-environment命令无法正常运行(由于缺少XDG_RUNTIME_DIR环境变量),从而导致dockerd-rootless-setuptool.sh无法正确执行。

直接使用ssh登录(确切来说不一定需要ssh,只要经过“登录”过程就可以访问),环境变量XDG_RUNTIME_DIR会自动设置,并且dockerd-rootless-setuptool.sh将能够正常执行。

最后以 rootless 用户通过 SSH 登录

docker run hello-world

如果成功,Rootless模式的引入将完成。

在这个状态下,除了 rootless 用户之外的用户(如 admin 用户或 root 用户等)无法使用 docker ps 等 docker 命令进行操作。这是正常状态,不表示环境出现故障。请继续进行下一步操作。

通过compose.yml文件启动服务

使用 SSH 登录到无 root 权限的用户,并执行以下操作。

创建名为 /home/rootless/work/test 的目录,并创建 /home/rootless/work/test/compose.yml。

version: "3"

services:
  nginx:
    image: nginx:latest
    ports:
      - 8080:80

请确保不要忘记在AWS EC2的安全组中添加”允许8080端口入站”的规则。

在这种状态下

docker compose up -d
docker compose down

请确认启动了 NGINX 时是否会出现欢迎页面的显示或不显示的情况。

有关可用端口号的使用

在这里,对于 ports: – 8080:80 的端口号设定,有两种限制。

    • Rootless モードの制約として 1024 以下のポート番号は使えません。(設定すれば使えますが本稿の範囲外とします)

ports: – 80:80 としていないのはこれが理由です。

最近のブラウザの制約として 10080 などの特定のポート番号は「ブラウザが」表示を制限します。

ports: – 10080:80 など該当するポート番号を使用してしまうと「curl ではデータが正常に受信できるがブラウザだと表示できない」という状況になります。
AWS などであれば HTTPS を終端するロードバランサの配下で 10080 番ポートで HTTP を待ち受けるという構成が可能と思われます。(未確認)

将 compose.yml 文件中的服务注册到 systemd 上。

所有操作都将在通过SSH以rootless用户登录后进行。
创建/home/rootless/.config/systemd/user/sample-nginx.service文件。

[Unit]
Description=Sample NGINX
Requires=docker.service
After=docker.service

[Service]
ExecStart=/usr/bin/docker compose -f /home/rootless/work/test/compose.yml up
ExecStop=/usr/bin/docker compose -f /home/rootless/work/test/compose.yml down
Restart=always

[Install]
WantedBy=default.target

在操作 systemctl 时,需要添加 –user 选项。

systemctl --user daemon-reload
systemctl --user status sample-nginx.service
systemctl --user start sample-nginx.service
systemctl --user stop sample-nginx.service
systemctl --user enable sample-nginx.service

开始后,将显示出NGINX的欢迎页面;停止后,页面将不再显示。

启用后,当通过 SSH 以非根用户身份登录到已重新启动的 EC2 实例时,将同时启动 Docker 服务和 sample-nginx.service。

换句话说,如果不以“ssh登录为rootless用户”的设定,Docker服务和sample-nginx.service将无法运行,也无法通过浏览器访问NGINX的欢迎页面。

总结一下,如果能够按照到这里的步骤进行实施,

    1. 启动(或重新启动)AWS EC2实例。

 

    1. 无论是root、admin还是rootless账户,都可以在浏览器中访问实例的IP地址(和端口号)而无需登录。

此时,浏览器将无法显示NGINX的欢迎页面。

通过ssh登录rootless用户,然后在浏览器中访问实例的IP地址(和端口号)。

浏览器将显示NGINX的欢迎页面。

应该是这个动作。

在实例启动时启动compose.yml

以 root 权限(不是 rootless 用户)

loginctl enable-linger rootless
loginctl show-user rootless

执行。
show-user 的执行结果如下所示。Linger 项目变为了 yes。

UID=1001
GID=1001
Name=rootless
Timestamp=Mon 2023-08-28 08:18:24 JST
TimestampMonotonic=13729055
RuntimePath=/run/user/1001
Service=user@1001.service
Slice=user-1001.slice
Display=2
State=active
Sessions=2
IdleHint=no
IdleSinceHint=1693180144047894
IdleSinceHintMonotonic=1853696593
Linger=yes

重启实例,并在不登录任何帐户(root、admin、rootless)的情况下,在浏览器中确认是否显示NGINX的欢迎页面。

请注意,需要等待几分钟才能开始运行 compose.yml 文件的配置,并执行重新启动实例的操作。

另外,

loginctl disable-linger rootless

当您执行该操作时,您会发现仅仅重新启动实例是无法显示NGINX的欢迎页面的。但是,如果您使用rootless用户通过ssh登录,就可以恢复到可以显示欢迎页面的状态。请确认这一点。

最终再一次

loginctl enable-linger rootless

我们做一下吧。

总结

    1. 安装无根模式的Docker。

 

    1. 对于配置的服务,执行”systemctl –user enable 配置的服务”。(仅需执行一次)

执行”loginctl enable-linger rootless”。(仅需执行一次)

通过掌握以上三个要点,可以实现在启动时使用Rootless模式的Docker自动开始compose.yml配置。

附加内容:在 VSCode 中连接到 Rootless 容器。

在 rootless 用户的 .profile 文件中添加一行,就可以在运行在 Rootless 模式的容器上,使用 VSCode 进行附加连接。

rootless@ip-172-31-44-83:~$ id
uid=1001(rootless) gid=1001(rootless) groups=1001(rootless)

rootless@ip-172-31-44-83:~$ diff -u ~/.profile.2023-0829-2231 ~/.profile
--- /home/rootless/.profile.2023-0829-2231      2023-08-29 13:32:27.460746100 +0000
+++ /home/rootless/.profile     2023-08-29 13:27:01.819819290 +0000
@@ -25,3 +25,6 @@
 if [ -d "$HOME/.local/bin" ] ; then
     PATH="$HOME/.local/bin:$PATH"
 fi
+
+export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock
+

编辑.profile后,使用VSCode的Remote-SSH扩展连接到AWS EC2实例的rootless用户。在连接状态下,尝试使用Dev Container扩展附加到容器时,可以选择一个运行在Rootless模式下的容器作为附加目标。

bannerAds