BLOG

Kontrollebene für verteiltes Kubernetes PaaS

Ankur Singla Miniaturansicht
Ankur Singla
Veröffentlicht am 15. November 2019

Dieser Blog ist der erste in einer Blog-Reihe, die verschiedene Aspekte dessen behandelt, was für den Aufbau und Betrieb unseres SaaS- Dienstes erforderlich war:

  1. Kontrollebene für verteiltes Kubernetes PaaS
  2. Globales Service Mesh für verteilte Anwendungen
  3. Plattformsicherheit für verteilte Infrastrukturen, Apps und Daten
  4. Anwendungs- und Netzwerksicherheit verteilter Cluster
  5. Beobachtbarkeit über eine global verteilte Plattform
  6. Betrieb und SRE einer global verteilten Plattform
  7. Golang-Service-Framework für verteilte Microservices

Wie wir in unserem früheren Blog beschrieben haben, entwickeln unsere Kunden komplexe und vielfältige Geschäftslösungen – etwa intelligente Fertigung, Videoforensik für die öffentliche Sicherheit, algorithmischen Handel, 5G-Telekommunikationsnetze – und daher müssen wir für diese Anwendungen und ihre Endbenutzer eine stets verfügbare, vernetzte und zuverlässige Erfahrung bereitstellen.

Da diese Anwendungen in mehreren Clustern bei verschiedenen Cloud-Anbietern oder an den Randstandorten der Kunden ausgeführt werden könnten, musste unser Plattformteam eine verteilte Steuerungsebene und einen PaaS-Dienst erstellen, um mehrere Kubernetes-Cluster mit mehreren Mandanten bereitzustellen, zu sichern und zu betreiben. Diese verteilte Steuerebene hat viele Betriebs-, Skalierungs- und Leistungsvorteile gebracht, die wir in unserer Präsentation ( Videolink ) behandeln werden – z. B. wie man Tausende von Edge-K8s-Clustern mit GitOps verwaltet – und in den kommenden Wochen auch in einem separaten Blog-Beitrag.

TL;DR (Zusammenfassung)

  • Wir konnten auf dem Markt keine einfach zu verwendende Lösung finden, die das Problem der Bereitstellung, Sicherung und des Betriebs mehrerer Anwendungscluster lösen könnte, die auf Cloud-Anbieter, private Clouds oder mehrere Edge-Standorte verteilt sind.
     
  • Wir konnten keine robuste Kubernetes-Distribution oder PaaS (z. B. OpenShift, Cloud Foundry usw.) finden, die einen umfassenden Satz an Sicherheits- und Betriebsdiensten bereitstellt, die für verteilte Cluster erforderlich sind – beispielsweise PKI-basierte Identität, RBAC und Benutzerzugriffsverwaltung, Geheimnis- und Schlüsselverwaltung über Cloud-Anbieter hinweg, Multi-Cluster-Service-Mesh, Beobachtungs- und Prüfprotokolle oder Anwendungs- und Netzwerksicherheit.
     
  • Anthos (Google), Azure Arc (Microsoft) und Rancher sind Multi-Cluster-Verwaltungsstationen und Pakete für mehrere unterschiedliche Dienste. Unserer Analyse zufolge hätten diese unsere Anforderungen an Betrieb, Skalierung, Sicherheit und Mandantenfähigkeit für Anwendungs- und Infrastrukturdienste über mehrere Cluster hinweg nicht erfüllen können.
     
  • Wir mussten für unser verwaltetes PaaS, das auf Kubernetes aufbaut, unsere eigene verteilte Kontrollebene erstellen. Wir haben mit Vanilla Kubernetes begonnen und dann wesentliche Änderungen vorgenommen, um die von unseren DevOps- und SRE-Teams benötigten Plattformdienste bereitzustellen. Darüber hinaus mussten wir eine Steuerebene erstellen, um eine große Anzahl verteilter Cluster zu verwalten und Multi-Tenancy über eine heterogene Infrastruktur (am Rand, in unserem Netzwerk und bei mehreren Cloud-Anbietern) bereitzustellen.

