Альтернативы ssh X11-forwarding для контейнеров Docker

Я запускаю контейнер Docker главным образом в качестве изолированной среды разработки для языка R. (Использование R здесь ортогонально остальной части сообщения, т.е. Вы можете просто предположить любую общую программу, которая может выполняться в repl -сегрессии.) Много раз это будет включать в себя такие вещи, как построение графика, создание графика и так далее; и мне нужно посмотреть эти. Следовательно, я предпочел бы иметь возможность отображения графики, которую я создал в своем контейнере. Вот как я это делаю до сих пор. Сначала создаю a Dockerfile. Оставляя тривиальные шаги, наиболее важными являются:

# Set root passwd 
RUN echo "root:test" | chpasswd

# Add user so that container does not run as root 
RUN useradd -m docker 
RUN echo "docker:test" | chpasswd 
RUN usermod -s /bin/bash docker 
RUN usermod -aG sudo docker 
ENV HOME /home/docker

RUN mkdir /var/run/sshd 
RUN mkdir -p /var/log/supervisor

# copy servisord.conf which lists the processes to be spawned once this 
# container is started (currently only one: sshd) 
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

EXPOSE 22 
CMD ["/usr/bin/supervisord"]

Я создаю изображение, а затем запускаю контейнер, используя:

docker run -d -p 127.0.0.1:5000:22 -h ubuntu-r -v /home/chb/files/Data:/home/docker/Data -P --name="rdev" ubuntu-r

и может затем ssh в мой контейнер:

ssh -X [email protected] -p 5000.

Это даст мне то, что я хочу. Но я хотел бы знать, есть ли еще один ресурсосберегающий способ получения графического/графического интерфейса из контейнера? (Я бы предпочел, если возможно, решения не включали бы vnc.)

Ответ 1

Существует хороший и полулегкий способ получения графического вывода из Контейнер-докер, не запуская демон sshd внутри контейнер. Docker может обеспечить голые характеристики металла при запуске одного процесс, который в этом случае должен быть R. Запуск демона sshd будет, как это ни парадоксально, вводить дополнительные накладные расходы. Это не лучше работает, запустив демона sshd в качестве дочернего процесса супервизор. Оба можно обойтись, если вы привязать крепления. После создания изображения, из которого предполагается контейнер для запуска мы запускаем интерактивный контейнер и привязываем /tmp/.X11-unix в него. Я укажу полную команду и подробно объясните, что он делает:

docker run -i -t -rm\

  • -i устанавливает интерактивный сеанс; -t выделяет псевдо tty; --rm делает этот контейнер эфемерным

-e DISPLAY = $DISPLAY\

  • устанавливает отображение хоста на дисплей локальных компьютеров (обычно это будет :0)

-u docker\

  • -u указать, что процесс должен запускаться пользователем (здесь docker), а не root. Этот шаг важен (v.i.)!

-v/tmp/.X11-unix:/tmp/.X11-unix:ro\

  • -v bind монтирует сокет X11, находящийся в /tmp/.X11-unix на вашем локальном компьютере, в /tmp/.X11-unix в контейнере, а :ro делает только сокет.

- name= "rdev" ubuntu-r R

  • --name="" укажите имя контейнера (здесь rdev); изображение, из которого вы хотите запустить контейнер (здесь ubuntu-r); процесс, который вы хотите запустить в контейнере (здесь R). (Последний шаг указания процесса необходим только в том случае, если вы не задали по умолчанию CMD или ENTRYPOINT для вашего изображения.)

После выдачи этой команды вы должны смотреть на красивый R начало производства. Если вы хотите попробовать demo(graphics), чтобы увидеть, выход уже работает, вы заметите, что это не так. Это потому расширения Xsecurity, предотвращающего доступ к сокету. Вы теперь можно ввести xhost + на вашем локальном компьютере и попробовать demo(graphics) в ваш контейнер снова. Теперь вы должны иметь графический вывод. Этот метод однако настоятельно не рекомендуется, поскольку вы разрешаете доступ к вашему xsocket для любой удаленный хост, к которому вы в настоящее время подключены. Пока вы только взаимодействуя с однопользовательскими системами, это может быть как-то оправданным, но как только будет задействовано несколько пользователей, это будет абсолютно небезопасный! Следовательно, вы должны использовать менее опасный метод. Хорошим способом является использовать интерпретируемый сервер

xhost +si:localuser:username

который может использоваться для указания одного локального пользователя (см. man xhost). Это означает username должно быть именем пользователя, который запускает сервер X11 вашей локальной машине и которая запускает контейнер докеров. Это также причина, почему важно указать пользователя при запуске контейнер. И последнее, но не менее важное: всегда есть более сложное решение используя файлы xauth и .Xauthority для предоставления доступа к сокету X11 (см. man xauth). Это, однако, также потребует немного больше знаний как работает X.

Положительный эффект, который это может иметь, можно увидеть в количестве процессов которые необходимо запустить для достижения желаемого.

(1) с supervisor и sshd, запущенным в контейнере:

UID                 PID                 PPID                C                STIME               TTY                 TIME                CMD
root                4564                718                 1                18:16               ?                   00:00:00            /usr/bin/python /usr/bin/supervisord
root                4576                4564                0                18:16               ?                   00:00:00            /usr/sbin/sshd

при входе через ssh и запуске R:

UID                 PID                 PPID                C                 STIME               TTY                 TIME                CMD
root                4564                718                 0                 18:16               ?                   00:00:00            /usr/bin/python /usr/bin/supervisord
root                4576                4564                0                 18:16               ?                   00:00:00            /usr/sbin/sshd
root                4674                4576                0                 18:17               ?                   00:00:00            sshd: docker [priv]   
chb                 4725                4674                0                 18:18               ?                   00:00:00            sshd: [email protected]/0
chb                 4728                4725                1                 18:18               pts/0               00:00:00            -bash

(2) с методом привязки привязки:

UID                 PID                 PPID                C                 STIME               TTY                 TIME                CMD
chb                 4356                718                 0                 18:12               pts/4               00:00:00            /usr/local/lib/R/bin/exec/R --no-save --no-restore

Ответ 2

Вот, безусловно, лучшее решение, которое я нашел до сих пор:

fooobar.com/info/27380/... (все кредиты идут в Юрген Вейгерт)

Преимущества:

  • Внутри докера, UID не имеет значения (но я по-прежнему рекомендую не использовать root)
  • На хосте вам не нужно изменять параметры безопасности (xhost +)