En bref: j'essaie de monter un répertoire hôte dans Docker, mais je ne peux pas y accéder depuis le conteneur, même si les autorisations d'accès semblent bonnes.
Les détails:
je fais
sudo docker run -i -v /data1/Downloads:/Downloads ubuntu bash
puis
ls -al
Ça me donne:
total 8892
drwxr-xr-x. 23 root root 4096 Jun 18 14:34 .
drwxr-xr-x. 23 root root 4096 Jun 18 14:34 ..
-rwxr-xr-x. 1 root root 0 Jun 18 14:34 .dockerenv
-rwx------. 1 root root 9014486 Jun 17 22:09 .dockerinit
drwxrwxr-x. 18 1000 1000 12288 Jun 16 11:40 Downloads
drwxr-xr-x. 2 root root 4096 Jan 29 18:10 bin
drwxr-xr-x. 2 root root 4096 Apr 19 2012 boot
drwxr-xr-x. 4 root root 340 Jun 18 14:34 dev
drwxr-xr-x. 56 root root 4096 Jun 18 14:34 etc
drwxr-xr-x. 2 root root 4096 Apr 19 2012 home
et beaucoup plus de lignes comme ça (je pense que c'est la partie pertinente).
Si je fais
cd /Downloads
ls
le résultat est
ls: cannot open directory .: Permission denied
L'hôte est Fedora 20, avec Docker 1.0.0 et go1.2.2.
Qu'est-ce qui ne va pas?
la source
-v $(pwd):/app:ro,Z
. Cela devrait être marqué comme la bonne réponse.Il s'agit d'un problème SELinux .
Vous pouvez émettre temporairement
sur l'hôte pour accéder ou ajouter une règle SELinux en exécutant
la source
AVERTISSEMENT: cette solution présente des risques de sécurité.
Essayez d'exécuter le conteneur avec privilèges:
Une autre option (que je n'ai pas essayée) serait de créer un conteneur privilégié puis de créer des conteneurs non privilégiés à l'intérieur de celui-ci.
la source
--privileged=true
--privileged
est un risque pour la sécuritéEn règle générale, les problèmes d'autorisations avec un montage de volume hôte sont dus au fait que l'uid / gid à l'intérieur du conteneur n'a pas accès au fichier conformément aux autorisations uid / gid du fichier sur l'hôte. Cependant, ce cas spécifique est différent.
Le point à la fin de la chaîne d'autorisation
drwxr-xr-x.
, indique que SELinux est configuré. Lorsque vous utilisez un montage hôte avec SELinux, vous devez passer une option supplémentaire à la fin de la définition du volume:Votre commande de montage de volume ressemblerait alors à:
En savoir plus sur les montages d'hôte avec SELinux sur: https://docs.docker.com/storage/#configure-the-selinux-label
Pour d'autres qui voient ce problème avec les conteneurs s'exécutant en tant qu'utilisateur différent, vous devez vous assurer que l'uid / gid de l'utilisateur à l'intérieur du conteneur dispose des autorisations sur le fichier sur l'hôte. Sur les serveurs de production, cela se fait souvent en contrôlant l'uid / gid dans le processus de création d'image pour faire correspondre un uid / gid sur l'hôte qui a accès aux fichiers (ou mieux encore, n'utilisez pas de montages d'hôte en production).
Un volume nommé est souvent préféré pour héberger des montages car il initialise le répertoire de volume à partir du répertoire d'image, y compris toute propriété de fichier et autorisations. Cela se produit lorsque le volume est vide et que le conteneur est créé avec le volume nommé.
Les utilisateurs de MacOS ont maintenant OSXFS qui gère automatiquement les uid / gid entre l'hôte Mac et les conteneurs. Les fichiers de l'intérieur de la machine virtuelle intégrée qui sont montés dans le conteneur, comme /var/lib/docker.sock, ne sont pas utiles.
Pour les environnements de développement où l'uid / gid de l'hôte peut changer par développeur, ma solution préférée est de démarrer le conteneur avec un point d'entrée s'exécutant en tant que root, de corriger l'uid / gid de l'utilisateur à l'intérieur du conteneur pour correspondre au uid / gid du volume de l'hôte, et puis utilisez
gosu
pour passer de la racine à l'utilisateur du conteneur pour exécuter l'application à l'intérieur du conteneur. Le script important pour cela estfix-perms
dans mes scripts d'image de base, qui peuvent être trouvés à: https://github.com/sudo-bmitch/docker-baseLe bit important du
fix-perms
script est:Cela obtient l'uid de l'utilisateur à l'intérieur du conteneur, et l'uid du fichier, et s'ils ne correspondent pas, appelle
usermod
pour ajuster l'uid. Enfin, il effectue une recherche récursive pour corriger tous les fichiers qui n'ont pas changé d'uid. J'aime mieux que d'exécuter un conteneur avec un-u $(id -u):$(id -g)
indicateur, car le code de point d'entrée ci-dessus ne nécessite pas que chaque développeur exécute un script pour démarrer le conteneur, et tous les fichiers en dehors du volume appartenant à l'utilisateur verront leurs autorisations corrigées.Vous pouvez également demander à docker d'initialiser un répertoire hôte à partir d'une image en utilisant un volume nommé qui effectue un montage de liaison. Ce répertoire doit exister à l'avance et vous devez fournir un chemin absolu vers le répertoire hôte, contrairement aux volumes hôtes dans un fichier de composition qui peuvent être des chemins relatifs. Le répertoire doit également être vide pour que docker l'initialise. Trois options différentes pour définir un volume nommé sur un montage de liaison ressemblent à:
Enfin, si vous essayez d'utiliser des espaces de noms d'utilisateurs, vous constaterez que les volumes hôtes ont des problèmes d'autorisation car les uid / gid des conteneurs sont décalés. Dans ce scénario, il est probablement plus facile d'éviter les volumes hôtes et de n'utiliser que les volumes nommés.
la source
Depuis access.redhat.com:Sharing_Data_Across_Containers :
Il semble que ce ne soit qu'une solution de contournement, mais j'ai essayé et cela fonctionne.
la source
J'ai vérifié que
chcon -Rt svirt_sandbox_file_t /path/to/volume
cela fonctionne et que vous n'avez pas à exécuter en tant que conteneur privilégié.C'est sur:
la source
Essayez
docker volume create
.Jetez un œil au document https://docs.docker.com/engine/reference/commandline/volume_create/
la source
J'ai eu un problème similaire, le mien a été causé par un décalage entre l'UID de l'hôte et l'UID de l'utilisateur du conteneur. Le correctif consistait à passer l'UID de l'utilisateur en tant qu'argument à la génération Docker et à créer l'utilisateur du conteneur avec le même UID.
Dans le DockerFile:
Dans l'étape de construction:
Après cela, l'exécution du conteneur et des commandes selon l'OP m'a donné le résultat attendu.
la source
J'ai résolu ce problème en utilisant un conteneur de données, cela a également l'avantage d'isoler les données de la couche application. Vous pouvez l'exécuter comme ceci:
Ce didacticiel fournit une bonne explication sur l'utilisation des conteneurs de données.
la source
Dans ma situation, le problème était différent. Je ne sais pas pourquoi, mais même si le répertoire sur l'hôte avait
chmod 777
fonctionné dessus, dans docker il était visible comme755
.Courir à l'intérieur du conteneur l'a
sudo chmod 777 my_volume_dir
corrigé.la source
chmod 777
ne règle presque jamais rien.sudo -s
a fait l'affaire pour moi sur MACla source