Cloud Native DevOps mit Kubernetes - John Arundel - E-Book

Cloud Native DevOps mit Kubernetes E-Book

John Arundel

0,0

Beschreibung

Cloud-Experten John Arundel und Justin Domingus zeigen Ihnen in diesem pragmatischen Buch, was Kubernetes kann, welche Tools und Frameworks Ihnen zur Verfügung stehen und wie Sie in der Cloud eine Anwendung mit Kubernetes entwickeln und deployen. Erfahren Sie alles über das Ökosystem von Kubernetes und lernen Sie erprobte Lösungen für die tagtäglichen Probleme kennen. Bauen Sie Schritt für Schritt eine Cloud-native Beispielanwendung und die zugehörige Infrastruktur auf, zusammen mit einer Entwicklungsumgebung und Continuous-Development-Pipeline, die Sie für Ihre eigenen Anwendungen nutzen können. - Verstehen Sie die Grundprinzipien von Containern und Kubernetes – es sind keine Vorkenntnisse notwendig. - Betreiben Sie Ihre eigenen Cluster oder wählen Sie einen Managed Kubernetes Service von Amazon, Google o. a. aus. - Nutzen Sie Kubernetes, um Ressourcen-Einsatz und Container-Lebenszyklen zu managen. - Optimieren Sie Cluster in Bezug auf Kosten, Performance, Resilienz, Kapazität und Skalierbarkeit. - Lernen Sie die besten Tools für das Entwickeln, Testen und Deployen Ihrer Anwendungen kennen. - Wenden Sie die aktuellen Best Practices in den Bereichen Sicherheit, Observabilität und Monitoring an. - Übernehmen Sie DevOps-Prinzipien, um Ihren Entwicklungsteams dabei zu helfen, schnell, effektiv und lean zu werden. "Der umfassendste, maßgeblichste und praxisnaheste Text über die Hege und Pflege der Kubernetes-Infrastruktur. Pflichtlektüre." Jeremy Yates, SRE Team, The Home Depot QuoteCenter "Sehr klar und informativ. Es behandelt alle Details, ohne Kompromisse bei der Verständlichkeit einzugehen." Will Thames, Platform Engineer, Skedulo

Sie lesen das E-Book in den Legimi-Apps auf:

Android
iOS
von Legimi
zertifizierten E-Readern

Seitenzahl: 492

Das E-Book (TTS) können Sie hören im Abo „Legimi Premium” in Legimi-Apps auf:

Android
iOS
Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



John Arundel ist Berater und Autor mit über 30 Jahren Erfahrung in der Computerbranche. Er arbeitet weltweit mit Firmen zusammen und berät sie zu Kubernetes sowie Cloud- und Infrastruktur-Themen.

Justin Domingus ist DevOps-Engineer bei CareZome.com. Er hat sich auf Kubernetes und Cloud Computing spezialisiert.

Zu diesem Buch – sowie zu vielen weiteren dpunkt.büchern – können Sie auch das entsprechende E-Book im PDF-Format herunterladen. Werden Sie dazu einfach Mitglied bei dpunkt.plus+:

www.dpunkt.plus

John Arundel • Justin Domingus

Cloud Native DevOpsmit Kubernetes

Bauen, Deployen und Skalierenmoderner Anwendungen in der Cloud

John Arundel • Justin Domingus

Übersetzung: Thomas Demmig

Lektorat: Sandra Bollenbacher

Copy-Editing: Petra Heubach-Erdmann, Düsseldorf

Satz: Gerhard Alfes, mediaService, Siegen, www.mediaservice.tv

Herstellung: Stefanie Weidner

Umschlaggestaltung: Helmut Kraus, www.exclam.de

Bibliografische Information der Deutschen Nationalbibliothek

Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.d-nb.de abrufbar.

ISBN:

Print978-3-86490-698-5

PDF978-3-96088-828-4

ePub978-3-96088-829-1

mobi978-3-96088-830-7

1. Auflage 2019

Copyright © 2019 dpunkt.verlag GmbH

Wieblinger Weg 17

69123 Heidelberg

Authorized German translation of the English edition of Cloud Native DevOps with Kubernetes

ISBN 978-1492040767 © 2019 John Arundel and Justin Domingus

This translation is published and sold by permission of O'Reilly Media, Inc., which owns or controls all rights to publish and sell the same.

Hinweis:

Dieses Buch wurde auf PEFC-zertifiziertem Papier aus nachhaltiger Waldwirtschaft gedruckt. Der Umwelt zuliebe verzichten wir zusätzlich auf die Einschweißfolie.

Schreiben Sie uns:

Falls Sie Anregungen, Wünsche und Kommentare haben, lassen Sie es uns wissen: [email protected].

Die vorliegende Publikation ist urheberrechtlich geschützt. Alle Rechte vorbehalten. Die Verwendung der Texte und Abbildungen, auch auszugsweise, ist ohne die schriftliche Zustimmung des Verlags urheberrechtswidrig und daher strafbar. Dies gilt insbesondere für die Vervielfältigung, Übersetzung oder die Verwendung in elektronischen Systemen. Es wird darauf hingewiesen, dass die im Buch verwendeten Soft- und Hardware-Bezeichnungen sowie Markennamen und Produktbezeichnungen der jeweiligen Firmen im Allgemeinen warenzeichen-, marken- oder patentrechtlichem Schutz unterliegen. Alle Angaben und Programme in diesem Buch wurden mit größter Sorgfalt kontrolliert. Weder Autor noch Verlag noch Herausgeber noch Übersetzer können jedoch für Schäden haftbar gemacht werden, die in Zusammenhang mit der Verwendung dieses Buches stehen.

5 4 3 2 1 0

Cloud Native DevOps ist für die verteilten Systeme von heute ein unentbehrliches Handbuch. Es ist ausgesprochen klar, sehr informativ und behandelt alle Details, während es gut lesbar bleibt. Ich habe viel gelernt und definitiv ein paar Aufgaben für mich mitgenommen!

– Will Thames, Platform Engineer, Skedulo

Der umfassendste, maßgeblichste und praxisnächste Text über die Hege und Pflege von Kubernetes-Infrastruktur. Absolut unverzichtbar.

– Jeremy Yates, SRE Team, The Home Depot QuoteCenter

Ich wünschte, ich hätte dieses Buch schon gehabt, als ich anfing! Es ist Pflichtlektüre für alle, die in Kubernetes entwickeln und Anwendungen laufen lassen.

– Paul van der Linden, Lead Developer, vdL Software Consultancy

Dieses Buch hat mich wirklich begeistert. Für jemanden auf der Suche nach Informationen über Kubernetes ist es unbezahlbar und ich habe das Gefühl, mein Niveau dadurch angehoben zu haben.

– Adam McPartlan (@mcparty), Senior Systems Engineer, NYnet

Ich habe es wirklich genossen, dieses Buch zu lesen. Es ist sehr lehrreich, gleichzeitig aber auch deutlich in seinen Empfehlungen. Man findet darin viele tolle praktische Tipps. Genau die Art von Informationen, die jeder sucht, von denen er aber nicht weiß, wie er sie bekommen soll.

– Nigel Brown, Cloud Native Trainer und Kursautor

Inhaltsverzeichnis

Vorwort

Einleitung

1Revolution in der Cloud

1.1Die Entstehung der Cloud

1.1.1Zeit einkaufen

1.1.2Infrastructure as a Service

1.2Der Aufstieg von DevOps

1.2.1Keiner versteht DevOps

1.2.2Der Geschäftsvorteil

1.2.3Infrastruktur als Code

1.2.4Gemeinsames Lernen

1.3Das Aufkommen von Containern

1.3.1State of the Art

1.3.2Innerhalb der Box denken

1.3.3Software in Containern verpacken

1.3.4Plug-and-Play-Anwendungen

1.4Das Container-Orchester dirigieren

1.5Kubernetes

1.5.1Von Borg zu Kubernetes

1.5.2Was macht Kubernetes so wertvoll?

1.5.3Wird Kubernetes wieder verschwinden?

1.5.4Kubernetes kann nicht alles

1.6Cloud Native

1.7Die Zukunft von Operations

1.7.1Verteiltes DevOps

1.7.2Manches wird zentralisiert bleiben

1.7.3Developer Productivity Engineering

1.7.4Sie sind die Zukunft

1.8Zusammenfassung

2Erste Schritte mit Kubernetes

2.1Starten Sie Ihren ersten Container

2.1.1Docker Desktop installieren

2.1.2Was ist Docker?

2.1.3Ein Container-Image starten

2.2Die Demo-Anwendung

2.2.1Den Quellcode anschauen

2.2.2Go?

2.2.3Wie die Demo-Anwendung funktioniert

2.3Einen Container bauen

2.3.1Dockerfiles verstehen

2.3.2Minimale Container-Images

2.3.3docker image build ausführen

2.3.4Ihrem Image einen Namen geben

2.3.5Port Forwarding

2.4Container-Registries

2.4.1Sich an der Registry authentifizieren

2.4.2Ihr Image benennen und pushen

2.4.3Ihr Image ausführen

2.5Hallo Kubernetes

2.5.1Die Demo-App starten

2.5.2Wenn der Container nicht startet

2.6Minikube

2.7Zusammenfassung

3Kubernetes-Installationen

3.1Cluster-Architektur

3.1.1Die Steuerungsebene

3.1.2Komponenten auf den Knoten

3.1.3Hochverfügbarkeit

3.2Die Kosten eines selbst gehosteten Kubernetes

3.2.1Es ist mehr, als Sie denken

3.2.2Es geht nicht nur um das initiale Setup

3.2.3Tools nehmen Ihnen nicht die ganze Arbeit ab

3.2.4Kubernetes ist schwer

3.2.5Administrativer Overhead

3.2.6Beginnen Sie mit Managed Services

3.3Managed Kubernetes Services

3.3.1Google Kubernetes Engine (GKE)

3.3.2Cluster Autoscaling

3.3.3Amazon Elastic Container Service for Kubernetes (EKS)

3.3.4Azure Kubernetes Service (AKS)

3.3.5OpenShift

3.3.6IBM Cloud Kubernetes Service

3.3.7Heptio Kubernetes Subscription (HKS)

3.4Turnkey-Kubernetes-Lösungen

3.4.1Stackpoint

3.4.2Containership Kubernetes Engine (CKE)

3.5Kubernetes-Installer

3.5.1kops

3.5.2Kubespray

3.5.3TK8

3.5.4Kubernetes The Hard Way

3.5.5kubeadm

3.5.6Tarmak

3.5.7Rancher Kubernetes Engine (RKE)

3.5.8Puppet Kubernetes Module

3.5.9Kubeformation

3.6Kaufen oder bauen: Unsere Empfehlungen

3.6.1Run Less Software

3.6.2Nutzen Sie Managed Kubernetes, wenn Sie können

3.6.3Aber was ist mit dem Vendor Lock-In?

3.6.4Nutzen Sie Self-Hosting-Standard-Tools für Kubernetes, wenn Sie müssen

3.6.5Wenn Ihre Auswahl begrenzt ist

3.6.6Bare-Metal und On-Prem

3.7Clusterless Container Services