Kubernetes für App-Management: Warum und wie

Wir haben uns für Kubernetes (K8s) als Kern unserer Plattform zur Verwaltung verteilter Anwendungen entschieden, da es einen umfangreichen Funktionsumfang bietet, ohne zu normativ zu sein. Dies gibt uns die Flexibilität, bei Dingen Innovationen einzuführen, die unserer Ansicht nach für unsere Kunden wichtig sind. Wir haben dies als Grundlage für den Aufbau unseres Dienstes verwendet und mit der wachsenden Popularität von K8s ist es auch einfacher, Entwickler und Betreiber zu finden, die damit vertraut sind.

Allerdings ist die Bereitstellung und Verwaltung einer großen Anzahl produktionsreifer Kubernetes-Cluster in einer Hybridumgebung (mehrere Clouds, Netzwerk-POPs und Edge-Standorte) nicht sehr einfach, da es keine sofort einsatzbereiten Lösungen für Kubernetes gibt, die Folgendes können:

  1. Harmonisierung heterogener Infrastrukturressourcen durch automatisiertes Clustering, Skalierung und Zero-Touch-Provisioning. Dies war besonders am Rand und in unseren Netzwerk-PoPs problematisch.
  2. Sorgen Sie für leistungsstarke und zuverlässige Konnektivität über unterschiedliche Standorte hinweg – insbesondere bei der Überquerung von Cloud-Anbietern und von Randstandorten aus
  3. Lösen Sie das Sicherheitsproblem von Daten während der Übertragung, Daten im Ruhezustand, Geheimnissen, Schlüsseln und Netzwerken … alles unterstützt durch eine einheitliche PKI-Identität, die über Edge, Netzwerk und Cloud hinweg funktioniert.
  4. Bieten Sie echte Mandantenfähigkeit – Mandantenisolierung und Sicherheitsgarantien – mit der Möglichkeit, Produktions- und Entwicklungs-Workloads für interne und Kundenanforderungen auf denselben Clustern auszuführen.
  5. Sorgen Sie für Beobachtung und Betrieb über verteilte Cluster hinweg, die an zentralisierte Richtlinien und Absichten angebunden sind, ohne dass komplexe Protokolle und Metriksammlungen erstellt werden müssen.

Nach mehreren Proof-of-Concept mit mehreren Cloud-Anbietern und Open-Source-Plattformen wie GKE, AKS, EKS und RKE sowie OpenShift und Cloud Foundry stellten wir fest, dass keiner von ihnen alle fünf oben genannten Anforderungen erfüllen konnte. Aus diesem Grund haben wir uns entschieden, unsere eigene PaaS zu entwickeln – angefangen mit „Standard“-Kubernetes und mehreren Ergänzungen – für Identität, Netzwerke, Sicherheit, Mandantenfähigkeit, Protokollierung, Metriken usw. Obwohl wir Kubernetes zur Erfüllung unserer internen Anforderungen verwenden, mussten wir einige schwierige Entscheidungen treffen, z. B. diese Kubernetes-Cluster nicht direkt unseren internen Benutzern und/oder Kunden zur Verfügung zu stellen, damit diese ihre Workloads ausführen können (mehr dazu später, da Multi-Tenancy ein wichtiges Ziel für uns war).

Zusätzlich zu den zahlreichen neuen Funktionen, die wir hinzufügen mussten, bestand auch die Notwendigkeit, unsere Workloads/Dienste parallel zu den Workloads der Kunden an vielen Standorten am Edge, in unserem Netzwerk und in öffentlichen/privaten Clouds auszuführen. Dies bedeutete, dass wir zusätzliche Funktionen zum Verwalten mehrerer Cluster in mehreren Umgebungen entwickeln mussten … alle verbunden über unser globales Netzwerk und unsere verteilten Anwendungs-Gateways, um Zero-Trust-Konnektivität und Konnektivität auf Anwendungsebene zwischen diesen Clustern bereitzustellen.

Der schwierige Teil: Multi-Tenancy und Multi-Cluster für Kubernetes

