Erhebung und Auswertung der Verbrauchsdaten einer VMWare Cloud-Plattform

Für einen schweizer Cloud Provider entwickelte ich eine Plattform zur Sammlung und Auswertung von Verbrauchsdaten seiner eigenen Cloud-Umgebung. Das Ziel: Den Endkunden nach effektiven Verbrauch abrechnen und dabei maximale Transparenz schaffen.
Problemstellung
Die Verrechnung der eigenen Cloud-Plattform konnte mit Bordmittel von VMWare nicht marktgerecht gelöst werden. Die vom Kunden eingesetzte Eigenentwicklung war nicht in der Lage, mit der steigenden Anzahl an virtuellen Maschinen umzugehen und in unterschiedlichen Netzwerk-Zonen eingesetzt zu werden.
Lösung
Eine vielschichtige Umgebung, unterschiedliche und komplexe APIs und den Anspruch, eine genaue, zeitnahe und überprüfbare Erhebung der Verbrauchsdaten von tausenden von virtuellen Maschinen zu erstellen. Kurzum: Für die Umsetzung war ein ganzheitlicher, kreativer Ansatz gefragt.
Durch den Aufbau einer event-basierten Microservice-Architektur, leichtgewichtige und zustandslose Microservices, APIs, UI, einem Postgres-Cluster und diversen Infrastruktur-Services, konnte ich eine performante, nachhaltige, sichere und skalierbare Plattform zur Erhebung und Rapportierung von Verbrauchswerten aus den Umsystemen von VMWare umsetzen.
Die Lösung ermöglichte es dem Kunden, seinen Endkunden eine verbrauchsorienterte und transparente Verrechnung seiner Cloud-Plattform anzubieten.
Umsetzung
Die dezentrale Architektur der Cloud-Umgebung in mehrere Datacenter mit diversen Sicherheitszonen sowie der Anforderungen, alle VMs zeitnah scannen und zukünftig wachsen zu können, machte eine skalierbare Lösung mit verteilten Systemen notwendig.
Ich entschied mich für eine Microservice-Architektur: Die Microservices sollten dabei leichtgewichtig, zustandslos, portabel und horizontal skalierbar sein (12-Faktor-App) und mittels eines Message-Brokers und Events asynchron miteinander kommunizieren. Der Code wird dabei vollautomatisiert mittels CI/CD-Pipeline getestet, in Container paketiert und in einer Container Registry bereitgestellt.
Orchestriert und ausgeführt wird das Ganze in einem Kubernetes-Cluster des Kunden, welcher parallel für dieses Projekt durchs Cloud-Team in Betrieb genommen wurde. Dabei begnügten wir uns vorerst mit einer Availability-Zone in einem Datacenter. Die Lösung wurde aber bereits mit Geo-Redundanz geplant und wo möglich aufgebaut.
Übersicht der Gesamt-Architektur
Die Rohdaten zu einer VM lagen verteilt in mehreren REST-
und SOAP-APIs
von VMWare vor. Diese galt es anzubinden, die korrekten Werte auszulesen, zu normalisieren, als Snapshot zu speichern, nach Tag/Monat/Jahr zu aggregieren, Reports im JSON-
und XLS-Format
zu generieren und über eine REST-API
den Umsystemen bereitzustellen.
Übersicht der einzelnen Software-Komponenten und des Message-Flows
Die fertige Lösung bestand aus folgenden Komponenten:
- Ein
Inventory Worker
(pro Zone), welcher die zu scannenden VMs über einen automatisierten Kubernetes-Task von einer API abruft und für jede gefundene VM einen "collect"-Event an den Message-Broker sendet. - Mehrere
Collect Worker
, welche auf diese "collect"-Events reagieren, die Verbrauchsdaten zu einer VM über die VMWare APIs abfragen und als "snapshot"-Event weiterschicken. - Ein
Snapshot Worker
, welcher die erhaltenen Daten prüft, aufbereitet, normalisiert und in einem Postgres-Cluster speichert. - Mehrere
Report Worker
, welche die Snapshots in entsprechende Reports aggregieren. - Ein
Cleanup Worker
, welcher bereits verdichtete Snapshots nach definiertem Intervall löscht. - Eine
REST-API
, welche Snapshots und Reports im JSON- und XLS-Format den Umsystemen bereitstellt. - Ein
Management UI
, welches die REST-API konsumiert und die Daten in einer intuitiven UI mit diversen Filtermöglichkeiten bereitstellt. - Diverse
CLI-Tools
, welche für Wartungsaufgaben genutzt werden.
Da zum Zeitpunkt der Umsetzung noch keine zentrale Log-Lösung zur Verfügung stand und keine Daten nach Aussen gelangen durften, habe ich das Logging ebenfalls über den Message-Broker abgehandelt. Etwaige Fehlermeldungen werden per Event verschickt, durch mehrere Log Worker
aufgefangen und zentralisiert gespeichert.
Für mehr Visibilität im Fehlerfall, habe ich weitere Metriken erhoben, über die REST-API zur Verfügung gestellt und mit einer eigenen Prometheus-Instanz abgerufen.
Logs und Metriken nutzte ich am Ende zur Visualisierung und Alarmierung mittels Grafana und ermöglichte eine zeitnahe und saubere Überwachung der kompletten Plattform.
Meine Arbeiten
- Analyse: Verstehen der Cloud-Plattform, der diversen Umsystem, APIs und existierenden Software.
- Konzeption: Erstellen eines Gesamt-Konzeptes.
- Proof of Concept: Prüfen der Machbarkeit mittels eines PoCs und lokalen Test-Instanzen.
- Beratung: Vertreten der Lösung gegenüber den Stakeholdern.
- Projektmanagement: Agile Entwicklung nach Scrum; Leiten von Scrum-Meetings mit dem internen Co-Worker.
- Coaching & Mentoring: Schulung des internen Co-Workers in SW-Architektur, -Konzepte und -Design-Patterns.
- Umsetzung: Entwicklung der event-basierten Microservice-Architektur, diverser Microservices, einer REST-API und UI, des Datenmodells und deren Relationen zueinander, dem Logging, dem Datastore und den diversen Infrastruktur-Services (API-GW, RabbitMQ, Prometheus, Grafana)
- Testing: Erstellung einer Vielzahl an Unit- & Functional-Tests.
- Deployment: Aufbau einer vollautomatisierten CI/CD-Pipeline; Deployment auf dem internen Kubernetes-Cluster als leichtgewichtige Container.
- Dokumentation: Festhalten der Architektur, des Programmablaufs jeder Software-Komponenten und der REST-API.
Tech-Stack
- REST-API:
- PSR-15 Middleware mittels Laminas\Mezzio und diverser PSR-kompatiblen Bibliotheken
- Hohe Code-Qualität dank Standards, OOP, Design-Patterns und Unit- & Functional-Tests
- Doctrine als Datenbankabstraktionslayer und ORM-Mapper
- Datenhandling- und -Normalisierung mittels Hydratoren, Input-Filtern & -Validatoren, Serialisierer
- Diverse REST-Handler mit Filterung und Paginierung im JSON+HAL Format
- Standartisierte und domainspezifische Exceptions
- Worker + CLI-Tools: Symfony/Console sowie Python mit VMWare SDKs
- UI: HTML5+CSS3 Layout mit Angular als Frontend-Framework
- Messaging: Pub/Sub-Pattern mittels RabbitMQ
- Datastore: Postgres Cluster (1x write, 3x read)
- Metriken: Prometheus
- Monitoring + Alerting: Diverse Dashboards und Alert-Rules mittels Grafana
- DevOps: Github Actions für CI/CD, IaC mittels Kubernetes YAML-Files + HELM, Container Registry mittels Dockerhub
- Deployment: Kubernetes/Rancher
- API Gateway: Ingress L7 + Nginx
Fazit
Ein herausforderndes Projekt, welches viel von mir abverlangte. Angefangen beim Projektmanagement, der Konzeption der Plattform und Software, der Schulung des Co-Workers bis hin zur Umsetzung. Neben den Software-Themen waren insb. die Cloud-Themen wie die Kubernetes-Plattform oder die Installation & Konfiguration der benötigten Infrastruktur-Services wie RabbitMQ, Prometheus und Grafana im Fokus.
Die harte Arbeit hat sich gelohnt: Dank zustandslosen Microservices und der asynchronen, internen Kommunikation mittels Events kann die Plattform horizontal skaliert werden. Der Scanvorgang von 1000 VMs kann innert 30 Sekunden mit 5 Collect-Workern abgeschlossen werden, und ist somit für die Zukunft gewappnet.
Auch die Ausbaufähigkeit hat sich bereits kurz nach Beendigung des Projektes gezeigt: Die Cloud-Plattform wurde um eine weitere Zone in einem neuen Datacenter ergänzt, woraufhin die Lösung in wenigen Minuten bereits fähig war die neuen VMs zu inventarisieren und zu scannen.