3.7.1Amazon Fargate

3.7.2Azure Container Instances (ACI)

3.8Zusammenfassung

4Mit Kubernetes-Objekten arbeiten

4.1Deployments

4.1.1Supervising und Scheduling

4.1.2Container neu starten

4.1.3Deployments abfragen

4.2Pods

4.3ReplicaSets

4.4Den gewünschten Status warten

4.5Der Kubernetes-Scheduler

4.6Ressourcen-Manifeste im YAML-Format

4.6.1Ressourcen sind Daten

4.6.2Deployment-Manifeste

4.6.3kubectl apply verwenden

4.6.4Service-Ressourcen

4.6.5Das Cluster mit kubectl abfragen

4.6.6Ressourcen noch leistungsfähiger machen

4.7Helm: Ein Kubernetes-Paketmanager

4.7.1Helm installieren

4.7.2Einen Helm-Chart installieren

4.7.3Charts, Repositories und Releases

4.7.4Helm-Releases anzeigen

4.8Zusammenfassung

5Ressourcen managen

5.1Ressourcen verstehen

5.1.1Ressourcen-Einheiten

5.1.2Ressourcen-Anforderungen

5.1.3Ressourcen-Grenzen

5.1.4Halten Sie Ihre Container klein

5.2Den Lebenszyklus des Containers managen

5.2.1Liveness-Probe

5.2.2Verzögerung und Häufigkeit der Probe

5.2.3Andere Arten von Proben

5.2.4gRPC-Proben

5.2.5Readiness-Proben

5.2.6Dateibasierte Readiness-Proben

5.2.7minReadySeconds

5.2.8Pod Disruption Budgets

5.3Namensräume verwenden

5.3.1Mit Namensräumen arbeiten

5.3.2Welchen Namensraum sollte ich verwenden?

5.3.3Service-Adressen

5.3.4Resource Quotas

5.3.5Standards für Ressourcen-Anforderungen und -Grenzen

5.4Die Kosten von Clustern optimieren

5.4.1Deployments optimieren

5.4.2Pods optimieren

5.4.3Vertical Pod Autoscaler

5.4.4Knoten optimieren

5.4.5Storage optimieren

5.4.6Ungenutzte Ressourcen aufräumen

5.4.7Freie Kapazitäten prüfen

5.4.8Reservierte Instanzen nutzen

5.4.9Präemptive (Spot)-Instanzen verwenden

5.4.10Sorgen Sie für eine ausgeglichene Verteilung Ihrer Workloads

5.5Zusammenfassung

6Cluster betreiben

6.1Sizing und Skalieren des Clusters

6.1.1Kapazitätsplanung

6.1.2Knoten und Instanzen

6.1.3Das Cluster skalieren

6.2Konformitäts-Prüfungen

6.2.1CNCF Certification

6.2.2Konformitäts-Tests mit Sonobuoy

6.3Validierung und Auditing

6.3.1K8Guard

6.3.2Copper

6.3.3kube-bench

6.3.4Kubernetes Audit Logging

6.4Chaos Testing

6.4.1Nur Produktion ist Produktion

6.4.2chaoskube

6.4.3kube-monkey

6.4.4PowerfulSeal

6.5Zusammenfassung

7Power-Tools für Kubernetes

7.1Die Arbeit mit kubectl

7.1.1Shell-Aliasse

7.1.2Kurze Flags verwenden

7.1.3Ressourcen-Typen abkürzen

7.1.4Autovervollständigen von kubectl-Befehlen

7.1.5Hilfe erhalten

7.1.6Hilfe zu Kubernetes-Ressourcen erhalten

7.1.7Detaillertere Ausgaben nutzen

7.1.8Mit JSON-Daten und jq arbeiten

7.1.9Objekte beobachten

7.1.10Objekte beschreiben

7.2Mit Ressourcen arbeiten

7.2.1Imperative kubectl-Befehle

7.2.2Wann Sie keine imperativen Befehle verwenden sollten

7.2.3Ressourcen-Manifeste generieren

7.2.4Ressourcen exportieren

7.2.5Ressourcen diffen

7.3Mit Containern arbeiten

7.3.1Die Logs eines Containers anzeigen

7.3.2Sich mit einem Container verbinden

7.3.3Kubernetes-Ressourcen mit kubespy beobachten

7.3.4Einen Container-Port weiterleiten

7.3.5Befehle in Containern ausführen

7.3.6Container zur Fehlersuche ausführen

7.3.7BusyBox-Befehle verwenden

7.3.8BusyBox zu Ihren Containern hinzufügen

7.3.9Programme auf einem Container installieren

7.3.10Live Debugging mit kubesquash

7.4Kontexte und Namensräume

7.4.1kubectx und kubens

7.4.2kube-ps1

7.5Shells und Tools für Kubernetes

7.5.1kube-shell

7.5.2Click

7.5.3kubed-sh

7.5.4Stern

7.6Bauen Sie Ihre eigenen Kubernetes-Tools

7.7Zusammenfassung

8Container ausführen

8.1Container und Pods

8.1.1Was ist ein Container?

8.1.2Was gehört in einen Container?

8.1.3Was gehört in einen Pod?

8.2Container-Manifeste

8.2.1Image-Bezeichner

8.2.2Das Tag »latest«

8.2.3Container-Digests

8.2.4Basis-Image-Tags

8.2.5Ports

8.2.6Ressourcen-Anforderungen und -Grenzen

8.2.7Image-Pull-Richtlinie

8.2.8Umgebungsvariablen

8.3Sicherheit von Containern

8.3.1Container als Nicht-Root-Benutzer ausführen

8.3.2Root-Container blockieren

8.3.3Ein Read-Only-Dateisystem nutzen

8.3.4Privilege Escalation deaktivieren

8.3.5Capabilities

8.3.6Pod Security Contexts

8.3.7Pod Security Policies

8.3.8Pod Service-Accounts

8.4Volumes

8.4.1emptyDir-Volumes

8.4.2Persistente Volumes

8.5Neustart-Richtlinien

8.6Image Pull Secrets

8.7Zusammenfassung

9Pods managen

9.1Labels

9.1.1Was sind Labels?

9.1.2Selektoren

9.1.3Komplexere Selektoren

9.1.4Andere Einsatzzwecke für Labels

9.1.5Labels und Anmerkungen

9.2Node Affinities

9.2.1Hard Affinities

9.2.2Soft Affinities

9.3Pod Affinities und Anti-Affinities

9.3.1Pods zusammenhalten

9.3.2Pods auseinanderhalten

9.3.3Soft Anti-Affinities

9.3.4Wann Sie Pod Affinities verwenden

9.4Taints und Tolerations

9.5Pod-Controller

9.5.1DaemonSets

9.5.2StatefulSets

9.5.3Jobs

9.5.4Cronjobs

9.5.5Horizontal Pod Autoscaler

9.5.6PodPresets

9.5.7Operatoren und Custom Resource Definitions (CRDs)

9.6Ingress-Ressourcen

9.6.1Ingress-Regeln

9.6.2TLS Termination mit Ingress

9.6.3Ingress-Controller

9.7Istio

9.8Envoy

9.9Zusammenfassung

10Konfiguration und Secrets

10.1ConfigMaps

10.1.1ConfigMaps erstellen

10.1.2Umgebungsvariablen aus ConfigMaps setzen

10.1.3Die gesamte Umgebung aus einer ConfigMap erstellen

10.1.4Umgebungsvariablen in Argumenten für Befehle einsetzen

10.1.5Konfigurationsdateien aus ConfigMaps erstellen

10.1.6Pods bei einer Konfigurationsänderung aktualisieren

10.2Kubernetes-Secrets

10.2.1Secrets als Umgebungsvariablen verwenden

10.2.2Secrets in Dateien schreiben

10.2.3Secrets lesen

10.2.4Zugriff auf Secrets

10.2.5Encryption at Rest

10.2.6Secrets behalten

10.3Strategien zum Verwalten von Secrets

10.3.1Secrets in der Versionsverwaltung verschlüsseln

10.3.2Secrets remote ablegen

10.3.3Ein dediziertes Secrets-Management-Tool einsetzen

10.3.4Empfehlungen

10.4Secrets mit Sops verschlüsseln

10.4.1Einführung in Sops

10.4.2Eine Datei mit Sops verschlüsseln

10.4.3Ein KMS-Backend verwenden

10.5Zusammenfassung

11Sicherheit und Backups

11.1Zugriffskontrolle und Berechtigungen

11.1.1Den Zugriff vom Cluster abhängig machen

11.1.2Role-Based Access Control (RBAC)

11.1.3Rollen

11.1.4Rollen mit Benutzern verbinden

11.1.5Welche Rolle benötige ich?

11.1.6Den Zugriff auf cluster-admin beschränken

11.1.7Anwendungen und Deployment

11.1.8Fehlersuche mit RBAC

11.2Security Scanning

11.2.1Clair

11.2.2Aqua

11.2.3Anchore Engine

11.3Backups

11.3.1Muss ich ein Backup von Kubernetes machen?

11.3.2Backup von etcd

11.3.3Backup des Ressourcen-Status

11.3.4Backup des Cluster-Status

11.3.5Große und kleine Katastrophen

11.3.6Velero

11.4Den Cluster-Status monitoren

11.4.1kubectl

11.4.2CPU- und Speicherauslastung

11.4.3Konsole des Cloud-Providers

11.4.4Kubernetes Dashboard

11.4.5Weave Scope

11.4.6kube-ops-view

11.4.7node-problem-detector

11.5Weitere Informationen

11.6Zusammenfassung

12Kubernetes-Anwendungen deployen

12.1Manifeste mit Helm bauen

12.1.1Was befindet sich in einem Helm-Chart?

12.1.2Helm-Templates

12.1.3Variablen interpolieren

12.1.4Template-Werte mit Anführungszeichen versehen

12.1.5Abhängigkeiten festlegen

12.2Helm-Charts deployen

12.2.1Variablen setzen

12.2.2Werte in einem Helm-Release angeben

12.2.3Eine Anwendung mit Helm aktualisieren

12.2.4Zu früheren Versionen zurückrollen

12.2.5Ein Helm-Chart-Repo erstellen

12.2.6Helm-Chart-Secrets mit Sops managen

12.3Mehrere Charts mit Helmfile managen

12.3.1Was befindet sich in einem Helmfile?

12.3.2Chart-Metadaten

12.3.3Das Helmfile anwenden

12.4Fortgeschrittene Tools zur Manifest-Verwaltung

12.4.1ksonnet

12.4.2Kapitan

12.4.3kustomize

12.4.4kompose

12.4.5Ansible

12.4.6kubeval

12.5Zusammenfassung

13Entwicklungs-Workflow

13.1Entwicklungs-Tools

13.1.1Skaffold

13.1.2Draft

13.1.3Telepresence

13.1.4Knative

13.2Deployment-Strategien

13.2.1Rollierende Updates

13.2.2Recreate

13.2.3maxSurge und maxUnavailable

13.2.4Blue/Green-Deployments

13.2.5Rainbow-Deployments

13.2.6Canary-Deployments

13.3Migration mit Helm

13.3.1Helm Hooks

