Introduction
Le mode ‘rootless’ a été introduit dans Docker récemment et a quitté le statut expérimental depuis la version 20.10. Ce mode permet de lancer le daemon docker et les containeurs en tant qu’utilisateur sans les droits ‘root’ et répond dans ce sens aux principales critiques à son encontre. Ce mode comporte par contre quelques limitations de bases qui pour certaines peuvent être contournées. Nous allons voir dans cet article comment installer Docker en mode « rootless » en partant d’une installation existante.
Les principales limitations de ce mode sont :
- Les réseaux virtuels (MacVlan) ne sont pas supportés,
- appArmor n’est pas supporté,
- Le protocole SCTP n’est pas supporté,
- Il n’est pas possible d’atteindre l’adresse IP interne du containeur de l’extérieur,
- L’option expérimental ‘checkpoint’ dans Docker n’est pas supporté,
- Les ports <1024 ne sont pas utilisables par défaut,
- Les limitations de ressources ne sont pas possible par défaut,
- La commande ping n’est pas autorisé par défaut
Nous verrons dans la suite de l’article que les limitations en gras et orange sont déblocables en modifiant la configuration système.
Préparation de l’installation du mode ‘rootless’
Nous allons préparer au maximum en amont la bascule en mode ‘rootless’ pour optimiser l’installation et éviter les mauvaises surprises.
Activation des répertoires utilisateurs
L’activation des répertoires utilisateurs est un pré-requis pour utiliser le mode ‘rootless’ car il hébergera maintenant le ‘daemon’ docker. Il faut l’activer dans l’interface d’administration d’OMV. Personnellement j’ai monté le répertoire ‘/home’ dans mon disque système qui reste inutilisée.

Création utilisateur ‘omdocker’
Je vous renvoi à l’article de création d’un utilisateur ‘omdocker’
Organisation des répertoires docker (optionnelle)
Nous allons en profiter pour réorganiser l’architecture de nos répertoires contenant les configurations et les données des containeurs. Par défaut votre installation des données liées à Docker devrait se trouver dans le répertoire /var/lib/docker.
Personnellement j’ai re-créé deux répertoires :
- /srv/docker/config : Il contiendra les répertoires de toutes les configurations des containeurs,
- /srv/docker/data : Il contiendra les répertoires des données Docker : containeurs, images, volumes… etc
Nous aurons deux possibilités après avoir installer Docker en mode ‘Rootless’ qui dépendront surtout si vous choisissez de changer de répetoire de stockage des données Doker. Vous pourrez soit re-deployer chaque containeurs en ayant pris soin d’adapter la pile si nécessaire; soit recopier toutes les données Docker vers le nouveau répertoire. Le répertoire de configuration est lui par contre repris telle quelle.
Configuration du ‘daemon’ Docker
Le fichier de configuration ‘daemon.json’ se trouve dans le répertoire /etc/docker/ pour une installation de Docker normale. Il se situera maintenant dans le répertoire /home/omdocker/.config/docker/ de l’utilisateur ‘omdocker’ qui lancera le ‘daemon’ docker.
Vous pouvez le recopier dans votre répertoire utilisateur et modifier la ligne ‘data-root‘ si nécessaire. Le mode ‘rootless’ est plus restrictif et si vous aviez sécuriser auparavant votre ‘daemon’, il faudra modifier sa configuration. Je vous donne la configuration de mon ‘daemon’ qui fonctionne chez moi.
J’ai rajouté que la directive ‘log-driver‘, ‘no-new-privileges‘ et ‘live-restore‘ dans le fichier : .

Configuration du firewall (optionnelle)
La ‘daemon’ Docker n’a plus les privilèges pour gérer lui même les ‘iptables’. Il faut rajouter manuellement des règles pour les containeurs si vous avez configurer votre firewall strictement :
- Portainer : Il faudra autoriser le port 9000 en entrée,
- Containeurs : Il faudra ouvrir une plage de port en entrée pour tous vos containeurs,
- Swag / Nginx : Il faudra rajouter une règle spécifique pour faire le lien entre l’adresse ip interne et l’adresse ip externe du containeur.
INPUT ACCEPT 192.168.1.0/24:ALL IP_NAS:8200-8300:TCP (Docker In)
INPUT ACCEPT 192.168.1.0/24:ALL IP_NAS:9000:TCP (Portainer In)
INPUT ACCEPT ALL:ALL IP_SWAG_INTERNE:80:TCP (Container) Swag In
INPUT ACCEPT IP_NAS:PORT_EXT IP_SWAG_INTERNE:ALL:TCP Swag Out (Container)
Déblocage des limitations
Nous avons vu plus haut que la version ‘rootless’ avait des limitations. Nous allons ici modifier le fonctionnement du kernel pour débloquer ces limitations.
Déblocage des ports < 1024 et du ‘ping’
Les modifications s’effectuent au niveau de la configuration des variables systèmes avec le fichier /etc/sysctl.conf :
On vas décommenter la ligne 28 et créer les deux lignes suivantes en fin de fichiers vers la ligne 70 : ‘sudo nano /etc/sysctl.conf‘
#28 net.ipv4.ip_forward=1 # facultatif
...
#70 net.ipv4.ip_unprivileged_port_start=0
#71 net.ipv4.ping_group_range = 0 2147483647
On met à jour le système avec la commande : ‘sudo sysctl –system‘. Vous devriez voir en fin de commande les 3 lignes prises en compte par le système :

