Alles fließt

Ethernet und IP sind zentrale Bestandteile heutiger Netze und decken das komplette Anwendungsspektrum vom Heim- bis zum Backbone-Netz ab. Die schleppende Einführung von IPv6 zeigt, dass es in diesem Umfeld schwerfällt, Neuerungen umzusetzen. Die OpenFlow-Architektur verspricht hier Abhilfe.

In Pocket speichern vorlesen Druckansicht
Lesezeit: 15 Min.
Von
  • Zdravko Bozakov
Inhaltsverzeichnis

Eine Netzwerkinfrastruktur muss ein großes Spektrum von Anwendungsgebieten bedienen und gleichzeitig performant, skalierbar, abwärtskompatibel sowie kosteneffizient sein. Vom Heimnetzwerk bis zum Carrier-Backbone hat sich heute – neben IP – Ethernet als Hauptbestandteil der IT-Infrastruktur durchgesetzt. Obwohl diese Kombination eine beeindruckende Anzahl von Szenarien abdeckt, hemmt deren Verankerung Innovationen mit neuen Vernetzungsansätzen. Die sich schon Jahrzehnte hinziehende IPv6-Einführung verdeutlicht die Schwierigkeit, neue Techniken flächendeckend zum Einsatz zu bringen.

Dieser Entwicklung wollte die Universität Stanford entgegenwirken, als Ergebnis entstand die OpenFlow-Architektur. Das Konzept sieht vor, die Zeit zwischen Entwurf und Produktiveinsatz einer neuen Netzwerklösung deutlich zu verringern (siehe „Onlinequellen“, [a]). Mittlerweile unterstützen viele Hardwarehersteller OpenFlow, erlaubt es doch Netzbetreibern die in Switches integrierte Forwarding-Logik über eine offene API zu programmieren.

Ethernet verbindet Endgeräte auf der Netzwerkschicht (Layer 2) zu einem lokalen Netz (LAN), in dem jeder angeschlossene Knoten alle anderen über eine flache Adresse ansprechen kann. Dabei sind moderne Switches in der Lage, über einen einfachen Lernalgorithmus effizient und schleifenfrei eine Verbindung zwischen den Knoten aufzubauen. Seinen Siegeszug verdankt Ethernet im Wesentlichen den geringen Hardwarekosten sowie der einfachen Konfiguration der so realisierten Netze. Anders als bei OpenFlow-Switches haben Benutzer jedoch kaum Möglichkeiten, das Paket-Forwarding direkt zu beeinflussen.

Für ein besseres Verständnis der OpenFlow-Architektur hilft ein Blick auf die Arbeitsweise eines traditionellen L2-Switches. Er hat im Wesentlichen die Aufgabe, eingehende Pakete zu dem Port weiterzuleiten, an dem der Zielrechner angeschlossen ist. Dafür wertet er die Quell-MAC-Adresse jedes eingehenden Pakets aus und trägt sie zusammen mit dem dazugehörigen Eingangs-Port in der sogenannten Forwarding-Tabelle ein. Den Ziel-Port schlägt er für jedes Paket in der Tabelle nach. Bei einer Übereinstimmung leitet er das Paket an den gespeicherten Port weiter, andernfalls schickt er es per Broadcast an alle Ports. Nicht genutzte Einträge entfernt das Gerät nach einer vordefinierten Zeit aus der Forwarding-Tabelle. Da üblicherweise nicht alle Netzteilnehmer gleichzeitig miteinander kommunizieren, lassen sich so Switches mit einigen Tausend Speichereinträgen selbst in größeren Netzen effektiv einsetzen. Darüber hinaus führt der relativ geringe Speicherbedarf auch zu vergleichsweise niedrigen Herstellungskosten.

OpenFlow erweitert dieses einfache Grundprinzip, indem es die Einträge der Forwarding-Tabellen um weitere Header-Felder ergänzt und eine Schnittstelle bereitstellt, über die sich Tabelleneinträge extern manipulieren lassen. Statt des traditionellen L2-Lernalgorithmus können Benutzer somit beliebige Regeln für die Paketweiterleitung spezifizieren. Dadurch entkoppelt OpenFlow den für die Forwarding-Logik zuständigen Kontrollpfad vom Datenpfad und schafft die Voraussetzung für das Integrieren von Anwendungsfunktionen direkt ins Netzwerk. Als Beispiel hierfür sind Rechenzentren zu nennen, in denen zum optimalen Auslasten der physischen Server viele virtuelle Maschinen ständig migriert werden. Ein Netz aus intelligenten Switches kann den zur VM gehörenden Verkehr koordiniert und verlustfrei umleiten und gleichzeitig Datenstaus verhindern.

