一尘不染

Docker容器的SSH X11转发的替代方法

docker

我正在运行Docker容器,主要是作为该R语言的隔离开发环境。(R这里的用法与文章的其余部分是正交的,即,您可以假定可以在repl-session中运行的任何通用程序。)很多时候,这涉及到诸如绘图,制作图形等工作;我需要看看这些。因此,我希望可以选择显示在容器中创建的图形。到目前为止,这是我的操作方式。首先,我创建一个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 docker@localhost -p 5000.

这会给我我想要的。但是我想知道是否还有另一种更资源友好的方式来从容器中获取图形/ GUI输出?(如果可能,我希望解决方案不涉及vnc。)


阅读 765

收藏
2020-06-17

共1个答案

一尘不染

有一种从Docker容器获取图形输出的好方法,并且无需sshd在容器内运行守护程序。当运行单个进程(本来应该是这样)时,Docker可以提供裸机性能R。运行sshd守护程序可能会带来一些额外的开销,尽管可能很小。通过将sshd守护程序作为supervisor守护程序的子进程运行,这并没有得到改善。当一个人充分利用绑定安装时,两者都可以省去。在构建了应该从中运行容器的映像之后,我们启动一个交互式容器并将该/tmp/.X11-unix文件夹绑定安装
到其中。我将陈述完整的命令并详细解释它的作用:

泊坞窗运行-i -t –rm \

  • -i建立一个交互式会话;-t分配一个伪tty; --rm使这个容器短暂

-e DISPLAY = $ DISPLAY \

  • 将主机显示设置为本地计算机显示(通常为:0

-u泊坞窗\

  • -u指定该进程应由用户(在此处docker)而不是root运行。此步骤很重要(vi)!

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

  • -vbind 将本地计算机上的X11套接字安装/tmp/.X11-unix/tmp/.X11-unix容器中,:ro并使该套接字为只读。

--name =“ rdev” ubuntu-r R

  • --name="" specify the name of the container (here rdev); the image you want to run the container from (here ubuntu-r); the process you want to run in the container (here R). (The last step of specifying a process is only necessary if you have not set a default CMD or ENTRYPOINT for your image.)

发出此命令后,您应该查看漂亮的R
启动输出。如果要尝试demo(graphics)查看图形输出是否已经在工作,您会注意到它不是。那是因为Xsecurity扩展名阻止您访问套接字。现在,您可以xhost +在本地计算机上键入内容,然后demo(graphics)再次尝试使用您的容器。您现在应该具有图形输出。但是,强烈建议不要使用此方法,因为您允许访问当前连接到的任何远程主机的xsocket。只要您仅与单用户系统进行交互,这在某种程度上是合理的,但是一旦涉及多个用户,这绝对是不安全的!因此,您应该使用一种不太危险的方法。一个好的方法是使用服务器解释

xhost +si:localuser:username

可以用来指定一个本地用户(请参阅参考资料man xhost)。这意味着
username应该是在X11本地计算机上运行服务器并运行docker容器的用户的名称。这也是为什么在运行容器时指定用户很重要的原因。最后但并非最不重要的一点是,总是存在使用xauth.Xauthority文件授予对X11套接字的访问权限的更复杂的解决方案(请参阅参考资料man xauth)。但是,这还将涉及更多的知识X

这可以产生积极的影响,这是为了实现所需的过程而需要运行的过程数量。

(1)supervisorsshd在所述容器中运行:

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: docker@pts/0
chb                 4728                4725                1                 18:18               pts/0               00:00:00            -bash

(2)使用bind mount方法:

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
2020-06-17