Das Erstellen und Betreiben von Anwendungen, die in einem einzelnen Kubernetes-Cluster ausgeführt werden, ist keine triviale Aufgabe, selbst wenn ein vom Cloud-Anbieter verwalteter Cluster verwendet wird. Aus diesem Grund minimieren DevOps- und SRE-Teams häufig ihren Aufwand und müssen sich nicht mit der Komplexität vieler Cluster befassen. Es kommt häufig vor, dass Teams einen großen Kubernetes-Cluster erstellen und alle Arten von Ressourcen im selben Cluster platzieren. Dies erscheint zwar großartig, da dadurch die Abläufe vereinfacht und der Cluster mit maximaler Rechenleistung und zu maximalen Kosten betrieben werden kann, es ist jedoch aus mehreren Gründen nicht die beste Idee. Erstens unterscheiden sich die Anforderungen an Produktions-Workloads stark von denen für Entwicklungstests und Staging. Instabile Entwicklungs-Workloads können möglicherweise Probleme für stabilere Produktions-Workloads verursachen.

Neben den Anforderungen unterschiedlicher Workloads sind die Sicherheits- und Isolationsbeschränkungen von K8 ein weiterer Grund für die Verwendung mehrerer Cluster. Ein typischer Ansatz zur Lösung der Sicherheits- und Ressourcenisolierungsprobleme von K8 besteht darin, mithilfe eines Multi-Tenant-Modells unabhängige Cluster für jeden Mandanten zu erstellen. Während dies in der Cloud möglicherweise möglich ist, ist es am Rand nicht möglich, mehrere Cluster auszuführen. Edge-Sites unterliegen Einschränkungen bei Rechen- und Speicherressourcen sowie einer eingeschränkten Netzwerkbandbreite, um Protokolle und Messdaten für jeden zusätzlichen Cluster an die zentrale Cloud zu senden.

Um das Problem mehrerer Kubernetes-Cluster zu lösen, haben wir Rancher für die zentrale Verwaltung unserer Kubernetes-Cluster (als wir begannen, gab es Anthos und Azure Arc noch nicht) und KubeFed evaluiert. Die beiden damals verfügbaren Ansätze waren (und sind auch heute noch die gleichen):

  1. Die Verwaltung mehrerer Cluster (z. B. Rancher) über eine zentrale Konsole hätte uns die Möglichkeit gegeben, mehrere Cluster an jedem Standort einzusetzen und Lebenszyklusverwaltungsvorgänge wie Upgrades, Rollbacks usw. durchzuführen. Einige dieser Systeme ermöglichten auch die Automatisierung der Konfiguration und Bereitstellung von Anwendungen für einzelne Cluster.
     
  2. Ein anderer Ansatz besteht darin, eine Kubernetes Cluster Federation (KubeFed)-Steuerungsebene einzusetzen, mit der mehrere physische Cluster wie ein einziger Cluster aussehen können. Dieses Projekt stand zum Zeitpunkt unserer Recherche noch ganz am Anfang und befindet sich heute erst im Alpha-Stadium.

Nach der kürzlichen Ankündigung von GCP Anthos und Azure Arc haben wir unsere ursprüngliche Entscheidung zum Aufbau einer verteilten Steuerungsebene überdacht und sind zu dem Schluss gekommen, dass selbst diese beiden neuen Angebote zwei kritische Probleme mit verteilten Clustern nicht hätten lösen können. Diese beiden Schlüsselfunktionen benötigten wir für unsere Plattform:

  1. Verwalten mehrerer Cluster als Flotte, um das Problem der Durchführung von Vorgängen in allen oder einer logischen Gruppe von Clustern zu lösen – Vorgänge wie Konfiguration, Bereitstellung, Metriken usw. Dies ist von entscheidender Bedeutung, da wir den Betriebsaufwand für unsere SRE-Teams reduzieren, die Debug-Fähigkeit für unsere DevOps verbessern und die Skalierbarkeit unseres Systems steigern möchten.
     
  2. Möglichkeit, einen einzelnen physischen Kubernetes-Cluster für Multi-Tenancy aufzuteilen, ohne physische Cluster hochfahren zu müssen – dies ist insbesondere in ressourcenbeschränkten Umgebungen wichtig, in denen wir keine neuen physischen Cluster nur für Multi-Tenancy hinzufügen möchten.

