"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > une manière élégante de corriger les ID utilisateur dans les conteneurs Docker à l'aide de docker_userid_fixer

une manière élégante de corriger les ID utilisateur dans les conteneurs Docker à l'aide de docker_userid_fixer

Publié le 2024-11-01
Parcourir:514

an elegant way to fix user IDs in docker containers using docker_userid_fixer

de quoi s'agit-il ?

Il s'agit d'un problème plutôt technique lié à l'utilisation de conteneurs Docker qui interagissent avec l'ordinateur hôte Docker, généralement lié à l'utilisation du système de fichiers hôte à l'intérieur du conteneur.
Cela se produit en particulier dans le contexte de recherches reproductibles.
J'ai développé un utilitaire open source qui permet de résoudre ce problème.

conteneurs Docker comme environnements d'exécution

Le cas d'utilisation initial et principal d'un conteneur Docker : une application autonome qui interagit uniquement avec le système hôte avec certains ports réseau.
Pensez à une application web : le conteneur docker contient généralement un serveur web et une application web, s'exécutant par exemple sur le port 80 (à l'intérieur du conteneur). Le conteneur est ensuite exécuté sur l'hôte, en liant le port interne du conteneur 80 à un port hôte (par exemple 8000).
Ensuite, la seule interaction entre l'application conteneurisée et le système hôte se fait via ce port réseau lié.

Les conteneurs en tant qu'environnements d'exécution sont complètement différents :

  • au lieu de conteneuriser une application, c'est le système de création d'application qui est conteneurisé.
    • il pourrait s'agir d'un compilateur, d'un IDE, d'un moteur de bloc-notes, d'un système de publication Quarto...
  • les objectifs sont :
    • avoir un environnement standard, facile à installer et à partager
      • imaginez un environnement de construction complexe, avec des versions fixes de R, Python et des millions de packages externes. Tout installer avec les bonnes versions peut être une tâche très difficile et fastidieuse. Partager une image Docker contenant tout ce qui est déjà installé et préconfiguré est un véritable gain de temps.
    • avoir un environnement reproductible
      • en l'utilisant, vous êtes en mesure de reproduire certains résultats d'analyse, puisque vous utilisez le même environnement contrôlé
      • vous pouvez également facilement reproduire des bugs, ce qui est la première étape pour les corriger

Mais, pour utiliser ces environnements d'exécution, ces conteneurs doivent avoir accès au système hôte, en particulier au système de fichiers de l'utilisateur hôte.

conteneurs Docker et système de fichiers hôte

Supposons que vous ayez conteneurisé un IDE, par ex. Rstudio.
Votre Rstudio est installé et exécuté dans le conteneur Docker, mais il doit lire et modifier les fichiers dans votre dossier de projet.

Pour cela, vous liez le montage votre dossier de projet (dans votre système de fichiers hôte) à l'aide de l'option docker run --volume.
Ensuite, vos fichiers sont accessibles depuis le conteneur Docker.

Le défi réside désormais dans les autorisations de fichiers. Supposons que votre utilisateur hôte ait l'ID utilisateur 1001 et supposons que l'utilisateur propriétaire du processus Rsudio dans le conteneur soit 0 (root) ou 1002.

Si l'utilisateur du conteneur est root, il n'aura aucun problème à lire vos fichiers.
Mais dès que vous modifiez des fichiers existants et en créez de nouveaux (par exemple pdf, html), ces fichiers appartiendront également à la racine sur le système de fichiers hôte !.
Cela signifie que votre utilisateur hôte local ne pourra pas les utiliser, ni les supprimer, car ils appartiennent à root.

Maintenant, si l'ID utilisateur du conteneur est 1002, Rstudio risque de ne pas pouvoir lire vos fichiers, les modifier ou produire de nouveaux fichiers.
Même si c'est le cas, en définissant des autorisations très permissives, votre utilisateur hôte local ne pourra peut-être pas les utiliser.

Bien sûr, un moyen brutal de résoudre ce problème consiste à exécuter avec root à la fois sur l'ordinateur hôte et dans le conteneur Docker. Cela n'est pas toujours possible et soulève des problèmes de sécurité critiques évidents.

résoudre le problème du propriétaire de fichier, partie 1 : l'option docker run --user

Comme nous ne pouvons pas savoir à l'avance quel sera l'ID utilisateur de l'hôte (ici 1001), nous ne pouvons pas préconfigurer
l'ID utilisateur de l'utilisateur du conteneur Docker.

