Graphische Anwendungen mit Containern

Container isolieren Prozesse. Die zusätzliche Sicherheit gibt es fast Umsonst. Die graphische Ausgabe ist nicht von der eines »normalem« Programmaufrufs zu unterscheiden.

In der Grundkonfiguration sind alle Prozesse in einem Container strikt von denen des Hosts und anderen Containern getrennt. Ein Container kann keine fremde Bibliotheken oder Hardware-Schnittstellen benutzen.

Jede gewünschte Interaktion muss explizit freigegeben werden. Die LXD-Management-Ebene bietet einfache Werkzeuge zur Definition der Schnittstellen.

lxc profile

Schlüssel für die Kommunikation nach Außen ist der Befehl lxc profile. Während der Initialisierung wird ein »Default-Profil« angelegt, das über lxc profile show default ausgelesen werden kann. Dort werden Basisdienste, wie das Filesystem und das virtuelle Netzwerk definiert.

$ lxc profile show default
config: {}
description: Default LXD profile
devices:
  eth0:
    name: eth0
    network: lxdbr0
    type: nic
root:
  path: /
  pool: default
  type: disk
  name: default

GUI-Profil

Um die graphische Ausgabe auf den Bildschirm des Hosts auszugeben, wird ein Profil hinzugefügt. Im Projekt ib-container ist eine Standardkonfiguration enthalten

config:
  environment.DISPLAY: :0
  raw.idmap: both 1000 1000
  user.user-data: |
    packages:
      - x11-apps
      - mesa-utils
description: GUI LXD profile
devices:
  X0:
    path: /tmp/.X11-unix/X0
    source: /tmp/.X11-unix/X0
    type: disk
name: gui

Diese Konfiguration wird über

lxc profile edit gui < {name}

zum LXD-Profil hinzugefügt. Dann ist der Container graphikfähig.

Die Schnittstelle trifft zwei Grundannahmen:

  • der User, der die LXD-Container verwendet, hat die UID 1000.
  • das System, mit dem der User arbeitet, nutzt das Display-Port :0.

Das Setup-Skript für den ib-container erwartet einen Standard-Nutzer mit der UID 1000 und eine gra­phische Ausgabe auf $DISPLAY :0.

Sollte das System anders konfiguriert sein, muss das Profil angepasst werden.

Die eigene UID ermittelt id

$ id
 uid=1000(topo) gid=1000(topo) Gruppen=1000(topo),4(adm), … 
# bzw
$ id
uid=1000(topo) gid=1000(topo) groups=1000(topo),4(adm), … 

Das Remapping der UID’s des Hosts zum Container ist bei Linuxcontainers.org beschrieben.

Den Port der graphische Ausgabe gibt 'echo $DISPLAY' aus. Falls der Wert von :0 abweicht, muss dies in dem Profil angepasst werden. Gibt echo $DISPLAY beispielsweise :1 aus, muss “:0” gegen “:1” und “X0” gegen “X1” ausgetauscht werden.

Erfolgskontrolle

Ob die Umleitung der graphischen Ausgabe des Containers auf den Bildschirm des Hosts richtig konfiguriert ist, kann sehr einfach überprüft werden:

lxc open {container}
xeyes

Alternative: SSH

Falls über das Netzwerk auf einen Container zugegriffen wird, kann die graphische Ausgabe – wie gewohnt – per SSH auch über diverse Stationen umgeleitet werden

topo@aio:~$ ssh -Y omega                # omega ist ein im Netzwerk erreichbarer Rechner
Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-200-generic x86_64)

topo@omega:~$ ssh -Y ubuntu@hierdevel   # hierdevel ist ein Container 
Welcome to Ubuntu 20.04.5 LTS (GNU/Linux 5.15.0-56-generic x86_64)

hierdevel:~$ xeyes

oder in der Kurzform:

nothing
Abbildung: Graphische Ausgabe des Containers via SSH

Ressourcen