J'ai une image docker OpenSuse 42.3 que j'ai configurée pour exécuter un code. L’image a un seul utilisateur (autre que root) appelé "myuser" que je crée lors de la génération initiale de l’image via Dockerfile. J'ai trois fichiers de script qui génèrent un conteneur à partir de l'image en fonction du système d'exploitation utilisé par l'utilisateur.
Question : Le nom d'utilisateur "myuser" dans le conteneur peut-il être défini sur le nom d'utilisateur de l'utilisateur qui exécute le script de génération de conteneur?
Mon objectif est de permettre à un utilisateur d'accéder au conteneur de manière interactive et de pouvoir exécuter le code à partir de celui-ci. Le code est juste un simple binaire qui s'exécute et a quelques IO, je veux donc que le répertoire de l'utilisateur soit accessible depuis le conteneur afin qu'il puisse naviguer dans un dossier sur sa machine et exécuter le code pour générer une sortie dans son système de fichiers.
Vous trouverez ci-dessous ce que j'ai construit jusqu'à présent. J'ai essayé de définir la variable d'environnement USER lors de l'appel du script linux sur docker run
, mais cela n'a pas changé l'utilisateur de "myuser" en "bob" (le nom d'utilisateur de la machine hôte qui a démarré le conteneur). Le montage des répertoires semble bien fonctionner. Je ne sais pas s'il est même possible d'atteindre mon objectif.
Script de conteneur Linux:
username="$USER"
userID="$(id -u)"
groupID="$(id -g)"
home="${1:-$HOME}"
imageName="myImage:ImageTag"
containerName="version1Image"
docker run -it -d --name ${containerName} -u $userID:$groupID \
-e USER=${username} --workdir="/home/myuser" \
--volume="${home}:/home/myuser" ${imageName} /bin/bash \
Conteneur Mac:
username="$USER"
userID="$(id -u)"
groupID="$(id -g)"
home="${1:-$HOME}"
imageName="myImage:ImageTag"
containerName="version1Image"
docker run -it -d --name ${containerName} \
--workdir="/home/myuser" \
--v="${home}:/home/myuser" ${imageName} /bin/bash \
Script de conteneur Windows:
ECHO OFF
SET imageName="myImage:ImageTag"
SET containerName="version1Image"
docker run -it -d --name %containerName% --workdir="/home/myuser" -v="%USERPROFILE%:/home/myuser" %imageName% /bin/bash
echo "Container %containerName% was created."
echo "Run the ./startWindowsLociStream script to launch container"
Le code ci-dessous a été vérifié dans https://github.com/bmitch3020/run-as-user .
Je gérerais cela dans un entrypoint.sh qui vérifie la propriété de/home/myuser et met à jour l'uid/gid de l'utilisateur dans votre conteneur. Cela peut ressembler à quelque chose comme:
#!/bin/sh
set -x
# get uid/gid
USER_UID=`ls -nd /home/myuser | cut -f3 -d' '`
USER_GID=`ls -nd /home/myuser | cut -f4 -d' '`
# get the current uid/gid of myuser
CUR_UID=`getent passwd myuser | cut -f3 -d: || true`
CUR_GID=`getent group myuser | cut -f3 -d: || true`
# if they don't match, adjust
if [ ! -z "$USER_GID" -a "$USER_GID" != "$CUR_GID" ]; then
groupmod -g ${USER_GID} myuser
fi
if [ ! -z "$USER_UID" -a "$USER_UID" != "$CUR_UID" ]; then
usermod -u ${USER_UID} myuser
# fix other permissions
find / -uid ${CUR_UID} -mount -exec chown ${USER_UID}.${USER_GID} {} \;
fi
# drop access to myuser and run cmd
exec gosu myuser "$@"
Et voici quelques lignes d'un fichier Docker pertinent:
FROM debian:9
ARG GOSU_VERSION=1.10
# run as root, let the entrypoint drop back to myuser
USER root
# install prereq debian packages
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
apt-transport-https \
ca-certificates \
curl \
vim \
wget \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Install gosu
RUN dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')" \
&& wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch" \
&& chmod 755 /usr/local/bin/gosu \
&& gosu nobody true
RUN useradd -d /home/myuser -m myuser
WORKDIR /home/myuser
# entrypoint is used to update uid/gid and then run the users command
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD /bin/sh
Ensuite, pour l’exécuter, il vous suffit de monter/home/myuser en tant que volume et il ajustera les autorisations du point d’entrée. par exemple.:
$ docker build -t run-as-user .
$ docker run -it --rm -v $(pwd):/home/myuser run-as-user /bin/bash
Dans ce conteneur, vous pouvez exécuter id
et ls -l
pour vérifier que vous avez accès aux fichiers/home/myuser.
Les noms d'utilisateur ne sont pas importants. Ce qui est important, ce sont les valeurs uid et gid.
L'utilisateur myuser de votre conteneur aura un ID utilisateur de 1000 (premier ID utilisateur non root). Ainsi, lorsque vous démarrez votre conteneur et examinez le processus de gestion des conteneurs à partir de la machine hôte, vous verrez que le conteneur appartient à tout utilisateur possédant un ID utilisateur de 1000 sur la machine hôte.
Vous pouvez remplacer cela en spécifiant l'utilisateur une fois que vous exécutez votre conteneur en utilisant:
docker run --user 1001 ...
Par conséquent, si vous voulez que l'utilisateur à l'intérieur du conteneur puisse accéder aux fichiers de la machine hôte appartenant à un utilisateur ayant un ID utilisateur de 1005, exécutez simplement le conteneur à l'aide de --user 1005.
Pour mieux comprendre comment les utilisateurs établissent un lien entre le conteneur et l'hôte, jetez un coup d'œil à cet article merveilleux. https://medium.com/@mccode/understanding-how-uid-and-gid-work-in-docker-containers-c37a01d01cf
Tout d’abord ( https://docs.docker.com/engine/reference/builder/#arg ):
Avertissement: Il n'est pas recommandé d'utiliser des variables de construction pour transmettre des secrets tels que les clés github, les informations d'identification de l'utilisateur, etc. Variable de construction les valeurs sont visibles pour tout utilisateur de l'image avec l'historique du menu fixe commander.
Toutefois, si vous devez toujours le faire, lisez https://docs.docker.com/engine/reference/builder/#arg :
Un fichier Dockerfile peut inclure une ou plusieurs instructions ARG. Par exemple, Ce qui suit est un fichier Docker valide:
FROM busybox ARG user1 ARG buildno ...
et https://docs.docker.com/engine/reference/builder/#user :
L'instruction USER définit le nom d'utilisateur (ou UID) et éventuellement le groupe d'utilisateurs (ou GID) à utiliser lors de l'exécution de l'image et pour tout RUN, CMD et les instructions ENTRYPOINT qui suivent dans le fichier Docker.
USER <user>[:<group>] or USER <UID>[:<GID>]