Wie ich Anwendungen in Containern mit Atomic ausführe: Teil 1

Tom Apr 12, 2018
Wie ich Anwendungen in Containern mit Atomic ausführe: Teil 1

Vor Kurzem habe ich sowohl meinen Arbeits- als auch meinen Privatrechner auf Fedora Atomic Workstation (nachstehend Atomic) umgestellt - einem Betriebssystem mit einer Architektur, in dessen Mittelpunkt Cloud und Containerisierung stehen. In dieser Blogpost-Reihe werde ich mich mit dem Projekt Atomic [1] beschäftigen und erklären, was ein Atomic-Betriebssystem ist, sowie erste Schritte  erläutern.

Was ist Atomic?

Unter dem Projekt Atomic versammeln sich viele Projekte rund um die Neukonzipierung des Betriebssystems nach den Grundsätzen einer unveränderlichen Infrastruktur unter Zuhilfenahme des LDK-Stacks (Linux, Docker, Kubernetes) [2]. Atomic selbst ist die Bezeichnung einer besonderen Art der (anbieterunabhängigen) Linux-Distribution. Diese ist nach den Designgrundsätzen verteilter Systeme aufgebaut, bei denen Konfigurationskonsistenz und Skalierbarkeit von grösster Bedeutung sind. Atomic verfügt über ein unveränderliches Dateisystem, wird über ein OSTree-System aktualisiert, das ähnlich wie Git funktioniert, und behandelt Container bevorzugt. Wir werden uns im Folgenden jedes dieser Attribute kurz anschauen. Ausführlichere Erläuterungen finden sich unter Project Atomic [3], und RedHat bietet ebenfalls ein hervorragendes Vergleichsdokument [4].

Unveränderliches Dateisystem

Im Gegensatz zu einem normalen Linux-System ist das Dateisystem in einem Atomic-Betriebssystem schreibgeschützt. Indem Änderungen am Dateisystem verhindert werden, kann sichergestellt werden, dass bei Szenarien wie dem Einsatz einer grossen Anzahl an Atomic Hosts in einem Cluster (oder wenn Knoten dynamisch zu einem Cluster hinzugefügt bzw. daraus entfernt werden) die Geräte alle genau auf demselben Stand sind. Genau genommen sind /etc und /var die einzigen Ordner, in die in Atomic geschrieben werden kann! Wenn Sie nun der Ansicht sind, dass dadurch die Verwaltung von Systemaktualisierungen sehr anders vonstatten gehen muss als bei normalen Linux-Systemen, dann haben Sie Recht. Der Wechsel von einem bekannten Stand zu einem anderen über transaktionale Upgrades spielt im Konzept von Atomic eine zentrale Rolle. Statt ein Paket über das Schreiben (oder Überschreiben) eines bestehenden Dateisystems zu aktualisieren, lädt man einen neuen OSTree herunter, der die Updates enthält. OSTrees sind unveränderliche, bootfähige Dateisystem-Baumstrukturen und wurden schon als «Git für Binärcodes» [5] oder eine «feinere Version von Linux-VServer-Hardlinks» bezeichnet [6].

Atomic-Updates

Das Wort «Atom» in Atomic rührt daher, dass Updates des Dateisystems von ihrer Art her atomar bzw. transaktional sind. Dies geht Hand in Hand mit dem unveränderlichen Dateisystem und bedeutet, dass jeder neue OSTree, der ausgecheckt wird, und jedes Paket, das darauf abgelegt wird, nur zur Verfügung steht, nachdem der neue OSTree aktiviert wurde - also praktisch nach einem Neustart [7].

Einer der grössten Vorteile dieses Systems liegt darin, dass Atomic die vorangegangene Version des OSTree standardmässig speichert. Wenn es also nach einer Änderung zu Problemen kommt, können Sie im Bootloader einfach die vorherige Konfiguration auswählen und nahtlos zum alten Zustand zurückkehren.

Unterstützung von Containern

Einer der interessantesten Aspekte von Atomic ist, dass es nicht nur Docker unterstützt, sondern es Ihnen auch ermöglicht, OCI-Container ohne Daemon aufzubauen und zu betreiben (zum Beispiel unter Nutzung von runc [8]). Container ohne Daemon sind insofern interessant, weil sie es uns ermöglichen, Containerprozesse bereits in der Bootsequenz zu starten, unterschiedliche Orchestrierungssysteme zu verwenden, eine bessere Init-Systemintegration zu erreichen und vieles mehr… [9]. In diesem Bereich gibt es bereits viele Werkzeuge, die Ihnen dabei helfen, Container ohne Docker aufzubauen und zu betreiben [10]. Es ist daher der ideale Zeitpunkt, sich jetzt damit zu beschäftigen.

