Compartir comentarios
Las respuestas se generan en base a la documentación.

Consejos

Uso avanzado

Demonio

El archivo de unidad de systemd se instala como ~/.config/systemd/user/docker.service.

Utiliza systemctl --user para gestionar el ciclo de vida del demonio:

$ systemctl --user start docker

Para iniciar el demonio en el arranque del sistema, habilita el servicio de systemd y el lingering (persistencia de sesión):

$ systemctl --user enable docker
$ sudo loginctl enable-linger $(whoami)

No se admite iniciar Docker Rootless como un servicio de systemd a nivel de todo el sistema (/etc/systemd/system/docker.service), incluso con la directiva User=.

Para ejecutar el demonio directamente sin systemd, debes ejecutar dockerd-rootless.sh en lugar de dockerd.

Se deben configurar las siguientes variables de entorno:

  • $HOME: el directorio de inicio
  • $XDG_RUNTIME_DIR: un directorio efímero al que solo puede acceder el usuario esperado, por ejemplo, ~/.docker/run. El directorio se debe eliminar en cada apagado del anfitrión. El directorio puede estar en tmpfs, sin embargo, no debe estar bajo /tmp. Ubicar este directorio bajo /tmp podría ser vulnerable a ataques TOCTOU (Time-of-Check to Time-of-Use).

Es importante tener en cuenta que con las rutas de directorio:

  • La ruta del socket se establece en $XDG_RUNTIME_DIR/docker.sock por defecto. $XDG_RUNTIME_DIR se configura normalmente como /run/user/$UID.
  • El directorio de datos se establece en ~/.local/share/docker por defecto. El directorio de datos no debe estar en NFS.
  • El directorio de configuración del demonio se establece en ~/.config/docker por defecto. Este directorio es diferente de ~/.docker, que es utilizado por el cliente.

Cliente

Desde Docker Engine v23.0, dockerd-rootless-setuptool.sh install configura automáticamente la CLI de docker para utilizar el contexto rootless.

Antes de Docker Engine v23.0, el usuario tenía que especificar de forma explícita la ruta del socket o el contexto de la CLI.

Para especificar la ruta del socket utilizando $DOCKER_HOST:

$ export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock
$ docker run -d -p 8080:80 nginx

Para especificar el contexto de la CLI utilizando docker context:

$ docker context use rootless
rootless
Current context is now "rootless"
$ docker run -d -p 8080:80 nginx

Buenas prácticas

Docker Rootless en Docker

Para ejecutar Docker Rootless dentro de Docker "rootful" (con privilegios de root), utiliza la imagen docker:<version>-dind-rootless en lugar de docker:<version>-dind.

$ docker run -d --name dind-rootless --privileged docker:25.0-dind-rootless

La imagen docker:<version>-dind-rootless se ejecuta como un usuario no root (UID 1000). Sin embargo, se requiere --privileged para deshabilitar seccomp, AppArmor y las máscaras de montaje.

Exponer el socket de la API de Docker a través de TCP

Para exponer el socket de la API de Docker a través de TCP, debes iniciar dockerd-rootless.sh con DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS="-p 0.0.0.0:2376:2376/tcp".

$ DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS="-p 0.0.0.0:2376:2376/tcp" \
  dockerd-rootless.sh \
  -H tcp://0.0.0.0:2376 \
  --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem

Exponer el socket de la API de Docker a través de SSH

Para exponer el socket de la API de Docker a través de SSH, debes asegurarte de que $DOCKER_HOST esté configurada en el anfitrión remoto.

$ ssh -l <REMOTEUSER> <REMOTEHOST> 'echo $DOCKER_HOST'
unix:///run/user/1001/docker.sock
$ docker -H ssh://<REMOTEUSER>@<REMOTEHOST> run ...

Enrutar paquetes ping

En algunas distribuciones, ping no funciona por defecto.

Añade net.ipv4.ping_group_range = 0 2147483647 a /etc/sysctl.conf (o a /etc/sysctl.d) y ejecuta sudo sysctl --system para permitir el uso de ping.

Exponer puertos privilegiados

Para exponer puertos privilegiados (< 1024), establece CAP_NET_BIND_SERVICE en el binario rootlesskit y reinicia el demonio.

$ sudo setcap cap_net_bind_service=ep $(which rootlesskit)
$ systemctl --user restart docker

O añade net.ipv4.ip_unprivileged_port_start=0 a /etc/sysctl.conf (o a /etc/sysctl.d) y ejecuta sudo sysctl --system.

Limitar recursos

Limitar recursos con banderas de docker run relacionadas con cgroup, como --cpus, --memory o --pids-limit, solo se admite cuando se ejecuta con cgroup v2 y systemd. Consulta Cambiar la versión de cgroup para habilitar cgroup v2.

Si docker info muestra none como Cgroup Driver, no se cumplen las condiciones. Cuando estas condiciones no se cumplen, el modo rootless ignora las banderas de docker run relacionadas con cgroup. Consulta Limitar recursos sin cgroup para conocer alternativas.

Si docker info muestra systemd as Cgroup Driver, se cumplen las condiciones. Sin embargo, por lo general, solo los controladores memory y pids se delegan a usuarios no root por defecto.

$ cat /sys/fs/cgroup/user.slice/user-$(id -u).slice/user@$(id -u).service/cgroup.controllers
memory pids

Para permitir la delegación de todos los controladores, debes cambiar la configuración de systemd de la siguiente manera:

# mkdir -p /etc/systemd/system/[email protected]
# cat > /etc/systemd/system/[email protected]/delegate.conf << EOF
[Service]
Delegate=cpu cpuset io memory pids
EOF
# systemctl daemon-reload
Note

Delegar cpuset requiere systemd 244 o posterior.

Limitar recursos sin cgroup

Incluso cuando cgroup no está disponible, puedes seguir utilizando los tradicionales ulimit y cpulimit, aunque funcionan a nivel de granularidad de proceso en lugar de granularidad de contenedor, y el proceso del contenedor los puede deshabilitar de forma arbitraria.

Por ejemplo:

  • Para limitar el uso de CPU a 0.5 núcleos (similar a docker run --cpus 0.5): docker run <IMAGE> cpulimit --limit=50 --include-children <COMMAND>
  • Para limitar el VSZ máximo a 64MiB (similar a docker run --memory 64m): docker run <IMAGE> sh -c "ulimit -v 65536; <COMMAND>"
  • Para limitar el número máximo de procesos a 100 por UID con espacio de nombres 2000 (similar a docker run --pids-limit=100): docker run --user 2000 --ulimit nproc=100 <IMAGE> <COMMAND>