Inhalt | 9 |
Vorwort | 23 |
Der Autor | 24 |
Danksagung zur englischsprachigen Ausgabe | 25 |
Über dieses Buch | 27 |
Zielgruppe | 27 |
Der Aufbau dieses Buches | 28 |
Der Code | 29 |
Das Forum zum Buch | 30 |
Sonstige Onlinequellen | 30 |
Teil I: Überblick | 31 |
1 Einführung in Kubernetes | 33 |
1.1 Der Bedarf für ein System wie Kubernetes | 34 |
1.1.1 Von monolithischen Anwendungen zu Microservices | 34 |
1.1.2 Eine konsistente Umgebung für Anwendungen bereitstellen | 38 |
1.1.3 Übergang zu Continuous Delivery: DevOps und NoOps | 38 |
1.2 Containertechnologien | 40 |
1.2.1 Was sind Container? | 40 |
1.2.2 Die Containerplattform Docker | 44 |
1.2.3 Die Docker-Alternative rkt | 48 |
1.3 Kubernetes | 49 |
1.3.1 Die Ursprünge | 49 |
1.3.2 Kubernetes im Überblick | 49 |
1.3.3 Die Architektur eines Kubernetes-Clusters | 51 |
1.3.4 Anwendungen auf Kubernetes ausführen | 52 |
1.3.5 Vorteile der Verwendung von Kubernetes | 54 |
1.4 Zusammenfassung | 57 |
2 Erste Schritte mit Docker und Kubernetes | 59 |
2.1 Containerimages mit Docker erstellen, ausführen und teilen | 59 |
2.1.1 Docker installieren und einen Hello-world-Container ausführen | 60 |
2.1.2 Eine triviale Node.js-Anwendung erstellen | 62 |
2.1.3 Eine Docker-Datei für das Image erstellen | 63 |
2.1.4 Das Containerimage erstellen | 63 |
2.1.5 Das Containerimage ausführen | 66 |
2.1.6 Das Innenleben eines laufenden Containers untersuchen | 67 |
2.1.7 Container anhalten und entfernen | 69 |
2.1.8 Das Image zu einer Registry hochladen | 69 |
2.2 Kubernetes-Cluster einrichten | 71 |
2.2.1 Einen lokalen Kubernetes-Cluster mit einem Knoten mithilfe von Minikube ausführen | 71 |
2.2.2 Gehostete GKE-Cluster | 73 |
2.2.3 Einen Alias und die Befehlszeilenvervollständigung für kubectl einrichten | 76 |
2.3 Eine erste Anwendung in Kubernetes ausführen | 77 |
2.3.1 Die Node.js-Anwendung bereitstellen | 78 |
2.3.2 Auf die Webanwendung zugreifen | 81 |
2.3.3 Die logischen Bestandteile des Systems | 82 |
2.3.4 Anwendungen horizontal skalieren | 84 |
2.3.5 Auf welchen Knoten läuft die Anwendung? | 87 |
2.3.6 Das Kubernetes-Dashboard | 88 |
2.4 Zusammenfassung | 89 |
Teil II: Grundlagen | 91 |
3 Pods: Container in Kubernetes ausführen | 93 |
3.1 Einführung in Pods | 93 |
3.1.1 Wozu benötigen wir Pods? | 94 |
3.1.2 Grundlagen von Pods | 95 |
3.1.3 Container auf Pods verteilen | 96 |
3.2 Pods aus YAML- und JSON-Deskriptoren erstellen | 99 |
3.2.1 Den YAML-Deskriptor eines bestehenden Pods untersuchen | 99 |
3.2.2 Einen einfachen YAML-Deskriptor für einen Pod schreiben | 101 |
3.2.3 Einen Pod mit kubectl create erstellen | 103 |
3.2.4 Anwendungsprotokolle anzeigen | 104 |
3.2.5 Anforderungen an den Pod senden | 105 |
3.3 Pods mithilfe von Labels ordnen | 106 |
3.3.1 Einführung in Labels | 107 |
3.3.2 Labels beim Erstellen eines Pods angeben | 108 |
3.3.3 Labels vorhandener Pods ändern | 109 |
3.4 Eine Auswahl der Pods mithilfe von Labelselektoren auflisten | 110 |
3.4.1 Pods anhand eines Labelselektors auflisten | 110 |
3.4.2 Labelselektoren mit mehreren Bedingungen | 112 |
3.5 Die Podzuweisung mithilfe von Labels und Selektoren einschränken | 112 |
3.5.1 Labels zur Klassifizierung von Arbeitsknoten | 113 |
3.5.2 Pods bestimmten Knoten zuweisen | 114 |
3.5.3 Zuweisung zu einem einzelnen Knoten | 114 |
3.6 Pods mit Anmerkungen versehen | 115 |
3.6.1 Die Anmerkungen zu einem Objekt einsehen | 115 |
3.6.2 Anmerkungen hinzufügen und ändern | 116 |
3.7 Ressourcen mithilfe von Namespaces gruppieren | 116 |
3.7.1 Der Bedarf für Namespaces | 117 |
3.7.2 Andere Namespaces und die zugehörigen Pods finden | 117 |
3.7.3 Namespaces erstellen | 118 |
3.7.4 Objekte in anderen Namespaces verwalten | 119 |
3.7.5 Die Trennung der Namespaces | 120 |
3.8 Pods stoppen und entfernen | 120 |
3.8.1 Pods unter Angabe des Namens löschen | 120 |
3.8.2 Pods mithilfe von Labelselektoren löschen | 121 |
3.8.3 Pods durch Entfernen eines ganzen Namespaces löschen | 121 |
3.8.4 Alle Pods in einem Namespace löschen und den Namespace erhalten | 122 |
3.8.5 (Fast) alle Ressourcen in einem Namespace löschen | 122 |
3.9 Zusammenfassung | 123 |
4 Replikationscontroller & Co.: Verwaltete Pods bereitstellen | 125 |
4.1 Pods funktionsfähig halten | 126 |
4.1.1 Aktivitätssonden | 126 |
4.1.2 HTTP-Aktivitätssonden erstellen | 127 |
4.1.3 Eine Aktivitätssonde in Aktion | 128 |
4.1.4 Weitere Eigenschaften der Aktivitätssonde festlegen | 129 |
4.1.5 Wirkungsvolle Aktivitätssonden erstellen | 130 |
4.2 Replikationscontroller | 132 |
4.2.1 Die Funktionsweise von Replikationscontrollern | 133 |
4.2.2 Einen Replikationscontroller erstellen | 135 |
4.2.3 Der Replikationscontroller in Aktion | 136 |
4.2.4 Pods in den Gültigkeitsbereich eines Replikationscontrollers bringen und daraus entfernen | 141 |
4.2.5 Das Pod-Template ändern | 144 |
4.2.6 Pods horizontal skalieren | 145 |
4.2.7 Einen Replikationscontroller löschen | 147 |
4.3 Replikationssätze anstelle von Replikationscontrollern verwenden | 148 |
4.3.1 Replikationssätze und Replikationscontroller im Vergleich | 148 |
4.3.2 Einen Replikationssatz definieren | 149 |
4.3.3 Einen Replikationssatz erstellen und untersuchen | 150 |
4.3.4 Die ausdrucksstärkeren Labelselektoren des Replikationssatzes | 151 |
4.3.5 Zusammenfassung: Replikationssätze | 152 |
4.4 Daemonsets zur Ausführung einer Instanz eines Pods auf jedem Knoten | 152 |
4.4.1 Einen Pod auf allen Knoten ausführen | 152 |
4.4.2 Einen Pod nur auf einigen Knoten ausführen | 153 |
4.5 Pods für endliche Aufgaben | 156 |
4.5.1 Jobs | 157 |
4.5.2 Einen Job definieren | 158 |
4.5.3 Ein Job in Aktion | 158 |
4.5.4 Mehrere Podinstanzen in einem Job ausführen | 159 |
4.5.5 Die Zeit zum Abschließen eines Job-Pods begrenzen | 160 |
4.6 Jobs regelmäßig oder zu einem späteren Zeitpunkt ausführen | 161 |
4.6.1 Einen Cron-Job erstellen | 161 |
4.6.2 Die Ausführung geplanter Jobs | 162 |
4.7 Zusammenfassung | 163 |
5 Dienste: Pods finden und mit ihnen kommunizieren | 165 |
5.1 Dienste | 166 |
5.1.1 Dienste erstellen | 167 |
5.1.2 Dienste finden | 173 |
5.2 Verbindungen zu Diensten außerhalb des Clusters | 177 |
5.2.1 Dienstendpunkte | 177 |
5.2.2 Manuell eingerichtete Dienstendpunkte | 178 |
5.2.3 Einen Alias für einen externen Dienst erstellen | 180 |
5.3 Dienste für externe Clients verfügbar machen | 181 |
5.3.1 Einen NodePort-Dienst verwenden | 181 |
5.3.2 Einen Dienst über einen externen Load Balancer verfügbar machen | 185 |
5.3.3 Besondere Eigenschaften von externen Verbindungen | 187 |
5.4 Dienste über eine Ingress-Ressource extern verfügbar machen | 189 |
5.4.1 Eine Ingress-Ressource erstellen | 191 |
5.4.2 Über den Ingress auf den Dienst zugreifen | 192 |
5.4.3 Mehrere Dienste über denselben Domänennamen verfügbar machen | 193 |
5.4.4 Einen Ingress für TLS-Datenverkehr einrichten | 194 |
5.5 Die Bereitschaft eines Pods zur Annahme von Verbindungen signalisieren | 196 |
5.5.1 Bereitschaftssonden | 197 |
5.5.2 Einem Pod eine Bereitschaftssonde hinzufügen | 198 |
5.5.3 Bereitschaftssonden in der Praxis | 200 |
5.6 Headless-Dienste zur Ermittlung einzelner Pods | 202 |
5.6.1 Einen headless-Dienst erstellen | 202 |
5.6.2 Pods über DNS finden | 203 |
5.6.3 Alle Pods finden – auch diejenigen, die nicht bereit sind | 204 |
5.7 Fehlerbehebung bei Diensten | 205 |
5.8 Zusammenfassung | 206 |
6 Volumes: Festplattenspeicher zu Containern hinzufügen | 207 |
6.1 Volumes | 208 |
6.1.1 Ein Beispiel | 208 |
6.1.2 Arten von Volumes | 210 |
6.2 Gemeinsame Datennutzung durch die Container | 211 |
6.2.1 emptyDir-Volumes | 211 |
6.2.2 Ein Git-Repository als Ausgangspunkt für ein Volume verwenden | 214 |
6.3 Zugriff auf Dateien im Dateisystem des Arbeitsknotens | 217 |
6.3.1 HostPath-Volumes | 218 |
6.3.2 Systempods mit hostPath-Volumes | 218 |
6.4 Dauerhafte Speicherung | 220 |
6.4.1 Eine GCE Persistent Disk in einem Pod-Volume | 220 |
6.4.2 Andere Arten von Volumes mit zugrunde liegendem persistenten Speicher | 223 |
6.5 Pods von der zugrunde liegenden Speichertechnologie entkoppeln | 225 |
6.5.1 Persistente Volumes und Claims | 225 |
6.5.2 Ein persistentes Volume erstellen | 226 |
6.5.3 Mit einem Claim ein persistentes Volume beanspruchen | 228 |
6.5.4 Einen Claim in einem Pod verwenden | 230 |
6.5.5 Vorteile der Verwendung von persistenten Volumes und Claims | 231 |
6.5.6 Persistente Volumes wiederverwenden | 232 |
6.6 Persistente Volumes dynamisch bereitstellen | 234 |
6.6.1 Die verfügbaren Speichertypen mit Speicherklassen definieren | 234 |
6.6.2 Die Speicherklasse in einem Claim angeben | 235 |
6.6.3 Dynamische Bereitstellung ohne Angabe einer Speicherklasse | 237 |
6.7 Zusammenfassung | 240 |
7 Konfigurationszuordnungen und Secrets: Anwendungen konfigurieren | 243 |
7.1 Konfiguration von Anwendungen im Allgemeinen | 243 |
7.2 Befehlszeilenargumente an Container übergeben | 245 |
7.2.1 Den Befehl und die Argumente in Docker definieren | 245 |
7.2.2 Den Befehl und die Argumente in Kubernetes überschreiben | 247 |
7.3 Umgebungsvariablen für einen Container einrichten | 249 |
7.3.1 Eine Umgebungsvariable in einer Containerdefinition festlegen | 250 |
7.3.2 Im Wert einer Variablen auf andere Umgebungsvariablen verweisen | 250 |
7.3.3 Die Nachteile hartkodierter Umgebungsvariablen | 251 |
7.4 Die Konfiguration mit einer Konfigurationszuordnung entkoppeln | 251 |
7.4.1 Einführung in Konfigurationszuordnungen | 251 |
7.4.2 Eine Konfigurationszuordnung erstellen | 253 |
7.4.3 Einen Konfigurationseintrag als Umgebungsvariable an einen Container übergeben | 256 |
7.4.4 Alle Einträge einer Konfigurationszuordnung auf einmal als Umgebungsvariablen übergeben | 257 |
7.4.5 Einen Konfigurationseintrag als Befehlszeilenargument übergeben | 258 |
7.4.6 Konfigurationsdateien mithilfe eines configMap-Volumes verfügbar machen | 259 |
7.4.7 Die Konfiguration einer Anwendung ohne Neustart ändern | 265 |
7.5 Sensible Daten mithilfe von Geheimnissen an Container übergeben | 267 |
7.5.1 Einführung in Geheimnisse | 268 |
7.5.2 Das Geheimnis default-token | 268 |
7.5.3 Ein Geheimnis erstellen | 270 |
7.5.4 Unterschiede zwischen Konfigurationszuordnungen und Geheimnissen | 271 |
7.5.5 Das Geheimnis in einem Pod verwenden | 273 |
7.5.6 Geheimnisse zum Abrufen von Images | 277 |
7.6 Zusammenfassung | 278 |
8 Von Anwendungen aus auf Podmetadaten und andere Ressourcen zugreifen | 279 |
8.1 Metadaten über die Downward-API übergeben | 279 |
8.1.1 Die verwendbaren Metadaten | 280 |
8.1.2 Metadaten über Umgebungsvariablen verfügbar machen | 281 |
8.1.3 Metadaten über Dateien in einem downwardAPI-Volume übergeben | 284 |
8.2 Kommunikation mit dem Kubernetes-API-Server | 287 |
8.2.1 Die REST-API von Kubernetes | 288 |
8.2.2 Von einem Pod aus mit dem API-Server kommunizieren | 292 |
8.2.3 Botschaftercontainer zur Vereinfachung der Kommunikation mit dem API-Server | 298 |
8.2.4 Clientbibliotheken zur Kommunikation mit dem API-Server | 300 |
8.3 Zusammenfassung | 303 |
9 Deployments: Anwendungen deklarativ aktualisieren | 305 |
9.1 Anwendungen in Pods aktualisieren | 306 |
9.1.1 Alte Pods löschen und anschließend durch neue ersetzen | 307 |
9.1.2 Neue Pods starten und danach die alten löschen | 307 |
9.2 Automatische schrittweise Aktualisierung mit einem Replikationscontroller | 309 |
9.2.1 Die ursprüngliche Version der Anwendung ausführen | 309 |
9.2.2 Die schrittweise Aktualisierung mit kubectl durchführen | 311 |
9.2.3 Warum ist kubectl rolling-update veraltet? | 315 |
9.3 Deployments zur deklarativen Verwaltung von Anwendungen | 317 |
9.3.1 Ein Deployment erstellen | 317 |
9.3.2 Ein Deployment aktualisieren | 320 |
9.3.3 Eine Bereitstellung zurücknehmen | 324 |
9.3.4 Die Rolloutrate festlegen | 327 |
9.3.5 Den Rolloutvorgang anhalten | 329 |
9.3.6 Das Rollout fehlerhafter Versionen verhindern | 331 |
9.4 Zusammenfassung | 336 |
10 StatefulSets: Replizierte statusbehaftete Anwendungen bereitstellen | 337 |
10.1 Statusbehaftete Pods replizieren | 337 |
10.1.1 Mehrere Replikate mit jeweils eigenem Speicher ausführen | 338 |
10.1.2 Eine unveränderliche Identität für jeden Pod bereitstellen | 339 |
10.2 Statussätze | 341 |
10.2.1 Statussätze und Replikationssätze im Vergleich | 341 |
10.2.2 Unveränderliche Netzwerkidentität | 342 |
10.2.3 Eigenen beständigen Speicher für jede Podinstanz zuweisen | 344 |
10.2.4 Garantien von Statussätzen | 346 |
10.3 Statussätze nutzen | 347 |
10.3.1 Die Anwendung und das Containerimage erstellen | 347 |
10.3.2 Die Anwendung mithilfe eines Statussatzes bereitstellen | 348 |
10.3.3 Die Pods untersuchen | 353 |
10.4 Peers im Statussatz finden | 357 |
10.4.1 Die Peer-Ermittlung über DNS einrichten | 359 |
10.4.2 Einen Statussatz aktualisieren | 360 |
10.4.3 Den Clusterdatenspeicher ausprobieren | 361 |
10.5 Umgang mit Knotenausfällen | 362 |
10.5.1 Die Trennung eines Knotens vom Netzwerk simulieren | 362 |
10.5.2 Den Pod manuell löschen | 364 |
10.6 Zusammenfassung | 366 |
Teil III: Fortgeschrittene Themen | 367 |
11 Interne Mechanismen von Kubernetes | 369 |
11.1 Die Architektur | 369 |
11.1.1 Die verteilte Natur der Kubernetes-Komponenten | 370 |
11.1.2 Verwendung von etcd | 373 |
11.1.3 Aufgaben des API-Servers | 376 |
11.1.4 Benachrichtigungen des API-Servers über Ressourcenänderungen | 378 |
11.1.5 Der Scheduler | 380 |
11.1.6 Die Controller im Controller-Manager | 382 |
11.1.7 Die Rolle des Kubelets | 387 |
11.1.8 Die Rolle des Kubernetes-Dienstproxys | 388 |
11.1.9 Kubernetes-Add-ons | 389 |
11.1.10 Zusammenfassung | 391 |
11.2 Kooperation der Controller | 391 |
11.2.1 Die betroffenen Komponenten | 391 |
11.2.2 Die Abfolge der Ereignisse | 392 |
11.2.3 Clusterereignisse beobachten | 394 |
11.3 Laufende Pods | 395 |
11.4 Das Podnetzwerk | 396 |
11.4.1 Anforderungen an das Netzwerk | 396 |
11.4.2 Funktionsweise des Netzwerks | 398 |
11.4.3 CNI | 400 |
11.5 Implementierung von Diensten | 400 |
11.5.1 Der Kube-Proxy | 400 |
11.5.2 Iptables-Regeln | 401 |
11.6 Cluster mit hoher Verfügbarkeit | 403 |
11.6.1 Anwendungen hochverfügbar machen | 403 |
11.6.2 Die Komponenten der Kubernetes-Steuerebene hochverfügbar machen | 404 |
11.7 Zusammenfassung | 407 |
12 Sicherheit des Kubernetes-API-Servers | 409 |
12.1 Authentifizierung | 409 |
12.1.1 Benutzer und Gruppen | 410 |
12.1.2 Dienstkonten | 411 |
12.1.3 Dienstkonten erstellen | 412 |
12.1.4 Ein Dienstkonto mit einem Pod verknüpfen | 414 |
12.2 Rollengestützte Zugriffssteuerung | 416 |
12.2.1 Das RBAC-Autorisierungs-Plug-in | 416 |
12.2.2 RBAC-Ressourcen | 418 |
12.2.3 Rollen und Rollenbindungen | 421 |
12.2.4 Clusterrollen und Clusterrollenbindungen | 425 |
12.2.5 Standardclusterrollen und -clusterrollenbindungen | 434 |
12.2.6 Berechtigungen bedachtsam gewähren | 436 |
12.3 Zusammenfassung | 437 |
13 Sicherheit der Clusterknoten und des Netzwerks | 439 |
13.1 Die Namespaces des Hostknotens in einem Pod verwenden | 439 |
13.1.1 Den Netzwerknamespace des Knotens in einem Pod verwenden | 440 |
13.1.2 Bindung an einen Hostport ohne Verwendung des Host-Netzwerknamespace | 441 |
13.1.3 Den PID- und den IPC-Namespace des Knotens verwenden | 443 |
13.2 Den Sicherheitskontext eines Containers einrichten | 444 |
13.2.1 Einen Container unter einer bestimmten Benutzer-ID ausführen | 445 |
13.2.2 Die Ausführung eines Containers als root verhindern | 446 |
13.2.3 Pods im privilegierten Modus ausführen | 447 |
13.2.4 Einem Container einzelne Kernelfähigkeiten hinzufügen | 448 |
13.2.5 Fähigkeiten von einem Container entfernen | 450 |
13.2.6 Prozesse am Schreiben im Dateisystem des Containers hindern | 451 |
13.2.7 Gemeinsame Nutzung von Volumes durch Container mit verschiedenen Benutzer-IDs | 452 |
13.3 Die Bearbeitung der Sicherheitsmerkmale in einem Pod einschränken | 454 |
13.3.1 Podsicherheitsrichtlinien | 454 |
13.3.2 Die Richtlinien runAsUser, fsGroup und supplementalGroups | 457 |
13.3.3 Zulässige, unzulässige und Standardfähigkeiten festlegen | 459 |
13.3.4 Die verwendbaren Arten von Volumes einschränken | 460 |
13.3.5 Benutzern und Gruppen unterschiedliche Podsicherheitsrichtlinien zuweisen | 461 |
13.4 Das Podnetzwerk isolieren | 464 |
13.4.1 Die Netzwerkisolierung in einem Namespace aktivieren | 465 |
13.4.2 Einzelnen Pods im Namespace die Verbindung zu einem Serverpod erlauben | 465 |
13.4.3 Das Netzwerk zwischen Kubernetes-Namespaces isolieren | 466 |
13.4.4 Verwendung der CIDR-Schreibweise zur Isolierung | 468 |
13.4.5 Den ausgehenden Datenverkehr von Pods einschränken | 468 |
13.5 Zusammenfassung | 469 |
14 Die Computerressourcen eines Pods verwalten | 471 |
14.1 Ressourcen für die Container eines Pods anfordern | 471 |
14.1.1 Pods mit Ressourcenanforderungen erstellen | 472 |
14.1.2 Einfluss der Ressourcenanforderungen auf die Zuteilung zu Knoten | 473 |
14.1.3 Der Einfluss der CPU-Anforderungen auf die CPU-Zeitzuteilung | 478 |
14.1.4 Benutzerdefinierte Ressourcen definieren und anfordern | 478 |
14.2 Die verfügbaren Ressourcen für einen Container einschränken | 479 |
14.2.1 Harte Grenzwerte für die von einem Container verwendeten Ressourcen festlegen | 479 |
14.2.2 Überschreiten der Grenzwerte | 481 |
14.2.3 Grenzwerte aus der Sicht der Anwendungen in den Containern | 482 |
14.3 QoS-Klassen für Pods | 484 |
14.3.1 Die QoS-Klasse eines Pods festlegen | 484 |
14.3.2 Auswahl des zu beendenden Prozesses bei zu wenig Speicher | 487 |
14.4 Standardanforderungen und -grenzwerte für die Pods in einem Namespace festlegen | 488 |
14.4.1 Der Grenzwertbereich | 489 |
14.4.2 Einen Grenzwertbereich erstellen | 490 |
14.4.3 Die Grenzwerte durchsetzen | 491 |
14.4.4 Standardanforderungen und -grenzwerte anwenden | 492 |
14.5 Die in einem Namespace insgesamt verfügbaren Ressourcen beschränken | 493 |
14.5.1 Ressourcenkontingente | 493 |
14.5.2 Kontingente für persistenten Speicher festlegen | 495 |
14.5.3 Die Höchstzahl der Objekte in einem Namespace beschränken | 496 |
14.5.4 Kontingente für einzelne Podstatus und QoS-Klassen festlegen | 497 |
14.6 Die Ressourcennutzung der Pods überwachen | 498 |
14.6.1 Die tatsächliche Ressourcennutzung erfassen | 498 |
14.6.2 Verlaufsdaten des Ressourcenverbrauchs speichern und analysieren | 500 |
14.7 Zusammenfassung | 504 |
15 Automatische Skalierung von Pods und Clusterknoten | 505 |
15.1 Automatische horizontale Podskalierung | 506 |
15.1.1 Der Vorgang der automatischen Skalierung | 506 |
15.1.2 Skalierung auf der Grundlage der CPU-Nutzung | 509 |
15.1.3 Skalierung auf der Grundlage der Speichernutzung | 516 |
15.1.4 Skalierung auf der Grundlage anderer Messgrößen | 516 |
15.1.5 Geeignete Messgrößen für die automatische Skalierung auswählen | 518 |
15.1.6 Herunterskalieren auf null Replikate | 519 |
15.2 Automatische vertikale Podskalierung | 519 |
15.2.1 Ressourcenanforderungen automatisch einrichten | 519 |
15.2.2 Ressourcenanforderungen von laufenden Pods ändern | 520 |
15.3 Horizontale Skalierung von Clusterknoten | 520 |
15.3.1 Der Cluster-Autoskalierer | 520 |
15.3.2 Den Cluster-Autoskalierer aktivieren | 522 |
15.3.3 Die Unterbrechung von Diensten beim Herunterskalieren des Clusters minimieren | 523 |
15.4 Zusammenfassung | 525 |
16 Erweiterte Planung | 527 |
16.1 Pods mithilfe von Mängeln und Tolerierungen von bestimmten Knoten fernhalten | 527 |
16.1.1 Mängel und Tolerierungen | 528 |
16.1.2 Einem Knoten benutzerdefinierte Mängel hinzufügen | 530 |
16.1.3 Tolerierungen zu Pods hinzufügen | 530 |
16.1.4 Verwendungszwecke für Mängel und Tolerierungen | 531 |
16.2 Knotenaffinität | 532 |
16.2.1 Feste Knotenaffinitätsregeln aufstellen | 533 |
16.2.2 Knotenprioritäten bei der Zuteilung eines Pods | 535 |
16.3 Pods mit Affinitäts- und Antiaffinitätsregeln auf denselben Knoten unterbringen | 538 |
16.3.1 Podaffinitätsregeln zur Bereitstellung von Pods auf demselben Knoten | 539 |
16.3.2 Pods im selben Schaltschrank, in derselben Verfügbarkeitszone oder derselben geografischen Region bereitstellen | 541 |
16.3.3 Präferenzen statt fester Regeln für die Podaffinität angeben | 543 |
16.3.4 Pods mit Antiaffinitätsregeln voneinander getrennt halten | 544 |
16.4 Zusammenfassung | 546 |
17 Best Practices für die Anwendungsentwicklung | 549 |
17.1 Das Gesamtbild | 549 |
17.2 Der Lebenszyklus eines Pods | 551 |
17.2.1 Beendigung und Verlegung von Anwendungen | 551 |
17.2.2 Tote oder teilweise tote Pods neu bereitstellen | 554 |
17.2.3 Pods in einer bestimmten Reihenfolge starten | 555 |
17.2.4 Lebenszyklushooks | 557 |
17.2.5 Pods herunterfahren | 561 |
17.3 Die ordnungsgemäße Verarbeitung aller Clientanforderungen sicherstellen | 565 |
17.3.1 Unterbrechungen von Clientverbindungen beim Hochfahren eines Pods verhindern | 565 |
17.3.2 Unterbrechungen von Clientverbindungen beim Herunterfahren eines Pods verhindern | 565 |
17.4 Einfache Ausführung und Handhabung von Anwendungen in Kubernetes | 570 |
17.4.1 Einfach zu handhabende Containerimages erstellen | 570 |
17.4.2 Images sauber kennzeichnen | 571 |
17.4.3 Mehrdimensionale statt eindimensionaler Labels | 571 |
17.4.4 Ressourcen mit Anmerkungen beschreiben | 572 |
17.4.5 Gründe für die Beendigung eines Prozesses angeben | 572 |
17.4.6 Anwendungsprotokolle | 574 |
17.5 Empfohlene Vorgehensweisen für Entwicklung und Tests | 576 |
17.5.1 Anwendungen während der Entwicklung außerhalb von Kubernetes ausführen | 576 |
17.5.2 Minikube für die Entwicklung | 577 |
17.5.3 Versionssteuerung und Manifeste zur automatischen Bereitstellung von Ressourcen | 579 |
17.5.4 Ksonnet als Alternative zu YAML- und JSON-Manifesten | 579 |
17.5.5 Continuous Integration und Continuous Delivery (CI/CD) | 580 |
17.6 Zusammenfassung | 581 |
18 Kubernetes erweitern | 583 |
18.1 Eigene API-Objekte definieren | 583 |
18.1.1 Eigene Ressourcendefinitionen | 584 |
18.1.2 Benutzerdefinierte Ressourcen mit benutzerdefinierten Controllern automatisieren | 588 |
18.1.3 Benutzerdefinierte Objekte validieren | 592 |
18.1.4 Einen benutzerdefinierten API-Server für benutzerdefinierte Objekte bereitstellen | 592 |
18.2 Kubernetes mit dem Kubernetes-Dienstkatalog erweitern | 594 |
18.2.1 Der Dienstkatalog | 595 |
18.2.2 Der API-Server des Dienstkatalogs und der Controller-Manager | 596 |
18.2.3 Dienstbroker und die API OpenServiceBroker | 597 |
18.2.4 Dienste bereitstellen und nutzen | 598 |
18.2.5 Aufheben der Bindung und der Bereitstellung | 601 |
18.2.6 Vorteile des Dienstkatalogs | 601 |
18.3 Plattformen auf der Grundlage von Kubernetes | 602 |
18.3.1 Die Containerplattform Red Hat OpenShift | 602 |
18.3.2 Deis Workflow und Helm | 605 |
18.4 Zusammenfassung | 608 |
Anhang A: Verwendung von kubectl für mehrere Cluster | 609 |
A.1 Umschalten zwischen Minikube und Google Kubernetes Engine | 609 |
A.1.1 Umschalten zu Minikube | 609 |
A.1.2 Umschalten zu GKE | 609 |
A.2 Verwendung von kubectl für mehrere Cluster oder Namespaces | 610 |
A.2.1 Den Speicherort der Konfigurationsdatei festlegen | 610 |
A.2.2 Der Inhalt der Konfigurationsdatei | 610 |
A.2.3 Konfigurationseinträge auflisten, hinzufügen und ändern | 611 |
A.2.4 Verwendung von kubectl mit verschiedenen Clustern, Benutzern und Kontexten | 613 |
A.2.5 Umschalten zwischen Kontexten | 613 |
A.2.6 Kontexte und Cluster auflisten | 614 |
A.2.7 Kontexte und Cluster löschen | 614 |
Anhang B: Einen Cluster mit mehreren Knoten mit kubeadm erstellen | 615 |
B.1 Das Betriebssystem und die erforderlichen Pakete einrichten | 615 |
B.1.1 Die virtuelle Maschine erstellen | 615 |
B.1.2 Den Netzwerkadapter für die VM einrichten | 616 |
B.1.3 Das Betriebssystem installieren | 617 |
B.1.4 Docker und Kubernetes installieren | 620 |
B.1.5 Die VM klonen | 621 |
B.2 Den Master mit kubeadm konfigurieren | 623 |
B.2.1 Ausführung der Komponenten durch kubeadm | 624 |
B.3 Arbeitsknoten mit kubeadm einrichten | 625 |
B.3.1 Das Containernetzwerk einrichten | 626 |
B.4 Vom lokalen Computer auf den Cluster zugreifen | 627 |
Anhang C: Andere Containerlaufzeitumgebungen verwenden | 629 |
C.1 Docker durch rkt ersetzen | 629 |
C.1.1 Kubernetes zur Verwendung von rkt einrichten | 629 |
C.1.2 rkt in Minikube ausprobieren | 630 |
C.2 Andere Containerlaufzeiten über die CRI verwenden | 632 |
C.2.1 CRI-O | 632 |
C.2.2 Anwendungen in VMs statt in Containern ausführen | 632 |
Anhang D: Clusterverbund | 633 |
D.1 Der Kubernetes-Clusterverbund | 633 |
D.2 Die Architektur | 634 |
D.3 Verbund-API-Objekte | 635 |
D.3.1 Verbundversionen der Kubernetes-Ressourcen | 635 |
D.3.2 Funktionsweise von Verbundressourcen | 636 |
Anhang E: Kubernetes-Ressourcen in diesem Buch | 639 |
Index | 643 |