Die OpenFlow-Architektur trennt Kontrollebene und Forwarding-Pfade strikt voneinander (Abb. 1).

Die Bezeichnung OpenFlow bezieht sich sowohl auf die Switch-Architektur als auch auf das für die Kommunikation zwischen Daten- und Kontrollpfad verwendete Protokoll. Intern arbeitet OpenFlow mit sogenannten Flows als kleinste Einheit. Ein Flow ist definiert als eine Folge von Paketen mit identisch gesetzten Header-Bits, beispielsweise eine TCP-Verbindung (das heißt, je zwei Tupel aus Port und IP des Quell- beziehungsweise Zielrechners) oder Pakete mit einer bestimmten MAC-Source-Adresse. Jeder OpenFlow-kompatible Switch enthält eine Forwarding-Tabelle, die sogenannte Flow-Tabelle, und ist über einen SSL-gesicherten Kontrollkanal mit einem Controller verbunden (siehe Abbildung 1).

In der Flow-Tabelle speichert der Switch für jeden Flow einen Eintrag mit entsprechend gesetzten Header-Bits. Für jedes empfangene Paket prüft er, ob ein übereinstimmender Eintrag in der Tabelle existiert. Jedem dieser Einträge ist mindestens eine Aktion zugeordnet, die für alle als Treffer detektierten Pakete zum Einsatz kommt. Im Wesentlichen besteht die Flow-Tabelle also aus einer Liste von Regeln mit dazugehörigen Paketverarbeitungsaktionen. Alle OpenFlow-Switches kennen für die Kompatibilität der Programmierschnittstelle die in Abbildung 2 dargestellten Header-Felder für den Lookup.

Anhand definierter Header-Felder der Datenpakete entscheidet ein OpenFlow-fähiger Switch, welche Forwarding-Regel zum Tragen kommt (Abb. 2).

Darüber hinaus können Hardwarehersteller weitere Pakettypen unterstützen. In jedem Eintrag der Flow-Tabelle sind die Header-Bits entweder explizit auf „1“ gesetzt oder enthalten eine Wildcard, die jeden Wert als Treffer wertet. Weiterhin ist in der Tabelle jedem Eintrag eine Priorität zugewiesen. Das stellt sicher, dass Lookups stets ein eindeutiges Ergebnis liefern. Die Notwendigkeit für das Feld Flow-Priorität verdeutlichen die beiden folgenden Tabelleneinträge: „Alle Pakete mit TCP Quellport 1024“ respektive „Alle Pakete mit TCP Zielport 80“. Hätten beide Regeln die gleiche Priorität, würde ein eingehendes Paket mit Quellport 1024 sowie Zielport 80 mit beiden übereinstimmen und ein undefiniertes Verhalten triggern. Weiter gehören zut jedem Eintrag der Flow-Tabelle Zähler, die die Anzahl der Treffer, die übertragene Datenmenge, sowie die Zeit seit dem letzten Treffer beinhalten.

Ähnlich wie bei den Header-Feldern muss jeder OpenFlow-fähige Switch eine Reihe von Basisaktionen unterstützen, beispielsweise um Pakete über einen bestimmten Switch-Port weiterzuleiten, an alle Ports zu fluten oder sie zu verwerfen. Darüber hinaus können Hersteller optionale Aktionen unterstützen, zum Beispiel: bestimmte Header-Felder modifizieren, VLAN- oder MPLS-Tags hinzufügen respektive entfernen oder Pakete einem bestimmten Puffer zuweisen. Eine detaillierte Beschreibung der verfügbaren Aktionen und Flowtable-Einträge findet sich in der gut lesbaren Spezifikation [b].