docker run fournit désormais une option --user qui permet de créer un pseudo-utilisateur avec un identifiant utilisateur fourni
au moment de l'exécution. Par exemple, docker run --user 1001 ... créera un conteneur Docker exécuté avec des processus
appartenant à un utilisateur avec l'ID utilisateur 1001.

Alors, de quoi discutons-nous encore de cette question ? N'est-ce pas résolu ?

Voici quelques bizarreries à propos de cet utilisateur créé dynamiquement :

  • c'est un pseudo utilisateur
  • il n'a pas de répertoire personnel (/home/xxx)
  • il n'apparaît pas dans /etc/passwd
  • il ne peut pas être préconfiguré, par ex. avec un profil bash, quelques variables d'environnement, les valeurs par défaut de l'application, etc...

Nous pouvons contourner ces problèmes, mais cela peut être fastidieux et frustrant.
Ce que nous aimerions vraiment, c'est préconfigurer un utilisateur de conteneur Docker, et pouvoir changer dynamiquement son userid au runtime...

résoudre le problème du propriétaire de fichier, partie 2 : entrez docker_userid_fixer

docker_userid_fixer est un utilitaire open source destiné à être utilisé comme point d'entrée Docker pour résoudre le problème d'ID utilisateur que je viens de soulever.

Voyons comment l'utiliser : vous le définissez comme votre docker ENTRYPOINT, en spécifiant quel utilisateur doit être utilisé et faites modifier dynamiquement son userid :

ENTRYPOINT ["/usr/local/bin/docker_userid_fixer","user1"]

Soyons précis dans nos termes :

  • l'utilisateur cible, est l'utilisateur demandé à docker_userid_fixer, ici user1
  • l'utilisateur demandé est l'utilisateur provisionné par Docker Run, c'est-à-dire l'utilisateur qui (initialement) possède le premier processus (PID 1)

Ensuite, lors de la création du runtime du conteneur, il existe deux options :

  • soit l'ID utilisateur demandé correspond (déjà) à l'ID utilisateur cible, alors rien ne doit être modifié
  • ou ce n'est pas le cas. Par exemple, l'ID utilisateur demandé est 1001, et l'ID utilisateur cible est 100. Ensuite, docker_userid_fixer corrigera l'ID utilisateur de l'utilisateur cible user1 de 1000 à 1001, directement dans le processus principal du conteneur.

Donc, en pratique, cela résout notre problème :

  • si vous n'avez pas besoin de corriger l'ID utilisateur de votre conteneur, utilisez simplement Docker Run de la manière habituelle (sans l'option --user)
  • ou vous utilisez l'option --user, puis en plus d'exécuter votre processus principal avec un ID utilisateur que vous avez demandé, il modifiera votre utilisateur préconfiguré en votre ID utilisateur demandé, afin que votre conteneur s'exécute avec votre utilisateur prévu et prévu ID de l'utilisateur.

configuration de docker_userid_fixer

Vous pouvez trouver des instructions sur la configuration ici.

Mais cela se résume à :

  • créez ou téléchargez le petit exécutable (17 ko)

  • copiez-le dans votre image Docker

  • le rendre exécutable en tant que racine setuid

  • configurez-le comme point d'entrée

les détails sanglants

J'ai mis quelques courtes notes https://github.com/kforner/docker_userid_fixer#how-it-works
mais je vais essayer de reformuler.

Le nœud de l'implémentation est la racine setuid de l'exécutable docker_userid_fixer dans le conteneur.
Nous avons besoin des autorisations root pour modifier l'ID utilisateur, et ce setuid permet cette exécution privilégiée uniquement pour
le programme docker_userid_fixer, et cela pendant une durée très courte.

Dès que l'ID utilisateur aura été modifié si nécessaire, docker_userid_fixer changera le processus principal
à l'utilisateur demandé (et à l'ID utilisateur !).

Si ces sujets vous intéressent (docker, recherche reproductible, développement de packages R, algorithmique, optimisation des performances, parallélisme...) n'hésitez pas à me contacter pour discuter d'opportunités d'emploi et d'affaires.

Déclaration de sortie Cet article est reproduit à: https://dev.to/kforner/an-elegant-way-to-fix-user-ids-in-docker-ntonners-using-dockeruseridfixer-3c9i S'il y a une contrefaçon, veuillez contacter [email protected] pour le supprimer.
Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3