Virtual Networking mit Docker und OpenShift Funktionsweise von OpenShift 3.4

Autor Dipl. -Ing. Thomas Drilling |

Red Hat OpenShift lässt sich als „OpenShift Container Platform“ in Eigenregie betreiben. Die Netzwerkvirtualisierung ist dabei ein wesentlicher Aspekt, der in diesem Beitrag beleuchtet werden soll.

Anbieter zum Thema

OpenShist ist eine sicherere und vielseitigere Container Platform als etwa Docker Swarm und erlaubt Unternehmen eine innovativere App-Entwicklung.
OpenShist ist eine sicherere und vielseitigere Container Platform als etwa Docker Swarm und erlaubt Unternehmen eine innovativere App-Entwicklung.
(Bild: Red Hat)

Mit der Architektur von OpenShift haben wir uns bereits beschäftigt, in diesem Teil der OpenShift-Workshop-Reihe werfen wir einen Blick auf den Netzwerk-Layer. Dies ist essenziell für das Verständnis der Funktionsweise der Container-Kommunikation auf einen einzelnen Docker-Host und später in einem Kubernetes-Cluster.

OpenShift ist wie alle Cloud- und Virtualisierungslösungen sowie Container-Plattformen auf einen logischen Netzwerk-Layer angewiesen. OpenShift nutzt im Kernel Open vSwitch, wobei die Inter-Node-Kommunikation mit Hilfe via VXLAN als Transport-Netzwerk gekapselter logischer Netzwerke erfolgt. Containerisierte Workloads erfordern – auch wenn sie auf einen einzelnen Host residieren –, dass Anwendungen mit anderen Services sprechen können.

Ein containerisierter Applikationserver muss sich beispielsweise in irgendeiner Weise mit einer Datenbank im Container austauschen. Außerdem müssen in OpenShift gebaute Anwendungen auch von „außen“ nutzbar sein. Bevor wir aber einen Blick auf den Netzwerk-Layer von OpenShift werfen, schauen wir zunächst auf die Inter-Container-Kommunikation auf einem einzigen Docker-Host. Die lässt sich nämlich mit Linux-Bordmittel bewältigen.

Ein klassischer Docker-Host bindet hierzu schlicht die Container-Netzwerke, welche über ein virtuelles Ethernet-Device (z. B. eth0) verfügen, mit Hilfe eines einfachen Bridge-Device „docker0“ an den IP-Stack Hosts. Die IP-Adresse des Containers wird dabei vom Docker-Daemon verwaltet. Ähnlich arbeiten auch KVM-basierte Virtualisierungslösungen wie Red Hat Virtualization oder Oracle Virtual Box.

Wie schaut es aber bei Docker-Containern mit der Storage-Anbindung aus? Schließlich möchte man aus Containern heraus z. B. auch ein NAS ansprechen. Stateless Container sind zwar schick, aber letztendlich langweilig, könnte man keinen Status verwalten. Wie also bindet Docker beispielsweise NAS-Storage an Container an, ohne den Traffic über das Standard-Interface des Docker-Hosts zu leiten? Wir werden das Thema Storage-Nutzung in Container-Plattformen in einem weiteren Beitrag noch ausführlich beleuchten und schauen hier nur auf die „Berührungspunkte“ mit dem Netzwerk.

Bei klassischen Docker erfolgt ein IP-Storage-Zugriff aus einem Container nämlich problemlos über den Kernel-Stack des Docker-Hosts und damit einen völlig anderen Zugriffspfad. Der Kernel ist ja mittels iptables in der Lage, zwischen lokalen und Remote-Aufrufen zu unterscheiden und den Traffic passend zu routen, sodass IP-Storage-Zugriffe ihren Weg nach „außen“ finden.

Außen vor bleibt hier lediglich Objekt-Storage à la Amazon S3, der üblicherweise nicht über Kernel-Calls adressiert wird. REST-Aufrufe und die Docker-Bridge sorgen hier dafür, dass die Calls letztlich doch über das Default-Gateway nach außen geleitet werden. Übrigens funktioniert auch DNS standardmäßig in Docker-Containern, weil der Docker-Daemon Konfigurationdateien wie /etc/hosts, /etc/hostname oder /etc/resolv.conf beim Instanziieren des Containers anpasst.

SDS in OpenShift

Anders bei OpenShift: da die Plattform Container-Netzwerke über Node-Grenzen hinweg ermöglichen muss, benötigt es zwingend einen Software-Defined-Networking-Layer, der bei OpenShift mittels Open vSwitch realisiert ist. Open vSwitch beherrscht Security-Features wie VLAN-Isolation, Traffic Filtering und QoS, unterstützt zeitgemäße Monitoring-Funktionen, wie Netflow oder Port-Mirroring (SPAN, RSPAN) und lässt sich z. B via OpenFlow weitgehend automatisieren.

Das Design der Master-Node-Hosts ist übrigens in der umfangreichenSDN-Dokumentation von OpenShift sehr detailliert beschrieben.

Trotzdem soll OpenShift weitgehend kompatibel zum klassischen Docker bzw. zum Betrieb von Plain-Docker-Containern sein. Daher ergänzt OpenShift den Standard-Netzwerk-Stack des Docker-Hosts um zusätzliche Komponenten. So gibt es bei OpenShift-Nodes keine einzelne „docker0“-Bridge mehr, sondern zwei Bridge-Devices „lbr0“ und „br0“. Erstere ist eine klassische Linux-Bridge und „br0“, eine Open-vSwitch-Bridge, die über ein tun0-Device mit den Host-NICs kommuniziert, wobei beide miteinander über die zwei Devices „vlinbr“ und „vovsbr“ verbunden sind. Die nebenstehende Abbildung zeigt die Inter-Pod-Kommunikation in OpenShift.

