在实例启动时,通过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引擎。
-
- 我要在AWS上创建根用户并注册信用卡。
-
- 使用AWS的根用户创建IAM账户并授予PowerUserAccess角色。
-
- 在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的欢迎页面。
总结一下,如果能够按照到这里的步骤进行实施,
-
- 启动(或重新启动)AWS EC2实例。
-
- 无论是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
我们做一下吧。
总结
-
- 安装无根模式的Docker。
-
- 对于配置的服务,执行”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模式下的容器作为附加目标。