13.3.2Umgang mit fehlgeschlagenen Hooks

13.3.3Andere Hooks

13.3.4Hooks verketten

13.4Zusammenfassung

14Continuous Deployment in Kubernetes

14.1Was ist Continuous Deployment?

14.2Welches CD-Tool soll ich verwenden?

14.2.1Jenkins

14.2.2Drone

14.2.3Google Cloud Build

14.2.4Concourse

14.2.5Spinnaker

14.2.6GitLab CI

14.2.7Codefresh

14.2.8Azure Pipelines

14.3CD-Komponenten

14.3.1Docker Hub

14.3.2Gitkube

14.3.3Flux

14.3.4Keel

14.4Eine CD-Pipeline mit Cloud Build

14.4.1Google Cloud und GKE einrichten

14.4.2Das Demo-Repository forken

14.4.3Erste Schritte in Cloud Build

14.4.4Den Test-Container bauen

14.4.5Die Tests ausführen

14.4.6Den Anwendungs-Container bauen

14.4.7Die Kubernetes-Manifeste überprüfen

14.4.8Das Image veröffentlichen

14.4.9Git-SHA-Tags

14.4.10Den ersten Build-Trigger erstellen

14.4.11Den Trigger testen

14.4.12Von einer CD-Pipeline deployen

14.4.13Einen Deploy-Trigger erstellen

14.4.14Die Build-Pipeline optimieren

14.4.15Die Beispiel-Pipeline anpassen

14.5Zusammenfassung

15Observability und Monitoring

15.1Was ist Observability?

15.1.1Was ist Monitoring?

15.1.2Black-Box Monitoring

15.1.3Was heißt »Up«?

15.1.4Logging

15.1.5Metriken

15.1.6Tracing

15.1.7Observability

15.2Die Observability-Pipeline

15.3Monitoring in Kubernetes

15.3.1Externe Black-Box Checks

15.3.2Interne Health-Checks

15.4Zusammenfassung

16Metriken in Kubernetes

16.1Was sind Metriken wirklich?

16.1.1Zeitreihen-Daten

16.1.2Zähler und Maße

16.1.3Was können uns Metriken sagen?

16.2Die Wahl guter Metriken

16.2.1Services: Das RED-Muster

16.2.2Ressourcen: Das USE-Muster

16.2.3Business-Metriken

16.2.4Kubernetes-Metriken

16.3Metriken analysieren

16.3.1Was ist an einem einfachen Durchschnitt falsch?

16.3.2Mittelwert, Median und Ausreißer

16.3.3Perzentile

16.3.4Perzentile auf Metrikdaten anwenden

16.3.5Meist wollen wir das Schlimmste wissen

16.3.6Mehr als Perzentile

16.4Metriken in Dashboards visualisieren

16.4.1Ein Standard-Layout für alle Services verwenden

16.4.2Einen Information Radiator mit Master Dashboards bauen

16.4.3Dashboards mit Fehlerursachen

16.5Alarme durch Metriken

16.5.1Was ist falsch an Alarmen?

16.5.2Bereitschaftsdienst sollte nicht die Hölle sein

16.5.3Dringende, wichtige und umsetzbare Alarme

16.5.4Dokumentieren Sie Warnungen und Alarme außerhalb der Bürozeiten und in der Nacht

16.6Tools und Services für Metriken

16.6.1Prometheus

16.6.2Google Stackdriver

16.6.3AWS Cloudwatch

16.6.4Azure Monitor

16.6.5Datadog

16.6.6New Relic

16.7Zusammenfassung

17Nachwort

17.1Wohin als Nächstes?

17.2Willkommen an Bord

Index

Vorwort

Willkommen zu »Cloud Native DevOps mit Kubernetes«.

