用于Docker容器的ssh X11转发的替代方案 [英] Alternatives to ssh X11-forwarding for Docker containers
问题描述
我正在运行一个Docker容器,主要作为 R
语言的独立开发环境。 (这里使用 R
正好与其他帖子正交,即您可以假设任何通用程序可以在 repl
-session。)很多时候这将涉及到像绘图,制作图形等的东西;我需要看看
这些。因此,我宁可选择显示我在容器中创建的图形。这是我到目前为止这样做的。首先我创建一个 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容器获取图形输出是一种不错的半简单方式,而不必在$ b内运行 sshd
守护程序$ b容器。 Docker可以在运行单个
进程时提供裸机性能,在这种情况下,这应该是 R
。运行sshd守护进程
将会边缘化,因为它可能会引入额外的开销。通过运行sshd守护程序作为
supervisor守护程序的子进程,这不是
。当一个人充分利用
绑定装载时,两者都可以免去。在构建要运行容器的
的映像之后,我们启动一个交互式容器,并绑定
/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
) - sets the host display to the local machines display (which will usually be
:0
) -
-u
指定进程应由用户(这里docker
)运行,而不是由root运行。这一步很重要(vi)! -u
specify the process should be run by a user (heredocker
) and not by root. This step is important (v.i.)!-
-v
bind将本地计算机上/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 DISPLAY = $ DISPLAY \
-e DISPLAY=$DISPLAY \
docker \
-u docker \
-v /tmp/.X11-unix:/tmp /.X11-unix:ro \
-v /tmp/.X11-unix:/tmp/.X11-unix:ro \
- name =rdevubuntu-r R
--name="rdev" ubuntu-r R
发出此命令后,您应该查看美丽的 R
启动输出。如果要尝试演示(图形)
来查看图形
的输出是否正在工作,您会注意到它不是。那就是因为$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $您现在可以在本地机器上输入$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $再次你的容器你现在应该有图形输出。然而,这种方法
是非常不鼓励的,因为您允许访问您的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
服务器的用户的名称您的本地机器,并运行码头容器。这也是
的原因,为什么在运行
容器时指定用户很重要。最后但并非最不重要的是,使用 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)with 管理员
和 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
当通过并运行
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)带绑定方法:
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屋!