Подтвердить что ты не робот

Установить имя пользователя докере во время создания контейнера?

У меня есть изображение докеры OpenSuse 42.3, которое я настроил для запуска кода. У изображения есть один пользователь (кроме root), называемый "myuser" , который я создаю во время начального создания изображения через Dockerfile. У меня есть три файла script, которые генерируют контейнер из образа на основе того, в какой операционной системе включен пользователь.

Вопрос. Может ли имя пользователя "myuser" в контейнере быть установлено на имя пользователя пользователя, который выполняет создание контейнера script?

Моя цель - позволить пользователю входить в контейнер интерактивно и иметь возможность запускать код из контейнера. Код - это всего лишь один бинарный файл, который выполняется и имеет несколько IO, поэтому я хочу, чтобы каталог пользователя был доступен из контейнера, чтобы они могли перемещаться по папке на своей машине и запускать код для генерации вывода в своей файловой системе.

Ниже я до сих пор строил. Я попытался установить переменную среды USER во время вызова linux script на docker run, но это не изменило пользователя из "myuser" , чтобы сказать "bob" (имя пользователя на главной машине, которая запустила контейнер). Похоже, что установка каталогов работает нормально. Я не уверен, что даже можно достичь моей цели.

Контейнер Linux script:

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  \

Контейнер Mac script:

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  \

Контейнер Windows script:

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"
4b9b3361

Ответ 1

Следующий код был отмечен в https://github.com/bmitch3020/run-as-user.

Я бы справился с этим в entrypoint.sh, который проверяет право собственности на /home/myuser и обновляет uid/gid пользователя внутри вашего контейнера. Он может выглядеть примерно так:

#!/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 "[email protected]"

И вот некоторые строки из соответствующего файла Docker:

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

Затем, чтобы запустить его, вам просто нужно подключить /home/myuser в качестве тома, и он отрегулирует разрешения в точке входа. например:.

$ docker build -t run-as-user . 
$ docker run -it --rm -v $(pwd):/home/myuser run-as-user /bin/bash

Внутри этого контейнера вы можете запустить id и ls -l, чтобы увидеть, что у вас есть доступ к файлам/home/myuser.

Ответ 2

Имена пользователей не важны. Важны значения uid и gid.

Пользователь myuser внутри вашего контейнера будет иметь uid 1000 (первый идентификатор пользователя без полномочий root). Таким образом, когда вы запускаете свой контейнер и смотрите процесс контейнера с главной машины, вы увидите, что контейнер принадлежит любому пользователю, имеющему uid 1000 на главной машине.

Вы можете переопределить это, указав пользователя после запуска контейнера, используя:

docker run --user 1001 ...

Поэтому, если вы хотите, чтобы пользователь внутри контейнера, чтобы иметь доступ к файлам на хост-машине, принадлежащей пользователю, имеющему uid 1005, скажем, просто запустите контейнер с помощью --user 1005.

Чтобы лучше понять, как пользователи сопоставляют контейнер и хост, взгляните на эту замечательную статью. https://medium.com/@mccode/understanding-how-uid-and-gid-work-in-docker-containers-c37a01d01cf

Ответ 3

Прежде всего (https://docs.docker.com/engine/reference/builder/#arg):

Предупреждение. Не рекомендуется использовать переменные времени сборки для передачи секреты, такие как ключи github, учетные данные пользователя и т.д. Встроенная переменная времени значения видны любому пользователю изображения с историей докера команда.

Но если вам все еще нужно это сделать, прочитайте https://docs.docker.com/engine/reference/builder/#arg:

Файл Docker может содержать одну или несколько инструкций ARG. Например, следующий действительный файл Docker:

FROM busybox
ARG user1
ARG buildno
...

и https://docs.docker.com/engine/reference/builder/#user:

Инструкция USER устанавливает имя пользователя (или UID) и, при необходимости, группа пользователей (или GID) для использования при запуске изображения и для любого RUN, CMD и ENTRYPOINT, которые следуют за ним в файле Docker.

USER <user>[:<group>] or
USER <UID>[:<GID>]