Kubernetes ist eine echte Revolution für die Branche. Schon ein kurzer Blick auf die Interactive Landscape der Cloud Native Foundation (https://landscape.cncf.io) mit Daten über mehr als 600 aktuelle Projekte zeigt, wie wichtig Kubernetes heutzutage ist. Nicht alle diese Tools wurden für Kubernetes entwickelt, ja nicht einmal alle können mit Kubernetes genutzt werden, aber alle sind Teil des riesigen Ökosystems, in dem Kubernetes eines der Aushängeschilder ist.

Kubernetes hat die Art und Weise verändert, wie Anwendungen entwickelt und betrieben werden. Es ist eine zentrale Komponente der heutigen DevOps-Welt. Kubernetes verschafft Entwicklern Flexibilität und Operations-Freiheiten. Heutzutage können Sie Kubernetes mit jedem wichtigen Cloud-Provider nutzen, On-Premise auf eigenen Rechnern einsetzen (Bare-Metal), aber auch lokal auf dem Entwicklerrechner verwenden. Stabilität, Flexibilität, eine mächtige API, Open Code und eine offene Entwickler-Community sind ein paar der Gründe, warum Kubernetes zum Branchenstandard wurde – so wie Linux ein Standard bei den Betriebssystemen ist.

»Cloud Native DevOps mit Kubernetes« ist ein großartiges Handbuch für Leute, die tagtäglich mit Kubernetes arbeiten, aber auch für die, die gerade erst ihre Reise mit Kubernetes begonnen haben. John Arundel und Justin Domingus behandeln alle wichtigen Aspekte des Deployens, Konfigurierens und Betreibens von Kubernetes und Best Practices für das Entwickeln und Ausführen von Anwendungen darauf. Zudem liefern sie einen Überblick über zugehörige Technologien, unter anderem Prometheus, Helm und Continuous Deployment. Dieses Buch ist Pflichtlektüre für jeden in der Welt von DevOps.

Kubernetes ist nicht einfach nur ein weiteres tolles Tool – es ist ein Branchenstandard und Grundlage für moderne Technologien wie Serverless-Tools (Open-FaaS, Knative) und Werkzeuge zum maschinellen Lernen (Kubeflow). Die gesamte IT-Branche verändert sich mit der Cloud-Native-Revolution und es ist ausgesprochen spannend, dabei zu sein.

– Ihor Dvoretskyi, Develover Advocate,

Cloud Native Computing Foundation, Dezember 2018

Einleitung

In der Welt von IT Operations sind die Prinzipien von DevOps gut verstanden und weitgehend umgesetzt, aber jetzt hat sich die Situation geändert. Eine neue Anwendungsplattform namens Kubernetes kommt bei immer mehr Firmen auf der ganzen Welt und in allen möglichen Branchen zum Einsatz. Mit mehr und mehr Anwendungen und Geschäftsszenarien, die von klassischen Servern in die Kubernetes-Umgebung wandern, fragen sich die Leute, wie man in dieser neuen Welt denn DevOps umsetzen soll.

Dieses Buch erklärt, was DevOps in einer Cloud-Native-Welt bedeutet, in der Kubernetes die Standard-Plattform ist. Es wird Ihnen dabei helfen, die besten Tools und Frameworks im Kubernetes-Ökosystem auszuwählen. Auch wird es einen stimmigen Weg für den Einsatz dieser Tools und Frameworks beschreiben und erprobte Lösungen bieten, die jetzt schon zum Einsatz kommen – in der produktiven Wirklichkeit.

Was werde ich lernen?

Sie werden lernen, was Kubernetes ist, woher es kommt und was es für die Zukunft der Software-Entwicklung und von Operations bedeutet. Sie werden erfahren, wie Container funktionieren, wie man sie baut und managt und wie man Cloud Native Services und Infrastruktur entwirft.

Sie werden verstehen, was das Bauen und Hosten eigener Kubernetes-Cluster im Vergleich zum Einsatz von Managed Services bedeutet. Sie werden die Möglichkeiten, Grenzen sowie Vor- und Nachteile beliebter Installations-Tools für Kubernetes wie kops, kubeadm und Kubespray kennenlernen. Sie werden einen Überblick über die großen gemanagten Kubernetes-Angebote von den wichtigsten Anbietern wie Amazon, Google oder Microsoft erhalten.

Im Buch finden Sie Erfahrungen aus der Praxis zum Schreiben und Deployen von Kubernetes-Anwendungen, das Konfigurieren und Betreiben von Kubernetes-Clustern und das Automatisieren der Cloud-Infrastruktur und der Deployments mit Tools wie Helm. Sie lernen etwas über die Unterstützung von Kubernetes in den Bereichen Sicherheit, Authentifizierung und Berechtigungen, einschließlich der Role-Based Access Control (RBAC) und über Best Practices zum Absichern von Containern und Kubernetes im Produktivumfeld.

Sie werden erfahren, wie Sie Continuous Integration und Deployment mit Kubernetes umsetzen, wie Sie Daten sichern und wiederherstellen, wie Sie Ihr Cluster auf Konformität und Zuverlässigkeit prüfen, wie Sie Metriken überwachen, verfolgen, protokollieren und aggregieren und wie Sie Ihre Kubernetes-Infrastruktur skalierbar, widerstandsfähig und kostengünstig betreiben.

All das machen wir anhand einer sehr einfachen Demo-Anwendung deutlich. Sie können unsere Beispiele mithilfe des Codes aus unserem Git-Repo nachvollziehen.

Für wen ist dieses Buch gedacht?

Dieses Buch richtet sich vor allem an Mitarbeiter aus IT Operations, die für Server, Anwendungen und Services verantwortlich sind, und an Entwickler, die entweder neue Cloud Native Services bauen oder bestehende Anwendungen auf Kubernetes und in die Cloud migrieren sollen. Wir erwarten kein vorhandenes Wissen über Kubernetes oder Container – keine Sorge, all das werden wir Ihnen vorstellen.

Aber auch erfahrene Kubernetes-Anwender sollten in diesem Buch fündig werden: Es behandelt auch fortgeschrittene Themen wie RBAC, Continuous Deployment, Secrets-Management und Observability. Unabhängig von Ihrem Wissen hoffen wir, dass Sie auf diesen Seiten etwas Nützliches finden werden.

Welche Fragen beantwortet dieses Buch?

Bei der Planung und Entstehung dieses Buches haben wir mit Hunderten von Leuten über Cloud Native und Kubernetes gesprochen – von Branchenführern und Experten bis hin zu kompletten Neulingen. Dies sind ein paar der Fragen, die sie gerne in solch einem Buch beantwortet haben wollten:

»Ich will erfahren, warum ich meine Zeit für diese Technologie aufwenden sollte. Welche Probleme löst sie für mich und mein Team?«

»Kubernetes scheint toll zu sein, hat aber eine ziemlich steile Lernkurve. Eine schnelle Demo ist leicht aufgesetzt, aber Operations und Fehlersuche schrecken mich ab. Wir hätten gerne ein paar vernünftige Ratschläge von Leuten, die Kubernetes-Cluster in der Realität betreiben, und wüssten gerne, welche Probleme sich dabei stellen.«

»Gut begründete Empfehlungen wären nützlich. Das Ökosystem von Kubernetes enthält zu viele Möglichkeiten, aus denen sich neu damit befassende Teams wählen müssen. Welcher Weg ist der beste, wenn man etwas erreichen will? Wir entscheiden wir uns?«

Und die vielleicht wichtigste Frage von allen: »Wie nutze ich Kubernetes, ohne meine Firma zu gefährden?«

Wir haben diese Fragen – und viele andere – im Hinterkopf behalten, während wir das Buch schrieben, und wir haben uns Mühe gegeben, sie auch zu beantworten. Ist es uns gelungen? Finden Sie es auf den nächsten Seiten heraus.

Konventionen in diesem Buch

Die folgenden typografischen Konventionen werden in diesem Buch genutzt:

Kursiv

Für neue Begriffe, URLs, E-Mail-Adressen, Dateinamen und Dateierweiterungen.

Nichtproportionalschrift

Für Programmlistings, aber auch für Codefragmente in Absätzen, wie zum Beispiel Variablen- oder Funktionsnamen, Datenbanken, Datentypen, Umgebungsvariablen, Anweisungen und Schlüsselwörter.

fette Nichtproportionalschrift

Für Befehle und anderen Text, der genau so vom Benutzer eingegeben werden sollte.

kursive Nichtproportionalschrift

Für Text, der vom Benutzer durch eigene Werte ersetzt werden sollte.

Tipp

Dieses Symbol steht für einen Tipp oder Vorschlag.

Hinweis

Dieses Symbol steht für einen allgemeinen Hinweis.

Warnung

Dieses Symbol steht für eine Warnung oder Vorsichtsmaßnahme.

Der Einsatz von Codebeispielen

Zusätzliches Material (Codebeispiele, Übungen und so weiter) finden Sie (auf Englisch) zum Herunterladen auf https://github.com/cloudnativedevops/demo.

Dieses Buch ist dazu da, Ihnen beim Erledigen Ihrer Arbeit zu helfen. Im Allgemeinen dürfen Sie die Codebeispiele aus diesem Buch in Ihren eigenen Programmen und der dazugehörigen Dokumentation verwenden. Sie müssen uns dazu nicht um Erlaubnis fragen, solange Sie nicht einen beträchtlichen Teil des Codes reproduzieren. Beispielsweise benötigen Sie keine Erlaubnis, um ein Programm zu schreiben, in dem mehrere Codefragmente aus diesem Buch vorkommen. Wollen Sie dagegen eine CD-ROM mit Beispielen aus Büchern von dpunkt verkaufen oder verteilen, benötigen Sie eine Erlaubnis. Eine Frage zu beantworten, indem Sie aus diesem Buch zitieren und ein Codebeispiel wiedergeben, benötigt keine Erlaubnis. Eine beträchtliche Menge Beispielcode aus diesem Buch in die Dokumentation Ihres Produkts aufzunehmen, bedarf hingegen einer Erlaubnis.

Wir freuen uns über Zitate, verlangen diese aber nicht. Ein Zitat enthält Titel, Autor, Verlag und ISBN. Beispiel: »Cloud Native DevOps mit Kubernetes von John Arundel und Justin Domingus (dpunkt.verlag). Copyright 2019 dpunkt.verlag GmbH, 978-3-86490-698-5.«

Wenn Sie glauben, dass Ihre Verwendung von Codebeispielen über die übliche Nutzung hinausgeht oder außerhalb der oben vorgestellten Nutzungsbedingungen liegt, kontaktieren Sie uns bitte unter [email protected].

Wie Sie uns erreichen

Mit Anmerkungen, Fragen oder Verbesserungsvorschlägen zu diesem Buch können Sie sich jederzeit an den Verlag wenden:

[email protected]

Bitte beachten Sie, dass über unsere E-Mail-Adresse kein Software-Support angeboten wird.

Die englische Errata-Seite des Buches finden Sie unter:

http://bit.ly/cloud-nat-dev-ops

Danksagung

Unser ganzer Dank gilt den vielen Leuten, die frühe Versionen dieses Buches gelesen und uns wertvolles Feedback und gute Ratschläge gegeben haben oder uns auf andere Art und Weise behilflich waren. Dazu gehören (ohne Anspruch auf Vollständigkeit) Abby Bangser, Adam J. McPartlan, Adrienne Domingus, Alexis Richardson, Aron Trauring, Camilla Montonen, Gabriell Nascimento, Hannah Klemme, Hans Findel, Ian Crosby, Ian Shaw, Ihor Dvoretskyi, Ike Devolder, Jeremy Yates, Jérôme Petazzoni, Jessica Deen, John Harris, Jon Barber, Kitty Karate, Marco Lancini, Mark Ellens, Matt North, Michel Blanc, Mitchell Kent, Nicolas Steinmetz, Nigel Brown, Patrik Duditš, Paul van der Linden, Philippe Ensarguet, Pietro Mamberti, Richard Harper, Rick Highness, Sathyajith Bhat, Suresh Vishnoi, Thomas Liakos, Tim McGinnis, Toby Sullivan, Tom Hall, Vincent De Smet und Will Thames.

1Revolution in der Cloud

Es gab nie einen Zeitpunkt, an dem die Welt angefangen hat, weil sie immer wie in einem Kreis herumgeht. Auf einem Kreis gibt es aber keinen Punkt, wo er beginnt.

– Alan Watts

Eine Revolution findet statt. Eigentlich sind es sogar drei Revolutionen zugleich.

Die erste Revolution ist das Entstehen der Cloud – und wir werden noch erläutern, um was es sich da handelt und warum das wichtig ist. Die zweite ist das Aufkommen von DevOps, zu dem Sie erfahren werden, was darin steckt und wie es Operations verändert. Die dritte Revolution ist der Einsatz von Containern. Zusammen schaffen diese drei Wellen eine neue Software-Welt: die Cloud Native-Welt. Und das Betriebssystem für diese Welt nennt sich Kubernetes.

In diesem Kapitel werden wir kurz auf die Geschichte und Bedeutung dieser Revolutionen eingehen und aufzeigen, wie die Veränderungen die Art und Weise beeinflussen, nach der wir Software deployen und betreiben. Wir werden zeigen, was Cloud Native bedeutet und welche Unterschiede Sie in dieser neuen Welt erwarten können, wenn Sie im Software Development, in Operations, Deployment, der Entwicklung, im Networking oder im Sicherheitsumfeld tätig sind.

Wir denken, dass die Zukunft des Computing dank der Auswirkungen dieser miteinander verbundenen Revolutionen in cloudbasierten, containerisierten, verteilten Systemen liegt, die dynamisch per Automatisierung verwaltet werden und auf der Kubernetes-Plattform (oder etwas sehr Ähnlichem) laufen. Die Kunst des Entwickelns und Ausführens dieser Anwendungen – Cloud Native DevOps – wollen wir dann im weiteren Verlauf dieses Buches unter die Lupe nehmen.

Sind Sie mit diesem Hintergrund schon vertraut und wollen einfach mit Kubernetes loslegen, dürfen Sie gerne direkt zu Kapitel 2 springen. Wenn nicht, machen Sie es sich bequem, schnappen Sie sich eine Tasse Kaffee (oder was Sie gerne mögen) und dann legen wir los.

1.1Die Entstehung der Cloud

In den Anfängen (okay, in den 1960ern) füllten Computer Rack um Rack in großen, abgelegenen, klimatisierten Rechenzentren. Die Anwender bekamen sie nie zu sehen und konnten auch gar nicht direkt mit ihnen interagieren. Stattdessen reichten die Entwickler ihre Jobs aus der Ferne an den Computer ein und warteten auf die Ergebnisse. Viele Hunderte oder Tausende von Anwendern nutzten alle die gleiche Rechen-Infrastruktur und jeder erhielt eine Rechnung für die genutzte Prozessorzeit oder die verwendeten Ressourcen.

Für einzelne Unternehmen oder Organisationen lohnte es sich nicht, ihre eigene Rechenhardware zu kaufen und zu warten, daher entstand ein Geschäftsmodell, bei dem die Anwender die Rechenleistung auf woanders untergebrachten Computern gemeinsam nutzten, die jemand anderem gehörten, der sich auch um sie kümmerte.

Wenn sich das so anhört, als ob das nicht aus dem letzten Jahrhundert stammt, sondern hochaktuell ist – stimmt, das ist kein Zufall. Das Wort Revolution bedeutet »kreisförmige Bewegung« und die Computer sind, in gewisser Hinsicht, wieder dort gelandet, wo es begann. Sie sind zwar im Laufe der Jahre viel leistungsfähiger geworden – die aktuelle Apple Watch entspricht in etwa drei der Mainframes, die Sie in Abbildung 1–1 sehen – aber ein Pay-per-Use-Zugriff auf gemeinsam genutzte Rechenressourcen ist eine sehr alte Idee. Jetzt nennen wir das die Cloud und die Revolution, die mit Timesharing-Mainframes begann, hat ihren Kreis geschlossen.

Abb. 1–1Frühes Cloud Computing: Das IBM System/360 Model 91 im Goddard Space Flight Center der NASA

1.1.1Zeit einkaufen

Die zentrale Idee der Cloud ist folgende: Statt einen Rechner zu kaufen, kaufen Sie Rechenleistung. Statt also große Mengen an Kapital in realen Maschinen zu versenken, die sich schlecht skalieren lassen, kaputtgehen und schnell obsolet werden, kaufen Sie einfach Zeit auf dem Rechner von jemand anderem und lassen ihn sich um das Skalieren, Warten und Aktualisieren kümmern. In den Tagen der »Bare-Metal«-Geräte – dem »Eisenzeitalter«, wenn Sie so wollen – handelte es sich bei Rechenleistung um Anlagekosten. Jetzt sind es Betriebsausgaben, was einen großen Unterschied ausmacht.

Bei der Cloud geht es aber nicht nur um woanders stehende, gemietete Rechenleistung. Es geht auch um verteilte Systeme. Sie kaufen vielleicht reine Rechenressourcen (wie eine Google-Compute-Instanz oder eine AWS-Lambda-Funktion) und nutzen sie, um Ihre eigene Software auszuführen, aber zunehmend mieten Sie auch Cloud Services – im Prinzip den Einsatz von Software von jemand anderem. Verwenden Sie zum Beispiel PagerDuty, um Ihre Systeme zu monitoren und Sie zu benachrichtigen, wenn etwas nicht läuft, setzen Sie einen Cloud Service ein (manchmal auch als Software as a Service oder SaaS bezeichnet).

1.1.2Infrastructure as a Service

Nutzen Sie die Cloud-Infrastruktur, um Ihre eigenen Services laufen zu lassen, kaufen Sie Infrastructure as a Service (IaaS). Sie müssen kein Kapital binden, um sie zu kaufen, Sie müssen sie nicht aufbauen und auch nicht aktuell halten. Es ist einfach ein Rohstoff, so wie Strom oder Wasser. Cloud Computing ist eine Revolution in der Beziehung zwischen Unternehmen und ihrer IT-Infrastruktur.

Das Outsourcen der Hardware ist nur ein Teil der Geschichte – die Cloud ermöglicht es Ihnen zudem, die Software outzusourcen, die Sie nicht schreiben: Betriebssysteme, Datenbanken, Clustering, Replikation, Networking, Monitoring, Hochverfügbarkeit, Queue und Stream Processing und all die Unmengen an Software- und Konfigurations-Schichten, die die Lücke zwischen Ihrem Code und der CPU füllen. Managed Services können sich um so gut wie all das undifferenzierte »Heavy Lifting« für Sie kümmern (mehr zu den Vorteilen von Managed Services finden Sie in Kapitel 3).

Die Revolution in der Cloud hat auch eine Revolution bei den Leuten ausgelöst, die sie nutzen: die DevOps-Bewegung.

1.2Der Aufstieg von DevOps

Vor DevOps handelte es sich beim Entwickeln und Betreiben von Software mehr oder weniger um zwei getrennte Jobs, die von zwei verschiedenen Gruppen durchgeführt wurden. Entwickler schrieben Software, die sie dann an die Operations-Kollegen gaben, die die Software in der Produktivumgebung ausführten und betreuten (also echte Anwender bedienten, statt nur unter Testbedingungen zu laufen). Wie Computer, die eine eigene Etage im Gebäude brauchten, hat diese Trennung ihre Wurzeln in der Mitte des letzten Jahrhunderts. Software-Entwicklung war eine Aufgabe für Spezialisten, genauso wie das Betreiben der Computer, und es gab zwischen beidem nur wenig Überschneidungen.

Die beiden Abteilungen hatten dabei ziemlich unterschiedliche Ziele und Anreize, die öfter mal miteinander in Konflikt gerieten (Abbildung 1–2). Entwickler konzentrieren sich gerne darauf, schnell neue Features zu liefern, während es Operations-Teams wichtiger ist, Services langfristig stabil und zuverlässig zu machen.

Abb. 1–2Getrennte Teams können zu miteinander in Konflikt stehenden Anreizen führen. (Foto von Dave Roth)

Als die Cloud am Horizont erschien, wurde es anders. Verteilte Systeme sind komplex und das Internet ist sehr groß. Die Formalitäten beim Betreiben des Systems – Wiederherstellen nach Ausfällen, Umgang mit Timeouts, flüssiges Aktualisieren auf neuere Versionen – lassen sich nicht so einfach vom Design, der Architektur und Implementierung des Systems trennen.

Zudem ist »das System« nicht mehr länger nur Ihre Software: Es besteht aus In-House-Software, Cloud Services, Netzwerkressourcen, Load Balancern, Monitoring, Content Distribution Networks, Firewalls, DNS und so weiter. All diese Dinge sind eng miteinander verbunden und voneinander abhängig. Die Leute, die die Software schreiben, müssen verstehen, wie sie mit dem Rest des Systems im Zusammenhang steht, und die Leute, die das System betreiben, müssen verstehen, wie die Software funktioniert – oder auch nicht funktioniert.

Die Ursprünge der DevOps-Bewegung liegen in den Versuchen, diese beiden Gruppen zusammenzubringen – um zusammenzuarbeiten, ein gemeinsames Verständnis zu schaffen, die Verantwortung für die Zuverlässigkeit des Systems und die Korrektheit der Software zusammenzutragen und die Skalierbarkeit sowohl der Software-Systeme als auch der Teams zu verbessern, die sie bauen.

1.2.1Keiner versteht DevOps

DevOps wird gelegentlich als sehr umstrittene Sache angesehen, sowohl von Leuten, die darauf bestehen, dass es sich um nicht mehr als einen neuen Namen für bestehende gute Praktiken in der Software-Entwicklung handelt, wie auch von anderen, die keinen Bedarf für eine bessere Zusammenarbeit zwischen Entwicklung und Operations sehen.

Es gibt zudem ein weitverbreitetes Missverständnis darüber, was DevOps tatsächlich ist: Ein Job-Titel? Ein Team? Eine Methodik? Eine Reihe von Fähigkeiten? Der einflussreiche DevOps-Autor John Willis hat vier zentrale Säulen von DevOps herausgearbeitet, die er als Kultur, Automation, Messen und Teilen (Culture, Automation, Measurement and Sharing; CAMS) bezeichnet. Man kann es auch wie Brian Dawson als DevOps-Dreifaltigkeit bezeichnen: Menschen und Kultur, Prozess und Praktik sowie Tools und Technologie.

Mancher denkt, dass Cloud und Container zur Folge haben, dass wir kein DevOps mehr brauchen – eine Sichtweise, die manchmal als NoOps bezeichnet wird. Die Idee dahinter: Da das gesamte IT-Operations an einen Cloud-Provider oder eine andere Fremdfirma ausgelagert wurde, brauchen Firmen keine Vollzeit-Operations-Mitarbeiter mehr.

Der NoOps-Trugschluss basiert auf einer Fehleinschätzung dessen, was für Aufgaben DevOps tatsächlich beinhaltet:

Mit DevOps fällt ein großer Teil der klassischen Operations-Arbeit schon an, bevor der Code die Produktivumgebung erreicht. Zu jedem Release gehören Monitoring, Logging und A/B-Tests. CI/CD-Pipelines führen bei jedem Commit automatisch Unit-Tests, Security-Scans und Policy-Checks aus. Deployments sind automatisiert. Prüfroutinen, Aufgaben und nichtfunktionale Anforderungen werden nun vor dem Release implementiert und nicht erst während oder nach einem kritischen Ausfall.

– Jordan Bach (AppDynamics, https://blog.appdynamics.com/engineering/is-noops-the-end-of-devops-think-again)

Bei DevOps ist es am wichtigsten, sich darüber im Klaren zu sein, dass es sich vor allem um ein Thema rund um Organisation und Menschen handelt, nicht um eines rund um Technik. Dazu passt Jerry Weinbergs Second Law of Consulting:

Egal, wie es zu Beginn aussieht – es ist immer ein menschliches Problem.

– Gerald M. Weinberg, Secrets of Consulting

1.2.2Der Geschäftsvorteil

Aus wirtschaftlicher Sicht wurde DevOps beschrieben als »Verbessern der Qualität Ihrer Software durch das Beschleunigen von Release-Zyklen mithilfe von Cloud-Automation und -Praktiken, ergänzt durch den zusätzlichen Vorteil von Software, die im Produktivumfeld auch tatsächlich stabil läuft« (The Register, https://www.theregister.co.uk/2018/03/06/what_does_devops_do_to_decades_old_planning_processes_and_assumptions).

Die Übernahme von DevOps fordert von Unternehmen einen grundlegenden kulturellen Wandel, der in der Führungs- und strategischen Ebene beginnen und sich Schritt für Schritt auf jeden Teil der Firma ausweiten muss. Geschwindigkeit, Agilität, Zusammenarbeit, Automatisierung und Software-Qualität sind die zentralen Ziele von DevOps und für viele Unternehmen bedeutet das eine deutliche Veränderung in der Denkweise.

Aber DevOps funktioniert und Studien zeigen regelmäßig, dass Firmen, die DevOps-Prinzipien übernehmen, bessere Software schneller herausbringen, besser und schneller auf Fehler und Probleme reagieren, agiler im Markt vorgehen und die Qualität ihrer Produkte massiv verbessern:

DevOps ist keine Modeerscheinung – stattdessen handelt es sich um den Weg, auf dem erfolgreiche Organisationen heutzutage das Bereitstellen qualitativ hochwertiger Software industrialisieren, und er wird die neue Grundlage für die Zukunft und die kommenden Jahre darstellen.

– Brian Dawson (Cloudbees), Computer Business Review (https://www.cbronline.com/enterprise-it/applications/devops-fad-stay)

1.2.3Infrastruktur als Code

Früher kümmerten sich Entwickler um Software und die Operations-Teams um die Hardware und die Betriebssysteme, die darauf liefen.

Jetzt steht die Hardware in der Cloud und alles ist mehr oder weniger Software. Die DevOps-Bewegung bringt nun Softwareentwickler-Fähigkeiten nach Operations: Tools und Abläufe für das schnelle, agile, gemeinsame Bauen komplexer Systeme. Untrennbar mit DevOps verbunden ist dabei die Idee von Infrastruktur als Code.

Statt Computer und Switches physisch aufeinanderzustapeln und miteinander zu verkabeln, lässt sich Cloud-Infrastruktur automatisch durch Software provisionieren. Statt Hardware manuell zu deployen und zu aktualisieren, sind Operations-Techniker zu den Leuten geworden, die die Software zum Automatisieren der Cloud schreiben.

Dabei handelt es sich nicht um eine Einbahnstraße. Entwickler lernen von Operations-Teams, wie man Fehler und Probleme bei verteilten, cloudbasierten Systemen vorhersieht, ihre Folgen minimiert und wie man Software entwirft, die möglichst nur teilweise ausfällt und sicher zum Halten kommt.

1.2.4Gemeinsames Lernen

Sowohl Entwicklungs- wie auch Operations-Teams lernen dabei, zusammenzuarbeiten. Sie lernen, wie man Systeme entwirft und baut, wie man im Produktivumfeld Systeme überwacht und Feedback bekommt und wie man mit diesen Informationen die Systeme verbessert. Noch wichtiger ist dabei, dass die Teams lernen, wie sie die User Experience verbessern und für das Business mehr Wert erzeugen, das sie bezahlt.

Die schiere Größe der Cloud und die kollaborative, Code-zentrierte Natur der DevOps-Bewegung haben Operations zu einem Software-Problem werden lassen. Gleichzeitig wurde Software zu einem Operations-Problem, was zusammen zu diesen Fragen führt:

Wie deployen und aktualisieren Sie Software über große, gemischte Netzwerke hinweg mit unterschiedlichen Server-Architekturen und Betriebssystemen?

Wie deployen Sie in verteilte Umgebungen auf zuverlässige und reproduzierbare Art und Weise mit größtenteils standardisierten Komponenten?

Hier betritt die dritte Revolution die Bühne: Container.

1.3Das Aufkommen von Containern

Um eine Software zu deployen, brauchen Sie nicht nur sie selbst, sondern auch ihre Abhängigkeiten (Dependencies). Das sind Bibliotheken, Interpreter, Unterpakete, Compiler, Extensions und so weiter.

Außerdem brauchen Sie die Konfiguration der Software: Einstellungen, Sitespezifische Details, Lizenzschlüssel, Datenbankpasswörter – alles, was die rohe Software in einen nützlichen Service verwandelt.

1.3.1State of the Art

Frühere Versuche, dieses Problem zu lösen, griffen auf Systeme zum Konfigurationsmanagement zurück, wie zum Beispiel Puppet oder Ansible, die Code zum Installieren, Ausführen, Konfigurieren und Aktualisieren der auszuliefernden Software enthielten.

Alternativ bringen einige Sprachen ihre eigenen Paket-Mechanismen mit, wie zum Beispiel die JAR-Dateien von Java, die Eggs von Python oder die Gems bei Ruby. Aber das sind sprachspezifische Dinge und sie lösen das Abhängigkeitsproblem noch nicht ganz – immer noch ist zum Beispiel eine installierte Java Runtime notwendig, um eine JAR-Datei ausführen zu können.

Eine andere Lösung ist das Omnibus Package, das (wie der Name schon andeutet) versucht, alles für die Anwendung Notwendige in eine einzige Datei zu stecken. Ein Omnibus Package enthält die Software, ihre Konfiguration, die abhängigen Software-Komponenten, deren Konfiguration, deren Abhängigkeiten und so weiter. (So würde ein Java Omnibus Package zum Beispiel die Java Runtime und alle für die Anwendung nötigen JAR-Dateien enthalten.)

Manche Hersteller sind sogar noch einen Schritt weitergegangen und haben das gesamte Computersystem mit aufgenommen, das zum Ausführen erforderlich ist – in einem Virtual Machine Image, aber diese sind groß und unhandlich, kosten Zeit beim Bauen und Warten, lassen sich nur schwierig betreiben, langsam herunterladen und deployen und sind in Bezug auf Performance und Ressourcenverbrauch sehr ineffizient.

Aus Sicht von Operations müssen Sie nicht nur diese verschiedenen Arten von Paketen verwalten, sondern sich auch noch um eine ganze Armada von Servern kümmern, auf denen sie laufen.

Server müssen provisioniert werden, man muss sie korrekt ins Netz hängen, konfigurieren, mit Sicherheits-Patches aktuell halten, monitoren, managen und so weiter.

Das kostet alles deutlich Zeit, Skills und Aufwand – nur um eine Plattform bereitzustellen, auf der die Software laufen kann. Gibt es da keine bessere Möglichkeit?

1.3.2Innerhalb der Box denken

Um diese Probleme zu lösen, hat sich die Tech-Branche eine Idee aus der Schifffahrt abgeschaut: die Container. In den 1950ern hat ein Truckfahrer namens Malcolm McLean vorgeschlagen (https://hbswk.hbs.edu/item/the-truck-driver-who-reinvented-shipping), nicht mehr aufwendig Güter einzeln in den Häfen aus den LKW-Anhängern zu holen und auf die Schiffe zu verladen, sondern die LKWs selbst auf die Schiffe zu laden – oder eher die LKW-Rümpfe.

Ein LKW-Anhänger ist nicht viel mehr als eine große Metallbox auf Rädern. Wenn Sie die Box – den Container – von den Rädern und dem Chassis trennen können, auf denen er transportiert wurde, haben Sie etwas, das sich sehr leicht heben, verladen, stapeln und entladen lässt, und Sie können es direkt auf ein Schiff oder am anderen Ende der Reise auf einen anderen LKW verladen (Abbildung 1–3).

McLeans Container-Reederei Sea-Land wurde mit diesem System sehr erfolgreich, weil die Güter viel billiger transportiert werden konnten, und Container setzten sich schnell durch (https://www.freightos.com/the-history-of-the-shipping-Container). Heutzutage werden jedes Jahr über einhundert Millionen Container verschifft, in denen sich Güter im Wert vieler Billionen Dollar befinden.

Abb. 1–3Standardisierte Container haben die Kosten für den Transport von Massengütern drastisch gesenkt. (Foto von Pixabay [https://www.pexels.com/@pixabay], lizensiert unter Creative Commons 2.0)

1.3.3Software in Containern verpacken

Der Software-Container verfolgt genau die gleiche Idee: ein standardisiertes Paket- und Distributionsformat, generisch und weitverbreitet, das eine deutlich verbesserte Nutzlast besitzt, geringere Kosten hat, gut skalierbar ist und sich leicht handhaben lässt. Das Container-Format enthält alles, was die Anwendung zur Ausführung benötigt, verpackt in einer Image-Datei, die von einer Container Runtime ausgeführt werden kann.

Wie unterscheidet sich das von einem Image einer virtuellen Maschine? Auch dort ist alles enthalten, was die Anwendung zu ihrer Ausführung benötigt – aber noch viel mehr. Ein klassisches VM-Image ist etwa 1 GiB groß.1 Ein gut designtes Container-Image kann andererseits hundertmal kleiner sein.

Weil die virtuelle Maschine viele Programme, Bibliotheken und andere Dinge enthält, die die Anwendung niemals nutzen wird, ist viel von dem Platz verschwendet. Das Übermitteln von VM-Images über das Netz dauert viel länger als bei optimierten Containern.

Noch schlimmer ist, dass virtuelle Maschinen virtuell sind: Die genutzte reale CPU implementiert letztendlich eine emulierte CPU, auf der dann die virtuelle Maschine läuft. Die Virtualisierungs-Schicht hat einen dramatischen negativen Effekt auf die Performance (https://www.stratoscale.com/blog/Containers/running-Containers-on-bare-metal): In Tests laufen virtualisierte Aufgaben ungefähr 30% langsamer als in entsprechenden Containern.

Container laufen hingegen direkt auf der realen CPU ohne Virtualisierungs-Overhead, so wie die normalen Binaries.

Und weil Container nur die Dateien beinhalten, die sie benötigen, sind sie viel kleiner als VM-Images. Zudem nutzen sie eine clevere Technik von Dateisystem-Layern, die sich direkt ansprechen lassen und von mehreren Containern gemeinsam genutzt und wiederverwendet werden können.

Wenn Sie zum Beispiel zwei Container haben, die beide vom gleichen Debian-Linux-Basis-Image abgeleitet sind, muss das Basis-Image nur einmal heruntergeladen werden und jeder Container kann dann einfach darauf verweisen.

Die Container Runtime wird alle notwendigen Layer zusammenführen und nur die herunterladen, die noch nicht lokal gecacht sind. Das sorgt für einen sehr effizienten Einsatz des Plattenplatzes und der Netzwerk-Bandbreite.

1.3.4Plug-and-Play-Anwendungen

Der Container ist nicht nur die Deployment-Einheit und die Verpackungs-Einheit: Sie ist auch die Einheit, die wiederverwendet wird (das gleiche Container-Image kann als Komponente für viele verschiedene Services genutzt werden), die Skalierungs-Einheit und die Einheit zur Ressourcen-Anforderung (ein Container kann überall dort laufen, wo ausreichend Ressourcen für seine spezifischen Anforderungen vorhanden sind).

Entwickler müssen sich nicht mehr darum kümmern, dass verschiedene Versionen der Software auf unterschiedlichen Linux-Distributionen gegen unterschiedliche Bibliotheken und Sprachversionen und so weiter laufen. Der Container hängt nur noch vom Betriebssystem-Kernel ab (zum Beispiel Linux).

Stellen Sie Ihre Anwendung einfach in einem Container-Image zur Verfügung, dann wird sie auf jeder Plattform laufen, die das Standard-Container-Format unterstützt und einen kompatiblen Kernel besitzt.

Die Kubernetes-Entwickler Brendan Burns und David Oppenheimer haben es in ihrem Artikel »Design Patterns for Container-based Distribution Systems« (https://www.usenix.org/node/196347) wie folgt beschrieben:

Indem sie hermetisch abgeschlossen sind, ihre Abhängigkeiten bei sich haben und ein atomares Deployment-Signal bieten (»erfolgreich«/»fehlerhaft«), verbessern Container den bisherigen State of the Art des Deployens von Software im Datacenter oder in der Cloud. Aber Container haben das Potenzial, viel mehr als nur eine bessere Deployment-Möglichkeit zu sein – wir glauben, dass sie dafür bestimmt sind, das Äquivalent zu Objekten in objektorientierten Software-Systemen zu werden und damit die Entwicklung von Entwurfsmustern für verteilte Systeme zu ermöglichen.

1.4Das Container-Orchester dirigieren

Auch Operations-Teams stellen fest, dass ihre Arbeit durch Container deutlich einfacher wird. Statt einen stetig wachsenden Maschinenpark mit verschiedensten Typen, Architekturen und Betriebssystemen zu betreuen, müssen sie nur einen Container-Orchestrierer laufen lassen – eine Software, die dazu entworfen wurde, verschiedene Maschinen in einem Cluster zusammenzuführen: einer Art vereinheitlichtes Rechen-Substrat, das für den Anwender als ein sehr leistungsfähiger Computer erscheint, auf dem Container ausgeführt werden können.

Die Begriffe Orchestrieren und Scheduling werden häufig mehr oder weniger gleich genutzt. Streng genommen bedeutet Orchestrieren in diesem Kontext das Koordinieren und Sequenzieren verschiedener Aktivitäten, um ein gemeinsames Ziel zu erreichen (wie die Musiker in einem Orchester). Scheduling bedeutet, die verfügbaren Ressourcen zu verwalten und Workloads dorthin zuzuweisen, wo sie am effizientesten ausgeführt werden können. (Verwechseln Sie das nicht mit dem Scheduling im Sinne von Scheduled Jobs, die zu vorgegebenen Zeiten ausgeführt werden.)

Eine dritte wichtige Aktivität ist das Cluster Management: Dabei werden mehrere reale oder virtuelle Server in einer einheitlichen, zuverlässigen, fehlertoleranten und scheinbar nahtlosen Gruppe zusammengeführt.

Der Begriff des Container-Orchestrierers bezieht sich meist auf einen einzelnen Service, der sich um Scheduling, Orchestrieren und Cluster Management kümmert.

Das Containerisieren (der Einsatz von Containern als Standard-Methode beim Deployen und Ausführen von Software) hat viele offensichtliche Vorteile gebracht und ein De-facto-Standard-Container-Format ermöglichte eine Reihe von Skaleneffekten. Aber ein Problem stand der umfassenden Übernahme von Containern noch im Weg: das Fehlen eines Standard-Orchestrierungs-Systems für Container.

Solange viele verschiedene Tools für das Scheduling und Orchestrieren von Containern im Markt in Konkurrenz standen, hielten sich Unternehmen dabei zurück, auf eine bestimmte Technologie zu setzen. Aber das hat sich geändert.

1.5Kubernetes

Google hat Container im großen Maßstab für produktive Workloads schon lange vor irgendjemand anderem eingesetzt. So gut wie alle Services bei Google laufen in Containern: Gmail, Google Search, Google Maps, Google App Engine und so weiter. Weil es damals kein passendes Container-Orchestrierungs-System gab, musste Google eben selbst eines erfinden.

1.5.1Von Borg zu Kubernetes

Um das Problem zu lösen, sehr viele Services im globalen Maßstab auf Millionen von Servern laufen zu lassen, hat Google ein privates, internes Container-Orchestrierungs-System namens Borg entwickelt (https://pdos.csail.mit.edu/6.824/papers/borg.pdf).

Borg ist im Prinzip ein zentralisiertes Management-System, das Container auf einem Server-Pool allokiert und schedult. Es ist zwar sehr leistungsfähig, aber eng mit Googles eigenen internen und proprietären Technologien verbunden, lässt sich nur schlecht erweitern und unmöglich der Öffentlichkeit zur Verfügung stellen.

2014 hat Google ein Open-Source-Projekt namens Kubernetes begründet (vom griechischen Wort κυβερνήτης, »Steuermann« oder »Pilot«, abgeleitet), in dem ein Container-Orchestrierer entwickelt werden sollte, der von jedem eingesetzt werden kann und in das die Erfahrungen aus Borg und seinem Nachfolger Omega einfließen (https://storage.googleapis.com/pub-tools-public-publication-data/pdf/41684.pdf).

Kubernetes’ Aufstieg war kometenhaft. Es gab zwar schon vor Kubernetes andere Container-Orchestrierungs-Systeme, aber bei diesen handelte es sich um kommerzielle Produkte, die mit einem Hersteller verbunden waren, was immer eine Hürde für ihre weitreichende Verbreitung darstellte. Mit der Einführung eines wirklich freien und Open-Source-basierten Container-Orchestrierers wurden sowohl Container als auch Kubernetes unglaublich schnell umfassend eingesetzt.

Ende 2017 waren die Orchestrierungs-Kriege beendet und Kubernetes ging als Sieger daraus hervor. Andere Systeme sind zwar immer noch im Einsatz, aber Firmen, die sich überlegen, ihre Infrastruktur in Container zu verlagern, müssen sich nur noch mit einer Plattform befassen: Kubernetes.

1.5.2Was macht Kubernetes so wertvoll?

Kelsey Hightower, Entwickler bei Google, Mitautor von Kubernetes – Eine kompakte Einführung (dpunkt.verlag, https://www.dpunkt.de/buecher/13165/9783864905421-kubernetes.html) und Universal-Legende in der Kubernetes-Community, erklärt es so:

Kubernetes erledigt die Dinge so, wie es die besten Systemadministratoren machen würden: Automatisierung, Failover, zentralisiertes Logging, Monitoring. Was wir in der DevOps-Community gelernt haben, macht es zum Standardverhalten.

– Kelsey Hightower

Viele der klassischen Sysadmin-Aufgaben wie das Aktualisieren von Servern, das Installieren von Sicherheits-Patches, das Konfigurieren von Netzen und das Ausführen von Backups sind in der Cloud-nativen Welt weniger problematisch. Kubernetes kann all diese Dinge für Sie automatisieren, sodass sich Ihr Team darauf konzentrieren kann, seiner eigentlichen Arbeit nachzugehen.

Manche dieser Features, wie zum Beispiel Load Balancing und Autoscaling, sind schon im Kubernetes-Core enthalten. Andere kommen durch Add-Ons, Erweiterungen und Tools von dritter Seite dazu, die die Kubernetes-API verwenden. Das Kubernetes-Ökosystem ist groß und wächst fortlaufend.

Kubernetes erleichtert das Deployen

Ops-Mitarbeiter lieben Kubernetes dafür, aber es gibt auch für Entwickler signifikante Vorteile. Kubernetes reduziert Zeit und Aufwand zum Deployen deutlich. Zero-Downtime-Deployments sind nicht unüblich, weil Kubernetes standardmäßig rollierende Updates durchführt (es startet Container mit der neuen Version, wartet, bis sie wirklich zur Verfügung stehen, und fährt dann die alten herunter).

Kubernetes unterstützt auch das Implementieren von Continuous-Deployment-Praktiken, wie zum Beispiel Canary-Deployments: Dabei werden Updates immer nur auf einem Server gleichzeitig durchgeführt, um Probleme frühzeitig zu erkennen (siehe Abschnitt 13.2.6). Eine andere weitverbreitete Praktik sind Blue/Green-Deployments: Es wird parallel eine neue Version des Systems hochgefahren und der Traffic dorthin umgeleitet, wenn es wirklich läuft (siehe Abschnitt 13.2.4).

Anforderungsspitzen sorgen nicht mehr länger dafür, dass Ihr Service nicht verfügbar ist, weil Kubernetes Autoscaling unterstützt. Wenn zum Beispiel die CPU-Last durch einen Container einen bestimmten Wert erreicht, kann Kubernetes weitere Replicas des Containers hinzufügen, bis die Last wieder unter die Grenze fällt. Sinkt die Anforderung, fährt Kubernetes die Replicas wieder herunter und gibt Cluster-Kapazitäten für andere Workloads frei.

Weil Kubernetes Redundanz und Failover schon eingebaut hat, werden Ihre Anwendungen zuverlässiger und widerstandsfähiger sein. Manche Managed Services können sogar das Kubernetes-Cluster selbst abhängig von den Anforderungen hoch- und runterskalieren, sodass Sie niemals für ein größeres Cluster zahlen, als Sie gerade brauchen (siehe Abschnitt »Autoscaling« auf Seite 112).

Die Finanzabteilung wird Kubernetes ebenfalls lieben, weil es Infrastruktur-Kosten reduziert und die bestehenden Ressourcen besser nutzt. Klassische Server – selbst Cloud-Server – befinden sich den größten Teil der Zeit im Leerlauf. Unter normalen Umständen sind die Kapazitäten verschwendet, die zum Verarbeiten von Anforderungsspitzen notwendig sind.

Kubernetes verwendet diese verschwendete Kapazität, um darauf andere Workloads auszuführen, sodass Sie Ihre Maschinen deutlich besser ausnutzen können – und Sie bekommen noch kostenlos Scaling, Load Balancing und Failover dazu.

Während manche dieser Features, wie etwa Autoscaling, schon vor Kubernetes zur Verfügung standen, waren sie doch immer mit einem bestimmten Cloud-Provider oder Service verbunden. Kubernetes ist Provider-agnostisch: Haben Sie einmal die zu verwendenden Ressourcen definiert, können Sie sie auf jedem Kubernetes-Cluster ausführen – unabhängig vom zugrunde liegenden Cloud-Provider.

Das heißt nicht, dass Kubernetes Sie auf den kleinsten gemeinsamen Nenner beschränkt. Es bildet Ihre Ressourcen auf die passenden anbieterspezifischen Features ab. Zum Beispiel wird ein Kubernetes-Service mit Load Balancing auf der Google Cloud einen Google Cloud Load Balancer erstellen, auf Amazon aber einen AWS Load Balancer. Kubernetes abstrahiert die Cloud-spezifischen Details weg und ermöglicht es Ihnen so, sich auf das Verhalten Ihrer Anwendung zu fokussieren.

So wie Container eine portable Möglichkeit sind, Software zu definieren, bieten Kubernetes-Ressourcen eine portable Definition des Ausführens von Software.

1.5.3Wird Kubernetes wieder verschwinden?

Es mag seltsam klingen, aber trotz der momentanen Begeisterung für Kubernetes werden wir in den kommenden Jahren vielleicht gar nicht mehr viel darüber sprechen. Viele Dinge, die einmal neu und revolutionär waren, sind mittlerweile so sehr Teil des Computer-Alltags, dass wir gar nicht mehr wirklich über sie nachdenken: Mikroprozessoren, die Maus, das Internet.

Kubernetes wird ebenfalls sehr wahrscheinlich aus unserem Sichtfeld verschwinden und einfach Teil der Infrastruktur werden. Es ist langweilig, aber auf gute Art und Weise: Haben Sie einmal gelernt, was Sie zum Deployen Ihrer Anwendung auf Kubernetes wissen müssen, sind Sie mehr oder weniger fertig.

Die Zukunft von Kubernetes liegt vermutlich im Bereich der Managed Services. Virtualisierung, die einmal eine neue und spannende Technologie war, ist mittlerweile einfach ein Werkzeug. Viele Leute mieten virtuelle Maschinen bei einem Cloud-Provider, statt ihre eigene Virtualisierungs-Plattform wie vSphere oder Hyper-V zu betreiben.

Genauso wird unserer Meinung nach Kubernetes so sehr zu einem normalen Bestandteil der Standard-Umgebung werden, dass Sie gar nicht mehr wissen werden, dass es da ist.

1.5.4Kubernetes kann nicht alles

Wird die Infrastruktur der Zukunft vollständig auf Kubernetes basieren? Vermutlich nicht. Erstens, weil manche Dinge nicht gut zu Kubernetes passen (zum Beispiel Datenbanken):

Zum Orchestrieren von Software in Containern gehört das Hochfahren neuer, austauschbarer Instanzen, die sich nicht untereinander koordinieren müssen. Aber Datenbank-Replicas sind nicht austauschbar – sie haben alle einen eindeutigen Status und das Deployen einer Datenbank-Replica erfordert eine Koordination mit den anderen Knoten, um zum Beispiel sicherzustellen, dass Dinge wie Schema-Änderungen überall gleichzeitig durchgeführt werden.

– Sean Loiselle (Cockroach Labs, https://www.cockroachlabs.com/blog/kubernetes-state-of-stateful-apps)

Es ist durchaus möglich, zustandsbehaftete Workloads (wie Datenbanken) in Kubernetes mit einer für eine Produktivumgebung notwendigen Zuverlässigkeit laufen zu lassen, aber dafür ist so viel Zeit und Wissen nötig, dass dies für Ihre Firma nicht unbedingt sinnvoll ist (siehe Abschnitt 3.6.1). Stattdessen ist es im Allgemeinen kosteneffektiver, Managed Services zu verwenden.

Und zweitens ist Kubernetes für manche Dinge gar nicht notwendig, weil sie auf sogenannten Serverless Plattformen laufen können, besser bezeichnet als Functions as a Service oder FaaS-Plattformen.

Cloud-Funktionen und Funtainer

AWS Lambda ist zum Beispiel eine FaaS-Plattform, auf der Sie Code ausführen können, der in Go, Python, Java, Node.js, C# oder anderen Sprachen geschrieben ist, ohne Ihre Anwendung überhaupt kompilieren oder deployen zu müssen. Amazon erledigt all das für Sie.

Weil Sie für die Ausführungszeit in 100-ms-Schritten bezahlen müssen, ist das FaaS-Modell perfekt für Berechnungen, die nur laufen, wenn Sie sie benötigen, statt einen Cloud-Server zu bezahlen, der die ganze Zeit läuft – egal ob Sie Ihn brauchen oder nicht.

Diese Cloud-Funktionen sind in manchen Situationen praktischer als Container (auch wenn manche FaaS-Plattformen auch Container ausführen können). Aber am besten passen sie zu kurzen Standalone-Jobs (AWS Lambda beschränkt Funktionen zum Beispiel auf 15 Minuten Laufzeit und etwa 50 MiB bei deployten Dateien), insbesondere zu solchen, die mit bestehenden Cloud-Rechen-Services zusammenarbeiten, wie zum Beispiel Microsoft Cognitive Services oder die Google Cloud Vision API.

Warum bezeichnen wir dieses Modell nicht gerne als Serverless? Nun, weil es das nicht ist – der Server gehört nur jemand anderem. Entscheidend ist, dass Sie den Server nicht aufbauen und warten müssen, darum kümmert sich der Cloud-Provider.

Nicht jede Workload lässt sich irgendwie sinnvoll auf FaaS-Plattformen ausführen, aber es handelt sich trotzdem sehr wahrscheinlich um eine Schlüssel-Technologie für Cloud-Native-Anwendungen in der Zukunft.

Cloud-Funktionen sind auch nicht auf öffentliche FaaS-Plattformen wie Lambda oder Azure Functions beschränkt: Haben Sie schon ein Kubernetes-Cluster und wollen FaaS-Anwendungen darauf laufen lassen, ermöglichen das OpenFaaS (https://www.openfaas.com) und andere Open-Source-Projekte. Dieser Hybrid aus Funktionen und Containern wird manchmal als Funtainer bezeichnet – ein Name, der uns sehr gut gefällt.

Aktuell wird eine ausgefeiltere Plattform namens Knative zum Bereitstellen von Software für Kubernetes entwickelt, die sowohl Container wie auch Cloud-Funktionen berücksichtigt (siehe Abschnitt 13.1.4). Dies ist ein sehr vielversprechendes Projekt, das vielleicht dazu führt, dass die Grenzen zwischen Containern und Funktionen in Zukunft aufgeweicht werden oder ganz verschwinden.

1.6Cloud Native

Der Begriff Cloud Native hat zunehmend Verbreitung gefunden, wenn man über moderne Anwendungen und Services spricht, die die Vorteile der Cloud, von Containern und Orchestrierung nutzen und oft auf Open-Source-Software basieren.

In der Tat wurde die Cloud Native Computing Foundation (CNCF, https://www.cncf.io) 2015 gegründet, um »eine Community rund um eine Gruppe hochwertiger Projekte zu fördern, die Container als Teil einer Microservices-Architektur orchestriert.«

Als Teil der Linux Foundation will die CNCF Entwickler und Endanwender mit Herstellern zusammenbringen, unter anderem mit den großen öffentlichen Cloud-Providern. Das bekannteste Projekt der CNCF ist Kubernetes selbst, aber die Foundation dient auch als Inkubator und Förderer anderer zentraler Komponenten des Cloud-Native-Ökosystems: Prometheus, Envoy, Helm, Fluentd, gRPC und viele weitere.

Was meinen wir jetzt genau mit Cloud Native? Wie viele solche Dinge hat es für unterschiedliche Leute auch eine unterschiedliche Bedeutung, aber vielleicht gibt es ja einen gemeinsamen Kern.

Cloud-Native-Anwendungen laufen in der Cloud – darüber gibt es keine Diskussionen. Aber einfach nur eine bestehende Anwendung zu nehmen und sie auf einer Recheninstanz in der Cloud laufen zu lassen, macht sie nicht Cloud Native. Genauso wenig geht es darum, sie in einem Container laufen zu lassen oder Cloud Services wie Azures Cosmos DB oder Googles Pub/Sub zu verwenden, auch wenn das durchaus wichtige Aspekte einer Cloud-Native-Anwendung sein können.

Schauen wir uns also ein paar der Eigenschaften von Cloud-Native-Systemen an, denen die meisten Leute zustimmen können:

Automatisierbar

Wenn Anwendungen nicht von Menschen, sondern von Maschinen deployt und verwaltet werden sollen, müssen sie verbreitete Standards, Formate und Schnittstellen erfüllen. Kubernetes bietet diese Standard-Schnittstellen auf eine Art und Weise an, dass Anwendungsentwickler sich gar nicht darum kümmern müssen.

Überall einsetzbar und flexibel

Weil sie von realen Ressourcen wie Festplatten oder spezifischem Wissen über den Rechenknoten entkoppelt sind, auf dem sie laufen werden, können Containerisierte Microservices leicht von einem Knoten auf einen anderen verschoben werden – oder sogar von einem Cluster in ein anderes.

Widerstandsfähig und skalierbar

Klassische Anwendungen tendieren dazu, einzelne Schwachstellen (Single Points of Failure) zu entwickeln: Die Anwendung läuft nicht mehr, wenn ihr Hauptprozess abstürzt, die zugrunde liegende Maschine einen Hardware-Defekt hat oder eine Netzwerk-Ressource überlastet ist. Cloud-Native-Anwendungen lassen sich durch Redundanz und Graceful Degradation hochverfügbar machen, weil sie schon inhärent verteilt sind.

Dynamisch

Ein Container-Orchestrierer wie Kubernetes kann Container so schedulen, dass sie die verfügbaren Ressourcen maximal ausnutzen. Er kann viele Kopien von ihnen laufen lassen, um eine hohe Verfügbarkeit zu erreichen, und rollierende Updates durchführen, um Services still und leise zu aktualisieren, ohne irgendwelchen Traffic zu verlieren.

Observability

Cloud-Native-Anwendungen lassen sich aufgrund ihrer Natur schlechter inspizieren und debuggen. Daher ist eine zentrale Anforderung verteilter Systeme ihre Beobachtbarkeit (Observability): Monitoring, Logging, Tracing und Metriken helfen Entwicklern und Technikern dabei, zu verstehen, was ihre Systeme tun (und warum sie sich falsch verhalten).

Verteilt

Cloud Native ist ein Ansatz zum Bauen und Ausführen von Anwendungen, der sich die Vorteile der verteilten und dezentralisierten Natur der Cloud zunutze macht. Es geht nicht darum, wo Ihre Anwendung läuft, sondern wie sie funktioniert. Statt Ihren Code als einzelne Entität zu deployen (auch als Monolith bekannt), tendieren Cloud-Native-Anwendungen dazu, aus vielen miteinander kooperierenden, verteilten Microservices zusammengesetzt zu sein. Ein Microservice ist einfach ein in sich abgeschlossener Service, der eine Aufgabe erledigt. Bringen Sie genug Microservices zusammen, erhalten Sie eine Anwendung.

Es geht nicht nur um Microservices

Allerdings sind Microservices keine Patentlösung. Monolithen lassen sich leichter verstehen, weil sich alles an einem Platz befindet, und Sie können die Interaktionen der verschiedenen Teile besser verfolgen. Aber es ist schwer, Monolithen zu skalieren – sowohl in Bezug auf den Code selbst als auch auf die Entwickler, die sich darum kümmern. Wächst der Code, wachsen die Interaktionen zwischen den diversen Teilen exponentiell und das System als Ganzes wächst über die Grenzen dessen hinaus, was ein einzelner Mensch verstehen kann.

Eine gut designte Cloud-Native-Anwendung besteht aus Microservices, aber es ist nicht einfach, zu entscheiden, was diese Microservices sein sollen, wo die Grenzen sind und wie die verschiedenen Services miteinander interagieren. Ein gutes Design von Cloud-Native-Services trifft weise Entscheidungen beim Aufteilen der verschiedenen Elemente Ihrer Architektur. Aber auch eine gut designte Cloud-Native-Anwendung ist immer noch ein verteiltes System, wodurch es inhärent komplex ist, sich schlecht beobachten und durchdringen lässt und auf überraschende Art und Weise Fehler produzieren kann.

Während Cloud-Native-Systeme eher verteilt sind, kann man auch monolithische Anwendungen in der Cloud mit Containern laufen lassen und daraus Mehrwert für das Business schaffen. Das kann ein Schritt hin zum graduellen Migrieren von Teilen des Monolithen hin zu modernen Microservices sein, aber auch eine Übergangslösung, während das System für Cloud Native vollständig neu designt wird.

1.7Die Zukunft von Operations

Operations, Infrastructure Engineering und Systemadministration sind hoch qualifizierte Jobs. Werden sie in einer Cloud-Native-Zukunft überflüssig sein? Unserer Meinung nach nicht.

Stattdessen werden diese Fähigkeiten nur noch wichtiger. Das Entwerfen und Verstehen verteilter Systeme ist schwer. Netzwerke und Container-Orchestrierer sind kompliziert. Jedes Team, das Cloud-Native-Anwendungen entwickelt, benötigt Operations-Wissen und -Fähigkeiten. Durch die Automatisierung können sich die Mitarbeiter von langweiligen, sich wiederholenden Aufgaben befreien und mit komplexeren, interessanteren und netteren Problemen befassen, die die Computer selbst noch nicht lösen können.

Das bedeutet nicht, dass alle Operations-Jobs sicher erhalten bleiben werden. Sysadmins konnten im Allgemeinen ohne Programmierkenntnisse auskommen (außer vielleicht für das Zusammenschreiben einfacher Shell-Skripte). In der Cloud reicht das nicht mehr.

In einer durch Software definierten Welt wird die Fähigkeit entscheidend, Software zu schreiben, zu verstehen und zu warten. Wenn Sie sich keine neuen Kenntnisse aneignen wollen oder können, werden Sie zurückbleiben – so wie es schon immer war.

1.7.1Verteiltes DevOps

Statt in einem einzelnen Operations-Team konzentriert zu sein, das andere Teams bedient, wird die Ops-Expertise auf viele Teams verteilt werden.

Jedes Entwicklungs-Team wird mindestens einen Ops-Spezialisten benötigen, der für das Befinden des Systems oder die Services verantwortlich ist, die vom Team bereitgestellt werden. Das wird auch ein Entwickler sein, aber er ist dann der Experte für Networking, Kubernetes, Performance, Resilienz und die Tools und Systeme, die es anderen Entwicklern ermöglichen, ihren Code in die Cloud auszuliefern.

Dank der DevOps-Revolution wird es in den meisten Organisationen keinen Platz mehr für Entwickler geben, die kein Ops beherrschen, oder für Operations-Leute, die nicht programmieren können. Die Unterscheidung zwischen diesen beiden Disziplinen ist obsolet und wird sehr schnell verschwinden. Entwickeln und Betreuen von Software sind nur noch zwei Aspekte der gleichen Aufgabe.

1.7.2Manches wird zentralisiert bleiben

Gibt es Grenzen für DevOps? Oder wird das klassische, zentrale IT- und Operations-Team ganz verschwinden und sich in eine Gruppe vagabundierender interner Berater auflösen, die bei Ops-Themen coachen, lehren und Fehler beheben?

Unserer Meinung nach nicht – oder zumindest nicht vollständig. Manche Dinge sind immer noch zentralisiert von Vorteil. Es ist zum Beispiel nicht sinnvoll, wenn jedes Anwendungs- oder Service-Team seinen eigenen Weg zum Erkennen und Kommunizieren von Produktions-Zwischenfällen hat, oder ein eigenes Ticketing-System oder Deployment-Tools nutzt. Es gibt keinen Grund, wenn jeder das Rad neu erfindet.

1.7.3Developer Productivity Engineering

Wichtig ist, dass Self-Services ihre Grenzen haben. Das Ziel von DevOps ist, Entwicklungs-Teams zu beschleunigen, und nicht, sie mit unnötiger und redundanter Arbeit auszubremsen.

Ja, ein großer Teil der klassischen Operations-Arbeit kann und sollte an andere Teams übergeben werden, vor allem alles, was Code-Deployment und das Reagieren auf Code-bezogene Zwischenfälle betrifft. Aber damit das geschehen kann, muss es ein starkes zentrales Team geben, das das DevOps-Ökosystem aufbaut und unterstützt, in dem alle anderen Teams agieren.

Statt dieses Team Operations zu nennen, mögen wir den Namen Developer Productivity Engineering (DPE). DPE-Teams tun das, was nötig ist, damit die Entwickler ihre Arbeit schneller und besser erledigen können: die Infrastruktur betreuen, Tools bauen, Probleme beheben.

Und während das Developer Productivity Engineering weiterhin ein Bereich für die Spezialisten bleibt, können die Techniker selbst vielleicht in die Organisation ausschwärmen, um diese Expertise dorthin zu bringen, wo sie gebraucht wird.

Der Lyft-Entwickler Matt Klein hat vorgeschlagen, dass ein reines DevOps-Modell für Start-ups und kleine Firmen sinnvoll ist, es aber bei wachsenden Unternehmen eine natürliche Tendenz gibt, Infrastruktur- und Zuverlässigkeits-Experten in einem zentralen Team zu versammeln. Aber er sagt auch, dass dieses Team selbst nicht unbegrenzt wachsen kann: