Docker 容器的 ssh X11 转发的替代方案 [英] Alternatives to ssh X11-forwarding for Docker containers
问题描述
我运行 Docker 容器主要是作为 R
语言的隔离开发环境.(这里 R
的用法与文章的其余部分是正交的,即您可以假设任何可以在 repl
会话中运行的通用程序.)有时这将涉及做绘图、制作图形等工作;我需要看看这些.因此,我更愿意选择显示我在容器中创建的图形.到目前为止,这是我如何做到这一点.首先我创建一个 Dockerfile
.略去琐碎的步骤,最相关的是:
I am running a Docker container mainly as an isolated development environment for the R
language. (The usage of R
here is orthogonal to the rest of the post, i.e. you can just assume any generic program that can run in a repl
-session.) A lot of times this will involve doing stuff like plotting, making graphics and so on; and I need to look at
these. Hence, I would prefer to have the option of displaying graphics I created in my container. Here is how I do this so far. First I create a Dockerfile
. Leaving out the trivial steps the ones most relevant are:
# 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"]
我构建映像,然后使用以下命令启动容器:
I build the image and then start the container by using:
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 进入我的容器:
and can then ssh into my container:
ssh -X docker@localhost -p 5000.
这会给我我想要的.但我想知道是否有另一种更资源友好的方式从容器中获取图形/GUI 输出?(如果可能的话,我希望解决方案不涉及 vnc
.)
This will give me what I want. But I would like to know if there is another more resource friendly way of getting graphics/GUI output from a container? (I'd prefer, if possible, solutions would not involve vnc
.)
推荐答案
有一种不错的半简单方法可以从Docker 容器无需在容器内部运行 sshd
守护进程容器.Docker 可以在单机运行时提供裸机性能在这种情况下应该是 R
的过程.运行 sshd 守护进程将引入额外的开销,尽管它可能是微不足道的.这不是通过将 sshd 守护进程作为主管守护程序.两者都可以省去,只要善用绑定坐骑.在构建了容器应该来自的镜像之后要运行,我们启动一个交互式容器并绑定挂载/tmp/.X11-unix
文件夹.我将说明完整的命令和详细解释它的作用:
There is a nice and semi-easy way of getting graphical output from a
Docker container without having to run an sshd
daemon inside of the
container. Docker can provide bare metal performance when running a single
process which in this case is supposed to be R
. Running an sshd daemon
will, marginal as it may be, introduce additional overhead. This is not
made better by running the sshd daemon as a child process of the
supervisor daemon. Both can be dispensed with when one makes good use of
bind mounts. After building the image from which the container is supposed
to be run we start an interactive container and bind mount the
/tmp/.X11-unix
folder into it. I will state the complete command and
explain in detail what it does:
docker run -i -t --rm
docker run -i -t --rm
-i
设置交互会话;-t
分配一个伪 tty;--rm
使这个容器变得短暂-i
sets up an interactive session;-t
allocates a pseudo tty;--rm
makes this container ephemeral- 将主机显示设置为本地机器显示(通常为
:0
) -u
指定进程应该由用户(此处为docker
)而不是由 root 运行.这一步很重要(v.i.)!-u
specify the process should be run by a user (heredocker
) and not by root. This step is important (v.i.)!-v
绑定将驻留在本地机器上/tmp/.X11-unix
的X11
套接字挂载到/tmp/.X11-unix
和:ro
使套接字只读.-v
bind mounts theX11
socket residing in/tmp/.X11-unix
on your local machine into/tmp/.X11-unix
in the container and:ro
makes the socket read only.--name=""
指定容器的名称(这里是rdev
);您要从中运行容器的图像(此处为ubuntu-r
);要在容器中运行的进程(此处为R
).(仅当您尚未为图像设置默认CMD
或ENTRYPOINT
时,才需要指定进程的最后一步.)--name=""
specify the name of the container (hererdev
); the image you want to run the container from (hereubuntu-r
); the process you want to run in the container (hereR
). (The last step of specifying a process is only necessary if you have not set a defaultCMD
orENTRYPOINT
for your image.)
-e 显示=$显示
-u 码头工人
-v/tmp/.X11-unix:/tmp/.X11-unix:ro
-v /tmp/.X11-unix:/tmp/.X11-unix:ro
--name="rdev" ubuntu-r R
--name="rdev" ubuntu-r R
发出此命令后,您应该会看到漂亮的 R
开始输出.如果您要尝试 demo(graphics)
以查看图形输出已经在工作,你会注意到它不是.那是因为Xsecurity
扩展阻止您访问套接字.你现在可以在本地机器上输入 xhost +
并尝试 demo(graphics)
又是你的容器.您现在应该有图形输出.这个方法但是,强烈建议不要这样做,因为您允许访问您的 xsocket您当前连接到的任何远程主机.只要你只是与单用户系统交互这可能在某种程度上是合理的,但是一旦涉及多个用户,这绝对是不安全!因此,您应该使用危险性较小的方法.一个好方法是使用服务器解释
After issuing this command you should be looking at the beautiful R
start output. If you were to try demo(graphics)
to see if graphical
output is already working you would note that it is not. That is because
of the Xsecurity
extension preventing you from accessing the socket. You
could now type xhost +
on your local machine and try demo(graphics)
in
your container again. You should now have graphical output. This method
however, is strongly discouraged as you allow access to your xsocket to
any remote host you're currently connected to. As long as you're only
interacting with single-user systems this might be somehow justifiable but
as soon as there are multiple users involved this will be absolutely
unsafe! Hence, you should use a less dangerous method. A good way is to
use the server interpreted
xhost +si:localuser:username
可用于指定单个本地用户(请参阅man xhost
).这意味着username
应该是运行 X11
服务器的用户名您的本地机器并运行 docker 容器.这也是为什么在运行时指定用户很重要容器.最后但并非最不重要的总是有更复杂的解决方案使用 xauth
和 .Xauthority
文件授予对 X11
套接字的访问权限(参见man xauth
).然而,这也将涉及更多的知识X
是如何工作的.
which can be used to specify a single local user (see man xhost
). This means
username
should be the name of the user which runs the X11
server on
your local machine and which runs the docker container. This is also the
reason why it is important that you specify a user when running your
container. Last but not least there is always the more complex solution of
using xauth
and .Xauthority
files to grant access to the X11
socket
(see man xauth
). This however will also involve a little more knowledge
how X
works.
这可以在进程数量上看到的积极影响需要运行才能实现所需的内容.
The positive effect this can have can be seen in the number of processes that need to be run in order to achieve what is wanted.
(1) supervisor
和 sshd
在容器中运行:
(1) with supervisor
and sshd
running in the container:
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
时:
when logged in via ssh
and running 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: docker@pts/0
chb 4728 4725 1 18:18 pts/0 00:00:00 -bash
(2) 使用绑定挂载方法:
(2) with bind mount method:
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
这篇关于Docker 容器的 ssh X11 转发的替代方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!