Zur Lösung dieser beiden Probleme mussten wir eine neue Technik entwickeln – eine verteilte Steuerungsebene –, um den Betriebsaufwand „mehrerer“ Cluster zu verringern und ein Äquivalent „mehrerer Cluster“ für Multi-Tenancy in Umgebungen mit eingeschränkten Ressourcen bereitzustellen.

Verteilte Kontrollebene: So haben wir Multi-Cluster-Kubernetes erreicht

Unser Plattformteam hat beschlossen, eine verteilte Steuerungsebene für Kubernetes zu erstellen, die Kubernetes-APIs für die Verwendung durch unser Team bereitstellt. Diese APIs stammen jedoch aus „virtuellen“ Clustern, die nur in unserer Steuerungsebene vorhanden sind – einem virtuellen K8s (vK8s)-API-Server für einen virtuellen K8s-Cluster (siehe Abbildung 1 ). Diese Steuerebene ordnet die Absicht des Benutzers mehreren physischen Kubernetes-Clustern zu, die an unserem Edge, unseren Netzwerk-POPs und an öffentlichen Cloud-Standorten ausgeführt werden. Auf diese physischen Cluster kann nur über unsere verteilte Steuerungsebene zugegriffen werden, nicht jedoch über einzelne Mieter/Benutzer.

Steuerebene-01
Abbildung 1: Verteilte Kontrollebene

Diese Steuerebene stellt jedem Mieter einen oder mehrere „virtuelle“ Anwendungscluster zur Verfügung, in denen er seine Anwendung(en) bereitstellen kann. Je nach Konfiguration repliziert und verwaltet die Steuerebene diese über mehrere physische Kubernetes-Cluster hinweg. Zusätzlich zu den Konfigurations- und Bereitstellungsvorgängen werden diesem „virtuellen“ Cluster auch Überwachungsvorgänge unterzogen, ohne dass Tools zum Sammeln und Analysieren von Daten aus mehreren physischen Clustern entwickelt werden müssen.

Nehmen wir als Beispiel eine UI-Anwendung namens „productpage“, die der Benutzer verteilt an drei Standorten ausführen möchte – pa2-par, ny8-nyc und ams9-ams mit jeweils zwei Replikaten. Wenn der Benutzer ein vK8s-Objekt erstellt und es an einen virtuellen Cluster anfügt, wird sofort ein vK8s-API-Server bereitgestellt, der mit Standard-Kubectl verwendet werden kann.

Als nächsten Schritt lädt der Benutzer die Kubeconfig für diesen virtuellen Cluster herunter und erstellt ein Standard-YAML, um eine K8s-Bereitstellung für die Produktseite zu beschreiben.

Nach der Erstellung der Bereitstellungsspezifikation kann der Benutzer mit der Erstellung einer Bereitstellung auf diesem virtuellen Cluster fortfahren:

Wenn der Benutzer jetzt seine Bereitstellung überprüft, sieht er, dass 6 Replikate gestartet wurden, davon 2 an jedem Standort (pa2-par, ny8-nyc und ams9-ams).

Die folgende Ausgabe zeigt 2 Pods, die an jedem Standort ausgeführt werden und einem bestimmten physischen Knoten zugeordnet sind

Dieses einfache Beispiel zeigt, wie einfach es ist, innerhalb von Minuten eine Multi-Cluster-Replikation beliebiger Apps zu erreichen, ohne dass ein Installations- und Verwaltungsaufwand erforderlich ist. Neben der Abbildung der Absicht ermöglicht die verteilte Steuerungsebene auch die Beobachtung des virtuellen Clusters und nicht nur auf der Basis einzelner Cluster.

Verteilte Kontrolle und zentrale Verwaltung für Multi-Tenancy

