user-interface - management - kitematic ubuntu
Alternativas a ssh X11-forwarding para contenedores Docker (2)
Aquí está claramente la mejor solución que encontré hasta ahora:
https://stackoverflow.com/a/25280523/1353930 (todos los créditos van a Jürgen Weigert)
Ventajas:
- Docker interno, el UID del dado no es relevante (pero aún así recomiendo no usar root)
- En el host, no tiene que cambiar la configuración de seguridad (
xhost +
)
Estoy ejecutando un contenedor Docker principalmente como un entorno de desarrollo aislado para el lenguaje R
(El uso de R
aquí es ortogonal al resto de la publicación, es decir, puede suponer cualquier programa genérico que pueda ejecutarse en una sesión de réplica). Muchas veces esto implicará hacer cosas como trazar, hacer gráficos, etc. ; y necesito mirar esto. Por lo tanto, preferiría tener la opción de mostrar gráficos que creé en mi contenedor. Así es como hago esto hasta ahora. Primero creo un Dockerfile
. Dejando fuera los pasos triviales, los más relevantes son:
# 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"]
Construyo la imagen y luego comienzo el contenedor usando:
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
y luego puede entrar en mi contenedor:
ssh -X docker@localhost -p 5000.
Esto me dará lo que quiero. Pero me gustaría saber si hay otra forma más amigable con los recursos de obtener gráficos / salida de GUI desde un contenedor. (Preferiría, si es posible, las soluciones no implicarían vnc
)
Hay una manera agradable y semi-fácil de obtener una salida gráfica de un contenedor Docker sin tener que ejecutar un daemon sshd
dentro del contenedor. Docker puede proporcionar rendimiento sin protección cuando se ejecuta un único proceso, que en este caso se supone que es R
La ejecución de un daemon sshd, por muy marginal que sea, introducirá sobrecarga adicional. Esto no se mejora ejecutando el daemon sshd como un proceso secundario del daemon supervisor. Ambos pueden prescindirse cuando uno hace un buen uso de los montajes de unión. Después de crear la imagen desde la que se supone que se debe ejecutar el contenedor, iniciamos un contenedor interactivo y /tmp/.X11-unix
carpeta /tmp/.X11-unix
en ella. Declararé el comando completo y explicaré en detalle lo que hace:
Docker ejecutar -i -t --rm /
-
-i
establece una sesión interactiva;-t
asigna un pseudo tty;--rm
hace que este contenedor sea efímero
-e DISPLAY = $ DISPLAY /
- configura la visualización del host en la pantalla de las máquinas locales (que generalmente será
:0
)
-u docker
-
-u
especificar que el proceso debe ser ejecutado por un usuario (aquídocker
) y no por el usuario root. Este paso es importante (vi)!
-v /tmp/.X11-unix:/tmp/.X11-unix:ro /
-
-v
bind monta el socketX11
reside en/tmp/.X11-unix
en su máquina local en/tmp/.X11-unix
en el contenedor y:ro
hace que el socket sea solo de lectura.
--name = "rdev" ubuntu-r R
-
--name=""
especifica el nombre del contenedor (aquírdev
); la imagen desde la que desea ejecutar el contenedor (aquíubuntu-r
); el proceso que desea ejecutar en el contenedor (aquíR
). (El último paso para especificar un proceso solo es necesario si no ha configurado unCMD
oENTRYPOINT
porENTRYPOINT
para su imagen).
Después de emitir este comando, debería estar mirando la bella salida de inicio R
Si tuviera que probar una demo(graphics)
para ver si la salida gráfica ya está funcionando, notará que no es así. Esto se debe a la extensión Xsecurity
que le impide acceder al socket. Ahora puede escribir xhost +
en su máquina local y probar demo(graphics)
en su contenedor de nuevo. Ahora debería tener salida gráfica. Sin embargo, se desaconseja encarecidamente este método, ya que permite el acceso a su xsocket a cualquier host remoto al que esté conectado actualmente. Mientras solo interactúes con sistemas de un solo usuario, esto podría ser de alguna manera justificable, pero tan pronto como haya varios usuarios involucrados, ¡esto será absolutamente inseguro! Por lo tanto, debes usar un método menos peligroso. Una buena forma es usar el servidor interpretado
xhost +si:localuser:username
que se puede usar para especificar un solo usuario local (ver man xhost
). Esto significa que el nombre de username
debe ser el nombre del usuario que ejecuta el servidor X11
en su máquina local y que ejecuta el contenedor acoplable. Esta es también la razón por la cual es importante que especifiques un usuario al ejecutar tu contenedor. Por último, pero no menos importante, siempre existe la solución más compleja de usar los archivos xauth
y .Xauthority
para otorgar acceso al socket X11
(ver man xauth
). Sin embargo, esto también implicará un poco más de conocimiento sobre cómo funciona X
El efecto positivo que esto puede tener se puede ver en la cantidad de procesos que se deben ejecutar para lograr lo que se desea.
(1) con supervisor
y sshd
ejecutándose en el contenedor:
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
cuando inicia sesión vía ssh
y ejecuta 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) con el método de montaje de enlace:
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