我正在运行Docker容器,主要是作为该R语言的隔离开发环境。(R这里的用法与文章的其余部分是正交的,即,您可以假定可以在repl-session中运行的任何通用程序。)很多时候,这涉及到诸如绘图,制作图形等工作;我需要看看这些。因此,我希望可以选择显示在容器中创建的图形。到目前为止,这是我的操作方式。首先,我创建一个Dockerfile。忽略最简单的步骤是:
R
repl
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。)
vnc
有一种从Docker容器获取图形输出的好方法,并且无需sshd在容器内运行守护程序。当运行单个进程(本来应该是这样)时,Docker可以提供裸机性能R。运行sshd守护程序可能会带来一些额外的开销,尽管可能很小。通过将sshd守护程序作为supervisor守护程序的子进程运行,这并没有得到改善。当一个人充分利用绑定安装时,两者都可以省去。在构建了应该从中运行容器的映像之后,我们启动一个交互式容器并将该/tmp/.X11-unix文件夹绑定安装 到其中。我将陈述完整的命令并详细解释它的作用:
sshd
/tmp/.X11-unix
泊坞窗运行-i -t –rm \
-i
-t
--rm
-e DISPLAY = $ DISPLAY \
:0
-u泊坞窗\
-u
docker
-v /tmp/.X11-unix:/tmp/.X11-unix:ro \
-v
X11
:ro
--name =“ rdev” ubuntu-r R
--name=""
rdev
ubuntu-r
CMD
ENTRYPOINT
发出此命令后,您应该查看漂亮的R 启动输出。如果要尝试demo(graphics)查看图形输出是否已经在工作,您会注意到它不是。那是因为Xsecurity扩展名阻止您访问套接字。现在,您可以xhost +在本地计算机上键入内容,然后demo(graphics)再次尝试使用您的容器。您现在应该具有图形输出。但是,强烈建议不要使用此方法,因为您允许访问当前连接到的任何远程主机的xsocket。只要您仅与单用户系统进行交互,这在某种程度上是合理的,但是一旦涉及多个用户,这绝对是不安全的!因此,您应该使用一种不太危险的方法。一个好的方法是使用服务器解释
demo(graphics)
Xsecurity
xhost +
xhost +si:localuser:username
可以用来指定一个本地用户(请参阅参考资料man xhost)。这意味着 username应该是在X11本地计算机上运行服务器并运行docker容器的用户的名称。这也是为什么在运行容器时指定用户很重要的原因。最后但并非最不重要的一点是,总是存在使用xauth和.Xauthority文件授予对X11套接字的访问权限的更复杂的解决方案(请参阅参考资料man xauth)。但是,这还将涉及更多的知识X。
man xhost
username
xauth
.Xauthority
man xauth
X
这可以产生积极的影响,这是为了实现所需的过程而需要运行的过程数量。
(1)supervisor和sshd在所述容器中运行:
supervisor
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:
ssh
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