Die Inter-Pod-Kommunikation via Open vSwitch.
Die Inter-Pod-Kommunikation via Open vSwitch.
(Bild: Etsuji Nakai, Cloud Solutions Architect)

Dabei kommunizieren klassische Docker-Container über die lbr0-Bridge, welche „OpenShift-intern“ auf „docker0“ „umgesetzt wird. Alles, was durch OpenShift, bzw. Kubernetes verwaltet wird, läuft dagegen über das Open-vSwitch-Gerät, im OpenShift-Regelbetrieb also jegliche Inter-Pod-Kommunikation.

Gestartet wird indes jeder Pod stets vom Docker-Daemon, hängt also initial zunächst an der „lbr0“ und bekommt von diesem auch seien IP-Adresse zugewiesen. Erst danach greift sich OpenShift diesen Endpunkt und biegt ihn auf das Open-vSwitch-Device um, sodass der Pod letztendlich zwar mit beiden Devices verbunden ist, in der Praxis aber kein Pod mehr über das lbr0-Device kommuniziert.

An der lbr0-Bridge hängt dann nur noch der Endpunkt für das Open-vSwitch-Gerät in Form des „vlinuxbr“-Devices. Somit ist jeder OpenShift-Pod über den durch OpenvSwitch und VXLAN-Tunnel realisierten logischen Netzwerk-Layer via Kubernetes orchestrierbar, bleibt aber trotzdem mit Docker bzw. für Docker-Aufrufe kompatibel.

Der VXLAN-Tunnel sorgt dabei als Transport-VLAN für die Node-to-Node-Kommunikation. Die Kommunikation zwischen klassischen Containern und OpenShift-Pods hingegen funktioniert aus Sicherheitsgründen ausschließlich über das lokale Interface und wird nicht via VXLAN an andere Knoten transportiert.

Externer Zugriff auf das Cluster Netzwerk

Erfordert ein Host von außerhalb der OpenShift Container Platform einen Zugriff auf das Cluster Network, gibt es zwei Möglichkeiten, dies zu realisieren. Das Operations-Team kann den Host als einen Platform-Node konfigurieren, ihn aber als unschedulable markieren, sodass der Master auf diesem keine Container verteilt. Dem Tagging und Labeling-Features von OpenShift wenden wir uns in einem künftigen Teil zu. Ferner könnte man einen Tunnel zwischen diesem Host und einem anderem Host „im“ Cluster-Network einrichten.

Als Alternative zum Default-SDN-Layer unterstützt OpenShift Container Platform Ansible Playbooks zum Installieren eines „flannel“-basierten Netzwerk-Layers. Dies ist vor allem dann nützlich, wenn die OpenShift Container Platform auf/in einer existierenden Cloud-Plattform wie OpenStack laufen soll und eine duale SDN-Konfiguration mit Open vSwitch auf “beiden” Plattformen vermieden werden soll.

Sicherheit bei OpenShift

OpenShift ist Multi-Tenant-fähig, so dass Applikationen mehrerer Mandanten auf einem Node laufen können. Dabei isolieren mittels SELinux (Security-Enhanced Linux) kreierte Security-Policies die einzelnen Instanzen voneinander. SELinux implementiert Mandatory Access Control (MAC), also eine „verpflichtende“ Zugangskontrolle und damit eine für eine PaaS unverzichtbare Vorrausetzung.

Während SELinux ein granulares Einrichten von zentral gesteuerten und überwachten Berechtigungen für Benutzer UND Applikationen erlaubt, sorgen Control Groups (cgroups) für das Aufteilen von Prozessoren, Speicher und I/O-Ressourcen zwischen den Applikationen. Entwickler können also die Ressourcennutzung (wie z. B. CPU-Time), den Speicherverbrauch oder die beanspruchte Netzwerkbandbreite im Detail steuern und damit Verarbeitungsprioritäten einrichten bzw. überwachen.

Mit cgroups lassen sich auch Policies zum Implementieren von SLAs umsetzen. Dabei isolieren „Kernel-Namespaces“ die Prozessgruppen so voneinander, dass sich die jeweiligen Ressourcen gegenseitig nicht beeinflussen können. Damit lässt sich die Sicherheit von Containern zumindest ansatzweise in die Nähe von virtuellen Maschinen bringen. Für die unter OpenShift laufenden Applikation sieht es dann so aus, als hätte sie exklusiven Zugriff auf eine einzelne Instanz von Red Hat Enterprise Linux, in Wirklichkeit teilt sie sich aber die Instanz mit anderen Applikationen.

OpenShift erweitert die Security-Merkmale von Docker/LXC & Ci um SELinux.
OpenShift erweitert die Security-Merkmale von Docker/LXC & Ci um SELinux.
(Bild: Red Hat)

Die geschilderten Sicherheitsmerkmale von OpenShift-Pods ähneln zwar denen von Docker- oder LXC-Containern (cgroups und namespaces gibt es auch hier). Zusammen mit SELinux erlauben sie aber eine noch striktere Trennung und existierten schon bei bzw. für OpenShift Online, das naturgemäß noch höhere Anforderungen an die Isolierung von Ressourcen untereinander stellt.

Artikelfiles und Artikellinks

(ID:44572018)