In der neuen Cloud-Native-Welt müssen Betriebswerkzeuge für DevOps-Teams eine hohe Produktivität und einen schnellen Ablauf bis zur Produktion ermöglichen. Architekturen bestehen oft aus Dutzenden von Microservices, die schnell in der Cloud bereitgestellt und betrieben werden müssen. Das bedeutet einen erheblichen zusätzlichen Verwaltungsaufwand für Entwickler und separate Operations-Teams skalieren nicht ausreichend, um alle Services eines Projekts zu unterstützen. Ohne gute Werkzeuge, die den Großteil der täglichen Betriebsaufgaben von den Entwicklern fernhalten und automatisieren, kann keine große Plattform auf Dauer gewartet werden. Automatisierung ist der Schlüssel!
Die Cloud Native Computing Foundation (CNCF) definiert Cloud Native offiziell wie folgt:
Cloud-native Technologien befähigen Organisationen dazu, skalierbare Anwendungen in modernen, dynamischen Umgebungen wie öffentlichen, privaten und hybriden Clouds zu bauen und zu betreiben. Container, Service Meshes, Microservices, unveränderliche Infrastruktur und deklarative APIs sind typische Beispiele für diesen Ansatz. (Quelle).
Cloud-Native-Technologien erfordern Cloud-Native-Dev-Tools. Diese bieten Lösungen, um Cloud-Native-Anwendungen auf Container-Plattformen auszuführen und den Betrieb so weit wie möglich zu automatisieren. Werkzeuge werden für den gesamten Entwicklungsablauf einer Cloud-Native-Anwendung benötigt: von der Entwicklung der Container über deren Deployment bis hin zur Beobachtbarkeit (Observability) und Sicherheit der Anwendung selbst.
DevOps Entwicklungsflow
Schauen wir uns einige Beispiele an, wie Dev-Tools die verschiedenen Schritte im Entwicklungsablauf unterstützen können:
Build (Bauen):
Deploy (Bereitstellen):
Operate (Betreiben):
Was ist das richtige Werkzeug zur Entwicklung von Cloud-Native-Dev-Tools? Im Laufe der Jahre hat sich Go als die Hauptsprache hinter dem Cloud-Native-Stack etabliert. Docker, Kubernetes, Kubectl und viele andere bekannte Tools sowie Infrastrukturkomponenten sind alle in Go implementiert.
Beispiele für Cloud-native Tools geschrieben in Go
Go ist eine Open-Source-Sprache, die von Google gepflegt wird. Die Sprache bietet folgende wesentliche Vorteile:
Die Wahl von Go ermöglicht es uns, an der lebendigen Cloud-Native-Community teilzuhaben und die SDKs zu nutzen, die den Cloud-Native-Stack antreiben, um unsere eigenen Dev-Tools zu schreiben.
Für die betterCode im Jahr 2021 haben wir (M.-Leander Reimer and Markus Zimmermann) einen Workshop mit dem Titel „Go for Operations“ erstellt. Dieser führte Softwareentwickler-Kollegen in das Thema Cloud-Native-Dev-Tooling mit Go ein.
Der Workshop zeigte, dass jeder unterschiedliche DevOps-Erfahrungen aus seinem Berufsalltag mitbrachte, von strengen Compliance-Anforderungen bis hin zur Fähigkeit, schnell Prototypen für die eigene Infrastruktur zu bauen. Auch der Wissensstand bezüglich Go war gemischt und reichte von Anfängern bis zu fortgeschrittenen Benutzern. Durch praktische Übungen haben wir verschiedene Konzepte der Betriebsautomatisierung vorgestellt und gezeigt, wie man diese mit Go umsetzt. Am Ende konnte jeder etwas mit nach Hause nehmen, das er in seiner täglichen Betriebsarbeit anwenden wollte.
Die Inhalte des Workshops sind Open Source und die Übungsbeschreibungen als Schritt-für-Schritt-Anleitungen verfasst, sodass jeder die Übungen selbst ausprobieren kann. Besuchen Sie einfach unser GitHub-Repository, um den Workshop durchzuarbeiten!
Lassen Sie uns kurz einige der Automatisierungskonzepte durchgehen, die Teil des Workshops waren, um zu erfahren, welche Bibliotheken/Frameworks die Treiber für die Umsetzung dieser Konzepte in Go sind.
Command-Line-Interfaces (CLIs) sind Werkzeuge, mit denen jeder Entwickler gewohnt ist zu arbeiten. Sie sind schneller zu bedienen als grafische Oberflächen und können leicht automatisiert werden, indem man sie in Continuous-Integration-Pipelines aufruft. kubectl ist ein Beispiel für eine gute CLI und wird zur Verwaltung von Kubernetes-Clustern verwendet. Es ist in Go geschrieben und seine Implementierung kann als Blaupause für CLI-Anwendungen dienen. Es nutzt die beliebten CLI-Bibliotheken Cobra und Viper welche die Haupttreiber für Go-CLI-Anwendungen sind. Mit diesen Bibliotheken können Sie schnell eine CLI schreiben und erhalten viele Features wie Autovervollständigung, Hilfe-Generierung und Konfigurationsverwaltung als Bonus dazu.
Sie können Challenge 1 unseres Workshops absolvieren, um zu lernen, wie man Cobra/Viper zum Schreiben von CLIs verwendet.
Das Ergebnis der Challenge ist ein funktionierendes kubectl Plugin, das Chaos in unserem Cluster erzeugt, um die Resilienz unserer bereitgestellten Services zu testen. Kubectl Plugins lassen sich einfach integrieren, da die installierte Binärdatei lediglich das Präfix kubectl- haben muss. Die einzige Einschränkung ist, dass Plugins keinen bereits existierenden kubectl-Befehl überschreiben können. Sie können beispielsweise kein Plugin mit dem Namen kubectl-create erstellen, da es mit dem bestehenden kubectl Befehl create kollidieren würde.
Sidecars sind eine einfache Möglichkeit, einen bereitgestellten Service in Kubernetes zu erweitern. Es handelt sich um einen Container, der an der Seite Ihrer Anwendung innerhalb desselben Pods läuft. Der Sidecar teilt sich Speichervolumen, Netzwerke und andere Ressourcen mit dem Anwendungscontainer. Dadurch kann er verwendet werden, um Datenverkehr abzufangen, Dateien mit der Anwendung zu teilen oder Monitoring einzubinden.
Ein solcher Sidecar-Container lässt sich problemlos mit reinem Go implementieren. Da es sich um eine eigenständige Binärdatei handelt, wird der Container relativ klein ausfallen.
Beispiel für einen Sidecar für Log-Shipping
Schauen Sie sich die Challenge 2 des Workshops an, in der Sie einen Log-Shipping-Container bauen. Dieser erweitert jede Anwendung, die Logs nur auf die Festplatte schreibt, um diese Logs über das Standard-Kubernetes-Log-Handling an einen beliebigen Logging-Anbieter zu senden.
Wie bereits erwähnt, helfen uns Kubernetes-Operatoren bei Wartungsaufgaben, die in laufenden Kubernetes-Deployments automatisiert werden müssen. Operatoren können benutzerdefinierte Ressourcen (Custom Resources) definieren und deren Zustand verwalten. Dies wird durch die Custom Resource Definition-Erweiterung von Kubernetes ermöglicht. Ein Vorteil von Custom Resources in Kubernetes ist, dass sie auf dieselbe Weise wie Ihre anderen Kubernetes-Ressourcen verwaltet werden können. Operatoren besitzen eine Schleife (Working Loop), die Änderungen an ihren Custom Resources überwacht und darauf reagiert, indem sie Aktionen innerhalb von Kubernetes auf den von ihnen verwalteten Ressourcen ausführt.
Kubernetes-Operatoren erklärt
Ein beliebtes Framework zum Schreiben von Operatoren ist das Operator SDK. Es bietet Scaffolding (Code-Generierung), erzeugt also allen benötigten Code und ermöglicht es Ihnen, Ihren Operator schnell zu schreiben und direkt auf einem Cluster bereitzustellen.
Werfen Sie einen Blick auf unsere Challenge 3 des Workshops: Hier bauen Sie mit dem Operator SDK einen Microservice-Operator, der die Kubernetes-Ressourcen abstrahiert, die für das Deployment eines Microservices auf Kubernetes erforderlich sind. Mit diesem Operator müssen Sie nur noch eine einzige Ressource definieren, um einen Microservice bereitzustellen, anstatt alle benötigten Kubernetes-Ressourcen wie das Deployment und den Service einzeln definieren zu müssen.
Dieser Artikel sollte Ihnen eine Einführung in Cloud-Native-Dev-Tools geben und zeigen, wie Sie Ihre eigenen Werkzeuge in Go, der Hauptsprache des Cloud-Native-Stacks, implementieren können. Mit den Workshop-Übungen können Sie praktische Erfahrungen sammeln und selbst Dev-Tools umsetzen. Vielleicht helfen sie Ihnen bei der Arbeit dabei, lästige Alltagsaufgaben zu automatisieren, um Raum für wichtigere Aufgaben zu schaffen. Wir werden versuchen, den Workshop weiterhin auf anderen Konferenzen anzubieten, um noch mehr Entwicklern Erfahrung mit Go zur Erstellung von Cloud-Native-Dev-Tools zu vermitteln und uns über Erfahrungen mit dem Cloud-Native-Stack auszutauschen.