Wenn Sie langlebige oder orchestrierte Containerprozesse steuern wollen, reicht Ihnen dieses System vielleicht nicht aus [11]. In diesem Fall wäre es sinnvoll, auf Ihrem Atomic Host zusätzlich Kubernetes oder Openshift auszuführen. Da Openshift über das grossartige OC Tool verfügt, ist das Ausführen einer lokalen Openshift-Instanz so einfach wie eine Systemeinheit mit «OC Cluster Up» und das Verknüpfen einiger Volumes für persistente Konfiguration und Speicherung. Openshift in 3.9 verwendet bereits CRI-O [12] als Laufzeit-Schnittstelle für Container [13], so dass Sie auch hier mit Laufzeiten ohne Docker experimentieren können.

Anwendungen in Atomic

Wie wir bereits festgestellt haben, funktioniert das Installieren von Paketen und Anwendungen in Atomic anders. Daher betrachten wir kurz die unterschiedlichen zur Verfügung stehenden Methoden.

Flatpak

Am einfachsten lässt sich eine Anwendung mit Flatpak ausführen. Flatpak ist eine distributionsunabhängige Sandbox, die über die üblichen Laufzeiten verfügt und alle erforderlichen Bibliotheken im Paket umfasst. Sicherheit wird bei Flatpak grossgeschrieben. Durch die Sandbox wird der Zugriff auf andere Prozesse verhindert.

Als zentrales Repository für die Flatpak-Anwendungen dient Flathub [14]. Die Anwendungen können von der Webseite, über die Benutzeroberfläche der Software oder über die Kommandozeile installiert werden. Der grösste Nachteil von Flatpaks besteht aktuell darin, dass sie nicht in ausreichender Anzahl verfügbar sind.

Es gibt noch andere Paket-Anwendungsformate, die auf Atomic laufen, zum Beispiel AppImages. Ich empfehle Ihnen, sich diese Vergleichstabelle [15] anzuschauen, um mehr zu jedem Format zu erfahren.

rpm-ostree

Bei Atomic gibt es anstelle eines Package Managers den Befehl «rpm-ostree». Mit diesem Befehl lassen sich Pakete über das aktuelle Dateisystem legen und ein neuer OSTree erstellen. Auf diese Weise als Overlay installierte Pakete unterliegen denselben Update-Regeln von Atomic wie das System selbst [16].

Mit dem Befehl «rpm-ostree» lassen sich so einige Kunststücke bewerkstelligen (wie zum Beispiel Bubblewrapping RPM % Post Scripts zur Sicherstellung der OSTree-Integrität). Da in diesem Format derzeit nur eine Teilmenge der Pakete im Haupt-Repository zur Verfügung steht [17], sollten Sie diesen Befehl nur verwenden, wenn Sie es nicht vermeiden können. Mein aktueller OSTree-Stand sieht wie folgt aus:

 ostree://pirate:fedora/27/x86_64/workstation
Version: 27.98 (2018-03-25 21:40:41)

BaseCommit: 837c870919d5182948ae9041e6404c5e306bae6c4db1ba3e07b2c323af8b7556

GPGSignature:
Valid signature by 860E19B0AFA800A1751881A6F55E7430F5282EE4

LayeredPackages:
libselinux-python python util-linux-user zsh
 

Wenn wir uns das genauer ansehen, zeigt sich, dass ich den (zum Zeitpunkt des Schreibens dieses Blogeintrags) neuesten OSTree verwende. Ich beziehe ihn vom inoffiziellen europäischen «pirate mirror» [18], und dass ich nur vier überlagerte Pakete habe,

util-linux-user ist vorhanden, somit kann ich zur Shell meiner Wahl wechseln. Zsh und die Python-Pakete sind installiert, so dass ich mein System mit Hilfe von Ansible konfigurieren kann, das ist alles! Die meisten meiner Anwendungen werden mit der letzten Methode - der Containerisierung - bereitgestellt, auf die wir jetzt einen Blick werfen.

Container