Letztere gibt keine Implementierungsdetails vor, sondern beschreibt lediglich die Architektur, das erwartete Verhalten sowie die für die Kommunikation mit dem Controller notwendigen Datentypen. Konzeptionell besteht ein OpenFlow-Switch aus einer Pipeline mehrerer seriell geschalteter Forwarding-Tabellen. Für jedes ankommende Paket sieht er zunächst in der ersten Tabelle nach. Im Falle eines Treffers führt er alle dem Eintrag zugeordneten Aktionen in der vorgegebenen Reihenfolge aus. Andernfalls reicht er das Paket an die nächste Tabelle weiter. Falls der Switch am Ende der Pipeline keine Übereinstimmung findet, sendet er das Paket an seinen Controller, der daraufhin üblicherweise einen neuen Forwarding-Eintrag generiert. Obwohl sich seit OpenFlow Version 1.2 die Pipeline über entsprechende Aktionen steuern lässt, können mehrere Tabellen nach außen auch als eine einzige erscheinen. Beispielsweise lassen sich L2- und L3-Lookups intern in getrennten Tabellen ausführen.

Mit dieser simplen Abstraktion können Hardwarehersteller OpenFlow implementieren und optimieren, ohne ihre gut gehüteten Architekturdetails offenlegen zu müssen. Für die Marktdifferenzierung können sie – neben den üblichen Leistungsmerkmalen wie Anzahl der Ports, Backplane- und Speicherkapazität – optionale OpenFlow-Aktionen implementieren oder selbst neue definieren. Außer in Firmware von Netzwerkgeräten lässt sich der OpenFlow-Datenpfad auch auf Standard-PC-Hardware implementieren. Das Projekt OpenVSwitch stellt entsprechende Software für Linux zur Verfügung.

Ein Grundprinzip von OpenFlow ist, dass der für die Implementierung der Steuerlogik zuständige Controller komplett von der Switch-Hardware getrennt ist. Somit kann man auf die eigenen Anforderungen angepasste Controller implementieren, die sich mit jedem OpenFlow-Switch einsetzen lassen. Die Kommunikation findet üblicherweise zwischen einem einzelnen Controller und mehreren Datenpfaden (Switches) über eine SSL-gesicherte Verbindung statt. Dabei kann die Steuerung In-Band oder aber über ein dediziertes Kontrollnetz erfolgen.

Üblicherweise meldet sich jeder OpenFlow-Switch selbstständig bei einem vorkonfigurierten Controller an. Dies erfolgt beim Handshake bei dem sich beide unter anderem auf die unterstützten Features (zum Beispiel Aktionen) einigen. Dann handeln beide Seiten die kleinste unterstützte OpenFlow-Version aus und tauschen nach dem Aufbau der Kontrollverbindung Protokollnachrichten aus. Der Controller installiert oder löscht neue Einträge in der Flow-Tabelle, fragt den Zustand der Switch-Zähler, -Tabellen und -Ports ab oder generiert Pakete für den Versand über einen Datenpfad-Port. Der Datenpfad nutzt die Kontrollverbindung für Statusmitteilungen, zum Weiterleiten empfangener Pakete, zur Weiterverarbeitung am Controller oder um ihn über die Löschung von Flow-Einträgen zu benachrichtigen (beispielsweise nach einem Timeout).

Obwohl das OpenFlow-Protokoll vergleichsweise simpel ist, wäre eine Neuimplementierung für jedes neue Projekt in der Praxis äußerst mühsam. Daher entstanden seit der Einführung von OpenFlow vor vier Jahren eine Reihe von Frameworks, die das Programmieren stark vereinfachen. Sie stellen häufig genutzte API-Aufrufe als Bibliotheken bereit und koordinieren die Kommunikation zwischen Controller-Modulen. Das älteste und wohl bekannteste Beispiel hierfür ist NOX. Es baut auf einem Event-System auf und erlaubt das Schreiben von OpenFlow-Controllern sowohl in C als auch in Python. Der Nutzer definiert eine Reihe von Callback-Funktionen, die von ankommenden OpenFlow-Protokollnachrichten getriggert werden. Somit lässt sich zum Beispiel für jedes Paket, das der Switch an den Controller weiterleitet, basierend auf dessen Header-Daten ein neuer Flow-Eintrag generieren. Ähnlich kann eine Initialisierung beim Anmelden eines neuen Datenpfades erfolgen. Mittlerweile konkurrieren eine ganze Reihe von Projekten mit teils unterschiedlichen Zielen um die Gunst der Nutzer.