Déblocage des limitations de ressources
Il y a un pré-requis pour que votre système puisse utilisé les limitations de ressources; il faut vérifier que le noyau le supporte la V2 de ‘cgroups‘. Normalement Debian le supporte depuis la version 11; mais vous pouvez le vérifier en tapant la commande suivante :
$ grep cgroup /proc/filesystems
Vous devriez avoir en retour apparaitre la mention V2, si votre système le supporte :
nodev cgroup
nodev cgroup2
Pour savoir quelle version votre système utilise actuellement, il faut vérifier la présence de ce fichier : /sys/fs/cgroup/cgroup.controllers. S’il existe tout vas bien; s’il n’existe pas c’est que votre système utilise la V1 de ‘cgroups’ et il faudra modifier les paramètres de lancement du système pour utiliser la V2.
Dans le cas ou le système n’utilise pas la V2, il faut créer le ficher de configuration suivant : ‘/etc/default/grub.d/cgroup.cfg‘ et relancer le NAS en tapant les commandes suivantes :
$ sudo echo "systemd.unified_cgroup_hierarchy=true" > cgroup.cfg
$ update-grub ; reboot
Les utilisateurs peuvent seulement utiliser les contrôleurs de type ‘memory’ et ‘pids, il faut donc modifier la configuration de ‘systemd’ pour pouvoir utiliser les autres contrôleurs en tapant les commandes suivantes :
$ 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
$ systemctl daemon-reload
Prérequis divers pour le mode ‘rootless’
Vous aurez besoin aussi d’installer ces 4 paquets supplémentaires en tapant les commandes suivantes :
$ sudo apt install uidmap
$ sudo apt-get install -y dbus-user-session
$ sudo apt-get install -y slirp4netns
$ sudo apt-get install -y fuse-overlayfs
Installation de docker ‘rootless’
Désinstallation de la version actuelle
On commence par arrêter tous les containeurs et le daemon docker, puis on supprime tous les réseaux Docker :
$ sudo docker stop $(sudo docker ps -a -q)
$ sudo systemctl disable --now docker.service docker.socket
$ sudo docker network rm *
Puis on désinstalle ‘Portainer’ et ‘Docker’ via l’interface d’administration :


Nous recopions toutes les configurations des containeurs dans le futur emplacement si vous l’avez changer. Concernant les données des containeurs, soit vous les conserver, soit vous redéployer à nouveau tous les containeurs un par un. Pour ma part je repars sur des données ‘propre’ et je redéployerais tous les containeurs un par un avec Docker compose.
Remarque : Si vous constatez qu’il existe des ‘pids’ de containeurs (‘ps aux | grep docker‘) encore en vie, il vous faudra relancer le NAS pour ne pas perturber la suite de la procédure. |
Installation de docker
On commence par installer les paquets Docker de base via le dépôt officiel, on vérifie que Docker fonctionne bien et on arrête le daemon :
$ sudo apt install docker-ce docker-ce-cli containerd.io
$ sudo docker info
$ sudo systemctl status docker
$ sudo systemctl disable --now docker.service docker.socket
On termine en rajoutant l’utilisateur ‘omdocker‘ au contrôleur ‘systemd‘ et on vérifie :
$ loginctl enable-linger omdocker
$ ls /var/lib/systemd/linger
Pour l’installation du mode ‘rootless’, vous avez deux possibilités. J’ai choisi personnellement la 2eme solution. Avant de lancer le script d’installation et pour la 2eme solution, il faut ouvrir une session utilisateur avec l’utilisateur ‘Docker’ que vous avez créer en début de cet article.
Remarque : Après avoir ouvert une session ‘omdocker‘, on tape la commande suivante pour relancer le daemon en tant que ‘user’ : ‘systemctl –user daemon-reload‘ |
Installation via le gestionnaire de paquet Debian
$ sudo apt-get install -y docker-ce-rootless-extras
Ce package vas installer le script ‘dockerd-rootless-setuptool.sh‘ dans le répertoire /usr/bin. On lance l’installation avec l’utilisateur ‘omdocker’ :
$ su omdocker
$ sh /usr/bin/dockerd-rootless-setuptool.sh install
L’installer directement à partir de l’URL officiel
Le scrip vas créer un répertoire ‘bin’ dans /home/omdocker contenant les exécutables ‘Docker’.
$ curl -fsSL https://get.docker.com/rootless | sh
Normalement si tout s’est bien passé, vous devriez avoir le déroulement suivant. Les variables entourées en rouge doivent apparaitre telle quelle; si vous avez un chemin différent pour ‘DOCKER_HOST‘ (avec l’ID de votre utilisateur), c’est que quelque chose cloche et que vous avez du oublier quelque :

Par exemple dans l’écran suivant, vous avez du oublier de rajouter l’utilisateur au contrôleur ‘systemd‘ et le chemin ‘DOCKER_HOST‘ n’est pas celui qu’il devrait être. Il est très important de suivre la procédure dans cet ordre précis.

Pour terminer il faut rajouter les deux lignes spécifiés en fin d’exécution du script à vos variables d’environnements. Ajouter les en fin de votre ficher ‘.bashrc’ ou ‘.zshrc’ en modifiant l’ID de votre utilisateur.
export PATH=/home/omdocker/bin:$PATH
export DOCKER_HOST=unix:///run/user/1003/docker.sock
On recharge ensuite l’environnement en tapant la commande ‘source ~/.zshrc‘ ou ‘source ~/.bashrc‘ suivant celui que vous utiliser.
On vérifie que tout est bien configuré et on insique au système de lancer docker au démarrage en tapant les commandes suivantes :
Remarque : toute les commandes ‘systemctl‘ devront se faire en mode utilisateur dorénavant avec la directive ‘–user‘ |
$ systemctl --user status docker
$ docker info
$ systemctl --user enable docker


Tout est bon; nous utilisons ‘Syslog‘, ‘Systemd‘, ‘Cgroup‘ version 2 et le ‘Root Dir‘ a bien été pris en compte.
Installation du containeur Portainer
Remarque : si la variable d’environnent ‘DOCKER_CONTENT_TRUST‘ est activée, il faut la désactiver via la commande : ‘export DOCKER_CONTENT_TRUST=0‘, sinon le lancement de ‘Portainer’ vas retourner une erreur de type ‘remote trust data does not exist for docker.io’. |
On vas installer ‘Portainer’ en tapant la commande suivante; vous devrez adapter les paramètres en gras à votre configuration :
$ docker run -d \
-p VOTRE_IP:8000:8000 \
-p VOTRE_IP:9000:9000 \
--name=portainer \
--restart=unless-stopped \
--cpus=0.5 \
--cpu-shares=512 \
--pids-limit=100 \
--memory=500m \
-v /volume/docker/config/portainer:/data \
-v /run/user/ID/docker.sock:/var/run/docker.sock \
portainer/portainer-ce:latest
On vérifie que tout se passe bien :

On se connecte à ‘Portainer‘ en tapant la commande http://VOTREIP:9000. Il est possible qu’il vous demande de relancer ‘Portainer‘ lors du 1er lancement; dans ce cas taper la commande ‘docker restart portainer‘ :

Nous terminons l’installation en créant un environnement de type « Docker standalone’ et ‘Socket’. On ne tient pas compte de la remarque concernant le montage du volume ‘/var/run/docker.sock‘ :

Voila notre containeur ‘Portainer’ tourne en mode ‘rootless’; il ne reste plus qu’à déployer tous vos containeurs via vos piles sauvegardées.


Redéploiement de vos containeurs
Vous aurez peut-être besoin d’adapter certaines de vos piles lors du redéploiement. Le mode ‘rootless’ peut aussi changer les UID/GID (des numéros à la place des noms d’utilisateurs et de groupes) de certains de vos répertoires de configurations de vos containeurs existants et il se peut que pour certains cela génère des perturbations. Si c’est le cas il faudra modifier les anciens UID et GID des répertoires du containeurs qui posent des problèmes de droits d’accès. Par exemple pour le containeur ‘Jellyfin, le mode ‘rootless’ a changé les UID et GID (363146 / 362243) de certains répertoires mais pas tous, ce qui engendre des problèmes de droits d’accès aux métadonnées. Il faut donc dans le cas précis modifier tous les répertoires restés avec les UID / GID ‘omdocker’ / ‘users’ :

Lors du redéploiement de vos piles, vous pouvez en profiter pour ajouter des restrictions pour sécuriser l’utilisation du kernel (voir article sécuriser docker) ; par exemple ici pour la pile ‘Duplicati’ :
