mirror of
https://github.com/moby/moby.git
synced 2026-08-03 22:51:03 +00:00
hack: run rootless daemon in a systemd user session when systemd is present
Previously, the rootless-systemd CI mode failed with:
open /sys/fs/cgroup/user.slice/user-1000.slice/cgroup.controllers: no such file or directory
on every container start. The daemon auto-selects the systemd cgroup
driver (cgroup v2 + systemd detected), but the test harness launched
dockerd-rootless.sh via plain "sudo" with a fabricated XDG_RUNTIME_DIR,
so there was no systemd user session at all: no user-${uid}.slice, no
user@${uid}.service, and no user D-Bus socket for runc to talk to.
withRootless() (daemon/oci_linux.go) then failed reading the controllers
file at every container start.
Set up the environment the way it is documented for production rootless
installations instead:
- hack/make/.integration-daemon-start: when systemd is running, enable
lingering for unprivilegeduser (which starts user@${uid}.service),
use /run/user/${uid} as XDG_RUNTIME_DIR, and export
DBUS_SESSION_BUS_ADDRESS so that runc can find the systemd user
manager. The variable also propagates to the daemons spawned by the
test suite (sudo --preserve-env in internal/testutil/daemon), whose
XDG_RUNTIME_DIR points to a non-standard location.
- hack/dind-systemd: delegate the cpu/cpuset/io/memory/pids cgroup
controllers to unprivileged users, matching
https://docs.docker.com/engine/security/rootless/#limiting-resources
Fixes the "test (amd64, *, rootless-systemd)" CI failures tracked in
issue 44084.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
This commit is contained in:
@@ -104,6 +104,16 @@ EOF
|
||||
systemctl enable collect-firewalld-logs.service
|
||||
fi
|
||||
|
||||
# Delegate cgroup v2 controllers to unprivileged users, so that the rootless
|
||||
# daemon can use the systemd cgroup driver and set resource limits. This is
|
||||
# the setup documented for production rootless installations:
|
||||
# https://docs.docker.com/engine/security/rootless/#limiting-resources
|
||||
mkdir -p /etc/systemd/system/user@.service.d
|
||||
cat > /etc/systemd/system/user@.service.d/delegate.conf << EOF
|
||||
[Service]
|
||||
Delegate=cpu cpuset io memory pids
|
||||
EOF
|
||||
|
||||
env > /etc/docker-entrypoint-env
|
||||
|
||||
cat > /etc/systemd/system/docker-entrypoint.target << EOF
|
||||
|
||||
@@ -84,14 +84,41 @@ if [ -n "$DOCKER_ROOTLESS" ]; then
|
||||
fi
|
||||
user="unprivilegeduser"
|
||||
uid=$(id -u $user)
|
||||
# shellcheck disable=SC2174
|
||||
mkdir -p -m 700 "/tmp/docker-${uid}"
|
||||
chown "$user" "/tmp/docker-${uid}"
|
||||
if [ -d "/run/systemd/system" ]; then
|
||||
# Set up a systemd user session for the user, with cgroup delegation
|
||||
# (see hack/dind-systemd), so that the daemon and the tests can use
|
||||
# the systemd cgroup driver. This mimics the setup documented for
|
||||
# production ("loginctl enable-linger"), where dockerd-rootless.sh
|
||||
# runs inside user@${uid}.service.
|
||||
# https://github.com/moby/moby/issues/44084
|
||||
xdg_runtime_dir="/run/user/${uid}"
|
||||
tries=0
|
||||
# Retried in a loop: this may race with systemd-logind/dbus startup,
|
||||
# as docker-entrypoint.service has no ordering dependency on them.
|
||||
until loginctl enable-linger "$user" && [ -S "${xdg_runtime_dir}/bus" ]; do
|
||||
tries=$((tries + 1))
|
||||
if [ $tries -gt 30 ]; then
|
||||
echo >&2 "# failed to set up a systemd user session for $user (no ${xdg_runtime_dir}/bus)"
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
# Propagated to the daemon started below, and to the test suite, which
|
||||
# passes it on to the daemons it spawns (sudo --preserve-env in
|
||||
# internal/testutil/daemon). runc needs it to find the systemd user
|
||||
# manager when $XDG_RUNTIME_DIR points to a non-standard location.
|
||||
export DBUS_SESSION_BUS_ADDRESS="unix:path=${xdg_runtime_dir}/bus"
|
||||
else
|
||||
xdg_runtime_dir="/tmp/docker-${uid}"
|
||||
# shellcheck disable=SC2174
|
||||
mkdir -p -m 700 "${xdg_runtime_dir}"
|
||||
chown "$user" "${xdg_runtime_dir}"
|
||||
fi
|
||||
chmod -R o+w "$DEST"
|
||||
# The rootless daemon won't be able to load modules for tests that need them, so do it here.
|
||||
# There's no modprobe in the dev container, so https://x.com/lucabruno/status/902934379835662336
|
||||
ip link show br_netfilter || true
|
||||
dockerd="sudo -u $user -E -E XDG_RUNTIME_DIR=/tmp/docker-${uid} -E HOME=/home/${user} -E PATH=$PATH -- dockerd-rootless.sh"
|
||||
dockerd="sudo -u $user -E -E XDG_RUNTIME_DIR=${xdg_runtime_dir} -E HOME=/home/${user} -E PATH=$PATH -- dockerd-rootless.sh"
|
||||
fi
|
||||
|
||||
if [ -z "$DOCKER_TEST_HOST" ]; then
|
||||
|
||||
Reference in New Issue
Block a user