Wie Sie in Abbildung 2 sehen können, läuft unsere zentralisierte Verwaltungsebene über zwei öffentliche Cloud-Anbieter (jeweils eine Region) – einen in AWS und einen in Azure (aus Redundanzgründen). Diese Verwaltungsebene ermöglicht unserem SRE, Mandanten mit harter Multi-Tenancy zu erstellen – beispielsweise kann ein Entwicklungsteam, das an unserem VoltMesh-Dienst arbeitet, ein Mandant sein, und ein Kundenlösungsteam, das an Kunden-POCs arbeitet, kann ein eigener Mandant mit einem eigenen Benutzersatz sein.

Abbildung 2: Mandantenfähigkeit und Multi-Cluster

Jeder dieser Mandanten kann mehrere Namespaces erstellen und einer Gruppe von Benutzern die Zusammenarbeit an diesen Namespaces zuweisen. Diese Namespaces sind keine Kubernetes-Namespaces – sie stellen eine Isolationsgrenze in unserer Plattform mit RBAC-Regeln und IAM-Richtlinien für Benutzer dar.

Wenn ein Benutzer innerhalb eines Namespace einen Anwendungscluster erstellen möchte, erstellt er ein vK8s-Objekt und das wiederum erstellt einen vK8s-API-Server in unserer Verwaltungsebene. Mit diesem vK8s-Objekt kann der Benutzer Bereitstellungen, Stateful Sets, PVCs usw. erstellen und die Steuerebene stellt sicher, dass diese Vorgänge auf einem oder mehreren physischen Clustern erfolgen, basierend auf Sites, die mit dem vK8s-Objekt verknüpft sind.

Da jeder Mieter und Benutzer standardmäßige K8s-Operationen ohne jegliche Änderungen verwendet, ist das System mit einer Reihe von Tools kompatibel, die bei Betreibern beliebt sind – z. B. Spinnaker, Helm, Jenkins usw.

Vorteile einer verteilten Steuerungsebene

Der große Vorteil einer verteilten Steuerungsebene besteht darin, dass sie den Betriebsaufwand für unsere SRE- und DevOps-Teams gelöst hat. Sie können jetzt Vorgänge (Konfiguration, Bereitstellung, Überwachung, Richtlinien usw.) über einen virtuellen Cluster ausführen und die Steuerebene ordnet diese automatisch mehreren physischen Clustern zu. Neben der betrieblichen Vereinfachung für mehrere Cluster hat die Steuerebene auch das Sicherheits- und Isolationsproblem für Multi-Tenancy gelöst.

Diese verteilte Steuerungsebene hat auch die Produktivität der Entwickler verbessert, die unserer Plattform neue Funktionen hinzufügen möchten – sie müssen nicht jedes Mal eine neue Automatisierung erstellen, wenn sie neue Funktionen hinzufügen, die sich auf die Konfiguration oder den Betrieb über mehrere Cluster hinweg auswirken. Sie verwenden das absichtsbasierte Konfigurationsmodell und die Steuerebene weiß, was zu tun ist. Darüber hinaus können sie weiterhin mit diesem verteilten und mehrfachen Clusterobjekt – virtuellen Kubernetes – interagieren, indem sie kubectl verwenden und nicht noch eine weitere CLI.

Nachdem wir dies nun über ein Jahr lang in unseren Entwicklungs-, Test-, Staging- und Produktionsumgebungen ausgeführt haben, wurde uns klar, dass diese global verteilte Steuerungsebene (die in unseren Netzwerk-POPs ausgeführt wird) auch erhebliche Vorteile hinsichtlich Skalierung, Leistung und Zuverlässigkeit bietet – etwas, das wir uns in der Anfangszeit nicht wirklich vorstellen konnten. Wir werden dieses Ergebnis in unserer kommenden KubeCon-Präsentation und in den kommenden Wochen in einem separaten Blogbeitrag behandeln.

Fortgesetzt werden…

In dieser Blogserie werden verschiedene Aspekte dessen behandelt, was für den Aufbau und Betrieb unseres weltweit verteilten SaaS-Dienstes mit vielen Anwendungsclustern in der öffentlichen Cloud, unseren privaten Netzwerk-PoPs und Edge-Sites erforderlich war. Als nächstes kommt Global Service Mesh für verteilte Apps