Container erstellen mit Systemd
Mit Systemd lassen sich recht simple Conatainer erstellen, welche mit systemd-nspawn
erstellt und mit einem seperaten Managment-Tool verwaltet werden.
Im Grunde ist solch ein Container für mich nur chroot auf Steroiden. Ein weiteres Manko dabei ist das man SElinux deaktivieren muss, da sonst bestimmte Operationen, wie zum Beispiel das ändern des Passwortes innerhalb der systemd-Umgebung, nicht möglich sind.
Vorbereitungen
Ich verwende hierbei Centos 7.5.
Zuerst deaktivieren wir SElinux mit dem Befehl setenforce Permissive
oder auch setenforce 0
Um diese Einstellung persistent einzustellen ersetzen wir in der Datei /etc/sysconfig/selinux
die Zeile
SELINUX=enforcing
durch
SELINUX=permissive
Natürlich kann man auch nach dem Setzen des Passwortes SElinux per setenforce 1
wieder aktivieren.
Nun erstellen wir das Root-Verzeichnis für das Container-System:
$ mkdir /var/lib/container
Erstellen des Containers
Um einen Centos-Container zu erstellen führen wir den folgenden Befehl aus:
$ yum -y --releasever=7 --installroot=/var/lib/container/centos7 install systemd passwd yum vim
Hierbei wird ein Centos in der Version 7 (--releasever
) im Verzeichnis /var/lib/container/centos7 (--installroot
) angelegt und es werden die Pakete installiert, welche nach dem install
mit angegeben werden.
Dies ist natürlich nur das rudimentäre System. Man kann, je nach Bedarf, noch weitere Pakete in den container installieren.
An dieser Stelle könnte man schon den Container starten hineinspringen, allerdings wird dann nach einem root-Passwort gefragt, welches bisher noch nicht gesetzt ist.
Um nun zu einer vollständigen Umgebung zu wechseln, in der man sich tatsächlich einloggen kann, muss man dem systemd-nspawn-Befehl den passwd-Befehl anhängen. Durchgeführt wird dies mit dem folgenden Befehl:
systemd-nspawn -D /var/lib/container/centos7 passwd
Alternativ dazu wechselt man mit dem Befehl
systemd-nspawn -D /var/lib/container/centos7
in den Container und ändert dort mit passwd
das root-Passwort.
ANMERKUNG: Um sich später erfolgreich einloggen zu können muss im Container die Datei /etc/securetty
entfernt oder umbenannt werden.
$ systemd-nspawn -D /var/lib/container/centos7
Spawning container centos7 on /var/lib/container/centos7.
Press ^] three times within 1s to kill container.
-bash-4.2# mv /etc/securetty /etc/securetty.disable
Bei auf Debian basierenden Systemen muss dbus
installiert sein
Container verwalten
Nun können wir den Container starten und hinwechseln, dies geschieht mit:
systemd-nspawn -D /var/lib/container/centos7 -b
Hier lauscht der Container am vorhandenen Netzwerk-Interface, wodurch uns nach dem Login direkt eine Netzwerkverbindung zur Verfügung steht.
Um den Container wieder zu verlassen, ohne poweroff
eingeben zu müssen, verwendet man die Tastenkombination:
Strg + ]
, also Strg+ Alt Gr + 9
auf meiner Tastatur und das dabei muss die ]
-Taste 3 mal hintereinander gedrückt werden.
Verwaltung mit machinectl
machinectl
ist das Systemd-eigene Verwaltungs-Tool.
Um den Container für die Verwaltung durch Systemd verfügbar zu machen verwenden wir den folgenden Befehl:
$ systemctl enable systemd-nspawn@centos7
Created symlink from /etc/systemd/system/machines.target.wants/systemd-nspawn@centos7.service to /usr/lib/systemd/system/systemd-nspawn@.service.
Der nächste Schritt ist das starten des Containers mithilfe des Systemd-Container-Managment-Tool machinectl
:
$ machinectl start centos7
Und genauso wie bei regulären Systemd-Diesnten kann man sich auch den aktuellen Staus anzeigen lassen:
$ machinectl status centos7
centos7
Since: So 2018-05-27 20:17:46 CEST; 4s ago
Leader: 11386 (systemd)
Service: nspawn; class container
Root: /var/lib/container/centos7
Iface: ve-centos7
OS: CentOS Linux 7 (Core)
Unit: systemd-nspawn@centos7.service
├─11385 /usr/bin/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --network-veth --machine=centos7
├─11386 /usr/lib/systemd/systemd
└─system.slice
├─console-getty.service
│ └─11418 /sbin/agetty --noclear --keep-baud console 115200 38400 9600 vt220
├─systemd-logind.service
│ └─11416 /usr/lib/systemd/systemd-logind
├─dbus.service
│ └─11414 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
└─systemd-journald.service
└─11402 /usr/lib/systemd/systemd-journald
Mai 27 20:17:46 localhost.localdomain systemd-nspawn[11385]: Starting Console Getty...
Mai 27 20:17:46 localhost.localdomain systemd-nspawn[11385]: [ OK ] Reached target Login Prompts.
Mai 27 20:17:46 localhost.localdomain systemd-nspawn[11385]: [ OK ] Started Cleanup of Temporary Directories.
Mai 27 20:17:46 localhost.localdomain systemd-nspawn[11385]: [ OK ] Started Login Service.
Mai 27 20:17:46 localhost.localdomain systemd-nspawn[11385]: [ OK ] Reached target Multi-User System.
Mai 27 20:17:46 localhost.localdomain systemd-nspawn[11385]: [ OK ] Reached target Graphical Interface.
Mai 27 20:17:46 localhost.localdomain systemd-nspawn[11385]: Starting Update UTMP about System Runlevel Changes...
Mai 27 20:17:46 localhost.localdomain systemd-nspawn[11385]: [ OK ] Started Update UTMP about System Runlevel Changes.
Mai 27 20:17:47 localhost.localdomain systemd-nspawn[11385]: CentOS Linux 7 (Core)
Mai 27 20:17:47 localhost.localdomain systemd-nspawn[11385]: Kernel 3.10.0-862.3.2.el7.x86_64 on an x86_64
Um sich nun in den Container einzuloggen kann man auch wieder machinectl
verwenden:
$ machinectl login centos7
Connected to machine centos7. Press ^] three times within 1s to exit session.
CentOS Linux 7 (Core)
Kernel 3.10.0-862.3.2.el7.x86_64 on an x86_64
centos7 login:
Anmerkung Wenn ich mich per machinectl login <Containername>
in einen Container einloggen fehlt leider immer Netzwerkverbindung.
Ich habe noch keine Lösung dafür gefunden und deshalb empfehle ich immer die Verwendung von systemd-nspawn -D /var/lib/container/centos7 -b
Um sich eine Auflistung der vorhandenen Container auf dem System anzeigen zu lassen, verwendet man:
$ machinectl list
MACHINE CLASS SERVICE
centos7 container nspawn
1 machines listed.
weitere Funktionen
Ähnlich wie z.B. auch LXC/LXD bietet der Systemd Befehl machinectl
Funktionen, neben dem Starten, Neustarten, etc., zum kopieren von Dateien vom Hostsystem in den Container und auch hinaus an.
poweroff NAME...
Power off one or more containers. This will trigger a reboot by sending SIGRTMIN+4 to the container's init process, which causes systemd-compatible init systems to shut down cleanly.
reboot NAME...
Reboot one or more containers. This will trigger a reboot by sending SIGINT to the container's init process, which is roughly equivalent to pressing Ctrl+Alt+Del on a non-containerized system,
and is compatible with containers running any system manager.
copy-to NAME PATH [PATH]
Copies files or directories from the host system into a running container....
copy-from NAME PATH [PATH]
Copies files or directories from a container into the host system....
Es ist sogar das Klonen von Containern möglich…
clone NAME NAME
Clones a container or disk image. The arguments specify the name of the image to clone and the name of the newly cloned image. Note that plain directory container images are cloned into
subvolume images with this command. Note that cloning a container or VM image is optimized for btrfs file systems, and might not be efficient on others, due to file system limitations.