Im Enterprise-Bereich zielen die jeweiligen Pakete der Open-Source-Projekte FloodLight und Maestro auf hohe Performance und Stabilität. Beide sind in Java geschrieben und greifen zum optimalen Ausnutzen der Ressourcen aktueller Mehrkernsysteme auf Multi-Threading zurück. Dadurch sind diese Controller in der Lage, mehrere Millionen Flow-Einträge pro Sekunde zu generieren und so die Flow-Tabellen vieler Datenpfade gleichzeitig zu befüllen. Kommerzielle Varianten, wie BigSwitch oder NECs ProgrammableFlow, versprechen eine reibungslose Integration in Management- und Monitoring-Systeme aus der eigenen Produktreihe. Andere Vertreter wie Trema oder OpenFaucet haben das Ziel, die Programmierung auch in anderen Sprachen (Ruby respektive Python) zu ermöglichen. Somit kann man die Ansteuerung von Netzwerkgeräten leicht in bestehenden Programmcode integrieren. Eine vollständige Auflistung aller Controller-Frameworks würde den Rahmen dieses Artikels sprengen, online wird man aber eher fündig [c].

In der Praxis ist es oft sinnvoll, die Steuerungslogik auf mehrere Controller zu verteilen. Zum einen zum Verteilen der Last und zum anderen, um den Controller nicht zum Single Point of Failure mutieren zu lassen. Vor allem aber lassen sich mehrere Netzanwendungen unabhängig voneinander und parallel auf der gleichen physischen Netzinfrastruktur ausführen. Den parallelen Betrieb mehrerer Controller auf einem gemeinsamen Substrat kann man als eine Art Netzwerkvirtualisierung betrachten. Konzeptionell ist die Virtualisierung dank strikter Trennung der Kontroll- und Forwarding-Pfade in der OpenFlow-Architektur trivial. Es ist jedoch eine Instanz erforderlich, die sicherstellt, dass nicht mehrere Controller die Forwarding-Regeln der Switches überschreiben können. Diese Isolation bezeichnet man im OpenFlow-Kontext als „Slicing“, da jeder Controller eine eigene Scheibe (Slice) der Switch-Ressourcen zugewiesen bekommt.

Die Umsetzung von Slicing erfolgt entweder als Feature des Herstellers, zum Beispiel durch direktes Unterstützen mehrerer Forwarding-Tabellen im Switch, oder als eigene externe Komponente. Letztere Variante gibt es mit dem Projekt FlowVisor als quelloffenes Framework. Der spezielle OpenFlow-Controller erlaubt Netzadministratoren, über die sogenannten FlowSpaces den Zugriff auf die Forwarding-Tabellen einzuschränken. Ein Flowspace definiert im Kern eine Gruppe auf einen bestimmten Wert gesetzter Header-Felder. FlowVisor weist jedem Nutzer (respektive dessen Controller) Lese- und Schreibrechte auf ein oder mehrere Flowspaces zu. Das stellt beispielsweise sicher, dass der Controller von Nutzer A nur Flow-Einträge für Pakete mit einer VLAN-ID von 201 installieren darf, während Nutzer B nur das Forwarding von HTTP-Paketen für alle übrigen VLAN IDs beeinflussen kann und Nutzer C zu Monitoringzwecken lediglich die Zählerstände für alle installierten Flow-Einträge abfragen darf.

FlowVisor liegt als transparente Schicht zwischen Switches und Controllern. Jeder von diesen verbindet sich zunächst mit der FlowVisor-Instanz, sodass sie alle Protokollnachrichten kontrolliert. Durch Umschreiben der Protokollnachrichten täuscht FlowVisor eine Punkt-zu-Punkt-Verbindung zwischen jedem Controller-/Datenpfad-Paar vor. Eine logische FlowVisor-Instanz kann man auch verteilt, zum Beispiel als Baumstruktur, umsetzen, da jeder FlowVisor nach außen hin als Switch beziehungsweise Controller fungiert. Dadurch kann jede Instanz Protokollnachrichten je nach Slice-Einstellung entweder an direkt angeschlossene Switches respektive Controller oder an eine weitere FlowVisor-Instanz weiterreichen.

