Kubernetes: Deployments unter Kontrolle

Wenn dein Produkt fertig ist, muss es auf einem Computer gestartet werden, der es übers Internet zur Verfügung stellt (Deployment bzw. Release). Früher war das ein Server, den man selbst aufsetzte und im eigenen Serverraum betrieb oder bei einem Provider mietete – heute kümmern sich grosse Firmen wie Google oder Amazon um die Hardware fürs Deployment und wir kontrollieren mit Tools wie Kubernetes, wie das Setup aussieht.

Docker: Überall dieselbe Umgebung dank Container.

Heute können auf jedem (Gross-)Rechner viele Installationen parallel laufen. Für die Abgrenzung sorgen Container. Container A und B laufen auf demselben Computer, wissen aber nichts voneinander und haben keine Möglichkeit, miteinander zu kommunizieren (ausser dies ist gewünscht). Dies nennt sich Virtualisierung.

Ein virtueller Container lässt sich mit einem Schiffscontainer vergleichen: Ein standardisierter Formfaktor (Docker) ermöglicht die Auslieferung (Deployment) komplett unterschiedlicher Inhalte (Applikationen) durch verschiedene Transportschiffe (Server-Hardware).

Die bekannteste Technik für Container-Virtualisierung ist Docker. Ein Docker-Container abstrahiert die Hardware, so dass die Umgebung für die Software im Container immer genau gleich aussieht – egal, ob der Container auf dem Computer der Entwicklerin oder im Rechenzentrum von Google ausgeführt wird. Das Resultat sind identische Zustände in unterschiedlichen Umgebungen und keine Bugs wegen abweichender Version einer Komponente im Betriebssystem.

Infrastruktur definiert, Deployments stabil

Im Container können Webserver wie nginx und Laufzeitumgebungen wie Node.js installiert werden. Solche Basis-Installation liegen als wiederverwendbare Images vor. Kubernetes ist für die Automatisierung dieses Setups, das Starten und Stoppen von Containern verantwortlich. Damit ist die Infrastruktur von A bis Z kontrollierbar und beinhaltet keine Unbekannten. Stabile Deployments sind garantiert – und Kubernetes bietet den Hebel, um laufende Anwendungen den Bedürfnissen entsprechend zuzuschalten.

Highlights:

  • Vollautomatisierte Releases: Entwickler*innen müssen beim Deployment keine Checkliste durchgehen – das eliminiert Fehlerquellen und ermöglicht kurze Releasezyklen.
  • Unterbrechungsfreier Betrieb: Änderungen und Bugfixes können ohne Wartungsfenster während des produktiven Betrieb aufgeschaltet werden – wenn der neue Container bereit ist, wird er aktiv geschaltet.
  • Vertikale Skalierbarkeit: Wenn mehr Last auf das System kommt, werden nach vorgängig festgelegten Regeln weitere Ressourcen zugeschaltet.
  • Self-Healing Mechanismen: Bemerkt das System ein Problem mit einer Komponente, wird diese kontrolliert neu gestartet. Christoph kann also endlich wieder durchschlafen.

Unsere Erfahrung

Wir haben Kubernetes schon bei mehreren Projekten eingesetzt, unter anderem:

Monitoring

Ein gutes Monitoring setzt Observability voraus, also Verfahren, um einen Einblick in den momentanen Zustand des Systems zu erhalten. Kubernetes hat dafür Mechanismen wie Readyness oder Liveness Probes. Diese bündeln die Daten und ermöglichen einen einheitlichen Zugriff.

Fürs Monitoring setzen wir auf Metrics Collection mit Prometheus und Log Collection mit FluentD. Die gesammelten Daten werden in einem Grafana- Dashboard visualisiert. Dazu gibt’s Alerts für alle gängigen Messaging-Systeme.

Und susch?

Jargon ist das Salz in der Techniksuppe. Ein kleiner Überblick. Und wenn du dann immer noch nicht genug hast, können wir auch unseren Blogpost über Kubernetes und Kuby empfehlen: How we simplified our Kubernetes deployments with an alternative to Helm

Die Cloud

Statt in den Serverraum nebenan zu deployen, lässt du Kubernetes und Google Cloud für dich arbeiten. «Die Cloud» ist in diesem Fall das Rechenzentrum von Google. Google Kubernetes Engine macht das Aufsetzen und Warten eines Kubernetes-Clusters in einem Schweizer Rechenzentrum zum Kinderspiel. Natürlich bieten auch andere grosse Cloud-Provider diese Dienstleistung an.

Continuous Integration & Continuous Delivery (CI/CD)

Bei jeder Code-Änderung stellt eine Test-Pipieline sicher, dass sich keine Fehler eingeschlichen haben. Die Pipeline fügt den Code zusammen und lässt das Resultat probeweise laufen (Continuous Integration).Durch möglichst kurz gehaltene Releasezyklen werden Fehler frühzeitig erkannt (Continuous Delivery). Die Deployment-Pipeline ist vollständig automatisierbar und garantiert, dass der Code zu jedem Zeitpunkt releast werden kann.

Secrets & Konfigurations­management

Kubernetes stellt Mechanismen zur Verfügung, um deine Applikation für unterschiedliche Umgebungen zu konfigurieren. Mit dem von uns eingesetzten Kube Sealer ist es sogar möglich, Konfigurationen mit Passwörtern in einem öffentlich zugänglichen Git-Repository abzulegen (siehe GitOps-Pattern) – nur der dafür vorgesehene Kubernetes-Cluster ist in der Lage, die verschlüsselten Informationen zu lesen.

Desired State

Anders als bei klassischen oder virtualisierten Deployments deklarieren wir bei Container-Deployments den sogenannte Desired State. Wir starten das Deployment nicht selbst, sondern delegieren an Kubernetes: «Bitte starte mir dieses Deployment». Kubernetes kümmert sich um die Ausführung und stellt sicher, dass der Desired State eingehalten wird.

Service Discovery & Load Balancing

Kubernetes kümmert sich darum, dass deine Deployments unter der richtigen Adresse erreichbar sind (Service Discovery) und die Last mit einem Loadbalancer auf die Replikate verteilt werden, wenn mehrere Container aktiv sind.

GitOps-Pattern

Beim GitOps-Pattern werden sämtliche Kubernetes-Konfigurationen (sogenannte Manifests) mit dem Quellcode in einem Git-Repository gespeichert. Git protokolliert sämtliche Änderungen am System und macht sie dadurch nachvollziehbar und erlaubt, sie jederzeit rückgängig zu machen.