Wenn Sie schon einmal Container verwendet haben, dann höchstwahrscheinlich eher im Zusammenhang mit dem Backend oder Webanwendungen als mit dem Desktop. Die gute Nachricht ist, dass es nicht schwierig ist, auch Desktop-Anwendungen mit Hilfe von Containern auszuführen, und etwas Arbeit hier kann uns ein wirklich tolles portierbares System verschaffen. Es gibt Leute, die in diesem Bereich wirklich tolle Arbeit leisten, und ich kann nur Jess Frazelle’s Github [19] empfehlen, um ein paar Ideen für die Werkzeuge zu bekommen, die man erfolgreich für Container einsetzen kann [20].

Atomic verfügt ebenfalls über einen eigenen Befehl zur Verwaltung von Containern. Werden INSTALL, RUN und UNINSTALL zu unserem Image hinzugefügt, kann der Atomic-Befehl Container erstellen, die ihren Lebenszyklus selbst verwalten, sich selbst installieren, indem sie zum Beispiel Teile des Dateisystems des Hosts einbauen und Systemeinheiten installieren und aktivieren. Sie können den Atomic-Befehl sogar verwenden, um die eigenen Container zu erweitern, indem die neueste Image-Version aus einem Repository entnommen wird, um Ihren Container damit neu zu erstellen.

Aber wozu das Ganze?

 Jetzt fragen Sie sich vielleicht: «Das klingt ziemlich toll für einen Cloudserver oder meinen Kubernetes-Cluster, aber warum sollte ich das für meinen Desktop einsetzen?» Das ist eine berechtigte Frage. Wenn Sie diesen Weg einschlagen, dann sollten Sie gern mit Containern arbeiten und auf eine Fehlersuche vorbereitet sein. Ich denke jedoch, dass sich die Mühe lohnt, denn Sie werden nicht nur einige der spannendsten Werkzeuge der Container-Technologie entdecken und mit ihnen arbeiten, sondern auch Erfahrungen damit sammeln und - davon bin ich überzeugt - die Vorteile von der Erstellung portierbarer Container-Umgebungen zu schätzen lernen. Wenn Sie an Ihrem Arbeitsplatz mit Containern arbeiten, dann können Sie Ihr gesamtes System ganz einfach überall reproduzieren und innerhalb von Minuten zum Laufen bringen. Damit werden wir uns in einem späteren Artikel näher beschäftigen. Ausserdem möchte ich noch hinzufügen, dass es einfach extrem angenehm ist, auf diese Weise zu arbeiten, und die Atomic-Gemeinde ist wirklich nett, offen und zugänglich. Wenn Sie Container für die Entwicklung oder Bereitstellung von Software nutzen, dann ist es wirklich nur ein kleiner Schritt, Container auch auf dem Desktop zu verwenden.

Damit sind wir mit unserem kurzen Überblick über Atomic am Ende. Das nächste Mal werden wir uns ansehen, wie man eine Desktop-Anwendung in einen Container packt und sie ohne Daemon ausführt, so dass Sie damit beginnen können, Ihre Umgebung in der Welt von Atomic neu zu erstellen.

>>> Hier gelangen Sie zum zweiten Teil der Serie.


   [1] https://www.projectatomic.io/
   [2] http://www.projectatomic.io/docs/introduction/
   [3] https://www.projectatomic.io/docs/
   [4] https://access.redhat.com/articles/2772861
   [5] https://ostree.readthedocs.io/en/latest/manual/introduction/
   [6] https://ostree.readthedocs.io/en/latest/
   [7] Derzeit wird daran gearbeitet, Änderungen vor Ort zu ermöglichen https://github.com/projectatomic/rpm-ostree/issues/639
   [8] https://github.com/opencontainers/runc
   [9] Für einen guten Überblick über die Architektur von Docker und die Funktionsweise von Laufzeiten empfehle ich folgende Artikel.
 [10] http://www.projectatomic.io/blog/2018/03/the-many-ways-to-build-oci-images/
 [11] Für eine leichte Cron-artige Ersetzung kann ich Crontainer des Niner-Kollegen Phil Hassig empfehlen
 [12] https://github.com/kubernetes-incubator/cri-o
 [13] https://www.redhat.com/en/blog/introducing-cri-o-10
 [14] https://flathub.org/
 [15] https://askubuntu.com/a/1009061
 [16] Der Befehl für die Aktualisierung des Systems «atomic host upgrade» ist tatsächlich ein Alias für «rpm-ostree upgrade»
 [17] Das Hinzufügen zusätzlicher Remotes wie epel funktioniert aus offensichtlichen Gründen auch nicht
 [18] https://faw.piratemirror.party/README.txt
 [19] https://github.com/jessfraz
 [20] Werfen Sie auch einen Blick auf ihren Blog! https://blog.jessfraz.com