Auch wenn man die Entwicklung von OpenFlow isoliert als eigenständige neue Technik betrachten kann, sieht die Forschungs-Community den Ansatz als Beispiel für ein neues Netzwerkparadigma: SDN (Software-Defined Networking). Dessen Hauptmerkmal ist die Programmierung der Kontrolllogik von Netzressourcen über eine zentrale, von der Hardware entkoppelte Instanz. Dabei verfügt der Controller über eine globale Sicht der angeschlossenen Datenpfade nebst dazugehöriger Topologie. Die Netzhardware wandelt sich im Wesentlichen zu einer Sammlung einfacher, generisch programmierbarer Forwarding-Elemente, die man nach Bedarf dem Netz hinzufügen oder sie daraus entfernen kann. Das vereinfacht die Entwicklung und Inbetriebnahme neuer Netzanwendungen erheblich – vor allem im Vergleich zu den heute genutzten dezentralen Algorithmen und proprietären Hardwareschnittstellen.

Mehr Infos

iX-TRACT

  • OpenFlow erlaubt die plattformübergreifende Programmierung von Netzwerkgeräten über eine offene Schnittstelle.
  • Durch die Entkopplung der Kontroll- und Forwarding-Pfade erlaubt OpenFlow eine einfache Programmierung der Netzwerklogik mithilfe von Controller Frameworks.
  • Software-Defined Networking ist ein neues Paradigma, das auf eine zentralisierte Ansteuerung von Netzwerkelementen baut und somit eine Abstraktionsebene für die Entwicklung neuer Netzdienste schafft.

So entfallen zum einen lange Entwicklungszyklen der Hardware und somit – zumindest teilweise – Abhängigkeiten von den Geräteherstellern, da eine neue Netzanwendung für den Einzug in eine Produktreihe nicht mehr eine kritische Nutzermasse erreichen muss. Zum anderen lassen sich viele Netzprobleme grundsätzlich besser oder stabiler mithilfe zentralisierter Algorithmen lösen. Zum Beispiel kann man den Netzverkehr mit Dijkstras Algorithmus über die kürzesten Pfade leiten. Im Gegensatz zum Spanning-Tree-Algorithmus entstehen so keine Engpässe, und der Algorithmus konvergiert nach Änderungen im Netz stets zu einer optimalen Lösung.

Insgesamt dürfte die künftige Entwicklung von Netzen durch den Einsatz von SDN und der damit einhergehenden Entkopplung von der physischen Netzwerkschicht ähnlich profitieren wie die Softwareentwicklung in den letzten Jahrzehnten vom zunehmenden Abstraktionsgrad moderner Programmiersprachen.

Mit seiner vergleichsweise simplen Architektur bildet OpenFlow eine extrem flexible und elegante Basis für programmierbare Netze. Auch wenn sich Beispiele finden lassen, für die OpenFlow in seiner jetzigen Form nicht das Mittel der Wahl sein mag, zeichnet sich ab, dass es besonders in Rechenzentren Optionen eröffnet, verteilte Anwendungen auf der Netzebene zu unterstützen. Dabei besteht OpenFlows wahre Neuerung nicht unbedingt in der Architektur – ähnliche Ansätze gab es schon früher – sondern darin, dass es die Entwickler geschafft haben, namhafte Hardwarehersteller nicht nur vom Konzept zu überzeugen, sondern sie auch zu bewegen, passende Produkte auf den Markt zu bringen.

Besonders im Hinblick darauf, dass es bei OpenFlow um den Zugriff auf das Innenleben von Netzkomponenten geht, ist die Einigung auf eine offene Spezifikation zwischen mehreren Herstellern bemerkenswert. Spätestens seit der Gründung der Open Networking Foundation (ONF, [d]) Ende 2011, die die Förderung von OpenFlow/SDN als Ziel hat und zu deren Mitgliedern Größen wie Google, Facebook oder Deutsche Telekom zählen, ist offensichtlich, dass in der Industrie ein großer Bedarf für einen herstellerunabhängigen Ansatz zur Programmierung von Netzen besteht.

arbeitet am Institut für Kommunikationstechnik der Leibniz Universität Hannover. Zu seinen Forschungsgebieten gehören die Virtualisierung und Leistungsbewertung von Netzen.

Alle Links: www.ix.de/ix1208112 (avr)