[TUTO] Installer Docker en mode "Rootless"

Bambusa29

Chevalier Jedi
10 Avril 2022
284
128
83

Un tuto pour ceux qui voudraient tester le mode 'rootless'. Je conseille tout de même de le faire plutôt à partir d'une config vierge pour un test au préalable avant de faire la bascule !!​


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 ce tuto 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 du tuto 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.

zsh04.png



Création utilisateur ‘omdocker’



Il faut créer un utilisateur dédié à docker. Dans ce tuto j'utiliserais l'utilisateur 'omdocker'.
Je ne détails pas la procédure ici. Il faudra le rajouter dans les groupes 'users' et 'docker'.


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épertoire 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 :

rootless01.png


tuto01.png


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. Chez moi j'ai ouvert les ports 8200 à 8300.
  • 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.


Code:
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

Code:
#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 :

rootless02.png


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 :

Code:
$ grep cgroup /proc/filesystems

Vous devriez avoir en retour apparaitre la mention V2, si votre système le supporte :

Code:
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 :

Code:
$ 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 :

Code:
$ 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 :

Code:
$ 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 :

Code:
$ 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 :


rootless04.png

rootless03.png


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 :

Code:
$ 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 :

Code:
$ 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 ‘omdocker’ que vous avez créer en début de ce tuto.

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 (solution 1)


Code:
$ 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’ :

Code:
$ su omdocker
$ sh /usr/bin/dockerd-rootless-setuptool.sh install


L’installer directement à partir de l’URL officiel (solution 2)



Le script vas créer un répertoire ‘bin’ dans '/home/omdocker' contenant les exécutables ‘Docker’.

Code:
$ 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 :

rootless06.png

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.

rootless05.png
Pour terminer il faut rajouter les deux lignes entourés en rouge en fin d’exécution du script à vos variables d’environnements. Ajouter les à la fin de votre ficher ‘.bashrc’ ou ‘.zshrc’ en modifiant l’ID de votre utilisateur.

Code:
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 indique 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

Code:
$ systemctl --user status docker
$ docker info
$ systemctl --user enable docker

rootless07.png

rootless08.png


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 'ID' et 'VOTRE_IP' à votre configuration :


Code:
$ 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 :

rootless09.png


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

rootless10.png


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‘ :

rootless_portainer02.png


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’ :

rootless11.png


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


rootless12.png

Je vous renvoi à la documentation officiel pour la gestion des 'CAP' : https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities
 
Dernière édition:
  • J'adore
Réactions: FX Cachem
Mon tuto n'est pas très détaillé et il gagnerait à plus d'explications pour pas mal de commandes citées en mode console. Je le mettrais à jour les jours prochains.