Dennis Hemeier

Top 10 Kubernetes Features

Wer neu in das Thema Kubernetes einsteigt, der stellt sich schnell die Frage, warum sollte man überhaupt Kubernetes einsetzen. Diese Frage kann je nach Einsatzort und Zweck ganz unterschiedlich beantwortet werden, daher stelle ich heute einmal meine persönliche Top 10 an Kubernetes Features vor, die mir regelmäßig die Arbeit erleichtern.
Top 10 Kubernetes Features

1. Resource Management

Das Thema Resource Management besteht grundlegend aus der Verwaltung der bestehenden Hardware Ressourcen in Form von CPU-Kernen, RAM und Storage. Ziel dabei ist es, die vorhandenen Ressourcen bestmöglich für die bestehenden Anwendungen einzusetzen, ohne das zu viel oder zu wenig Ressourcen bereitsgestellt werden. 

Technisch haben wir mehrere Möglichkeiten, innerhalb von Kubernetes die Ressourcen zu verwalten. Die beiden häufigsten möchte ich an dieser Stelle einmal erwähnen:

Request

Mit der Angabe von Requests innerhalb einer Applikation können wir definieren, wie viele Ressourcen dieser Applikation garantiert zur Verfügung gestellt werden. Diese Angabe können wir also für die Planung der freien Ressourcen innerhalb eines Clusters verwenden. Best Practice ist es hier, diese Werte auf die durchschnittliche Auslastung der jeweiligen Applikation zu setzen.

Limits

Mit Limits können wir in unserer Applikation zusätzlich harte Grenzen festlegen, die nicht überschritten werden können. Somit kann unsere Applikation bei einem plötzlichen Anstiegt der benötigten Ressourcen nicht die anderen auf dem Cluster laufenden Applikationen beeinflussen. In einer normalen Infrasturktur ohne feste Limits würde dieses Verhalten meist zu einem Totalausfall aller Applikationen führen.

2. Health Checks, Liveness Checks

Wir wollen, dass unsere Applikationen immer erreichbar sind. Aus diesem Grund sollte man diese entsprechend mit sogenannten (Health- und Liveness-) Probes ausstatten. Diese sorgen dafür, dass die Applikationen regelmäßig geprüft werden und im Fehlerfall automatisch neu starten.

3. Monitoring und Logging

In diesem Bereich geht es vor allem um einen möglichst ausführlichen Einblick in das Cluster sowie die einfache Anzeige der dort vorhandenen Logs. Im Bereich Monitoring verwende ich meist Prometheus in Verbindung mit Grafana als Open Source Lösung. Hierbei landen alle Metriken des Clusters in einem Prometheus Server, die Anzeige dieser Daten findet anschließend in selbst konfigurierten Grafana-Dashboards statt. Das besonders schöne an dieser Lösung ist, dass nicht nur "Resource Metriken" wie CPU, Memory, etc. angezeigt und gespeichert werden können, sondern auch eigene Applikations-Metriken wie die Anzahl der Requests oder die HTTP-Statuscodes eingebunden werden können.

Monitoring über Grafana
Monitoring über Grafana

Auch im Bereich Logging können verschiedene Anbieter genutzt werden. Für ein einfaches Logging eignet sich z.B. Loki, ein erweitertes Logging wird meist über den klassischen ELK-Stack (Elasticsearch, Logstash, Kibana) realisiert.

4. Neue Applikationen veröffentlichen

Neue Applikationen werden innerhalb von Kubernetes in der Regel über sogenannte Deployments angelegt. Ein Deploymet besteht dabei aus einer Definition der Applikation in Form einer oder mehrerer yaml-Dateien. In diesen Dateien steht die genaue Konfiguration wie das verwendete Image, die festgelegten Resourcen, die Health und Readiness Checks oder weitere Einstellungen. Vorteil hierbei, wir können diese Dateien ohne weiteren Aufwand in unserem Source Control Management System (z.B. Git) ablegen und dort sicher festhalten, wer, wann, welche Applikation erstellt oder bearbeitet hat.

Für häufig verwendete Applikationen gibt es Vorlagen und Tools, die uns die Arbeit weiter erleichtern. Allen voran sei hier Helm als Kubernetes Paket Manager erwähnt. Über Helm lässt sich eine vollständige "Production Ready Applikation" mit nur einem Klick installieren.

5. Config Management

Die saubere Konfiguration einer Applikation gestaltet sich meist schwierig. Wo lege ich den verwendeten API-Key, den Base-Path oder das Debug-Level der Applikation ab, ohne diese Daten direkt in der Applikation hinterlegen zu müssen.

Kubernetes bietet uns genau für diese Themen das Konzept der ConfigMaps und Secrets. Hierbei handelt es sich wie auch bei den Deployments um simple yaml-Dateien, in denen die gesamte Konfiguration abgelegt werden kann. Anschließend können wir diese Konfigurationen z.B. als ENV-Variablen innerhalb der Applikation verwenden. Nachfolgend einmal eine Beispiel ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: my-config
data:
  key: value
  error_reporting: "1"
  debug: "true"
  base_path: https://api.cloudpirate.io
  # multiline support
  ui.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true
    how.nice.to.look=fairlyNice

6. Persistent Storage

Container Storage ist Ephermal. Somit haben wir bei jedem Neustart der Applikation einen "Clean-State" und keine gespeicherten Daten mehr. Natürlich benötigt man für gewisse Applikationen persistenten Storage, der dauerhaft zur Verfügung steht und nicht gelöscht wird, wenn der Container neu startet. Innerhalb von Kubernetes ist dieses Problem sehr elegant gelöst. Auf der einen Seite haben wir die Entwickler, die für Ihre Anwendungen ganz bestimmten Speicher anfragen. Auf der anderen Seite haben wir die Administratoren, die den Speicher zur Verfügung stellen.

Technisch wird dies über Persistent Volume Claims sowie Persistent Volumes implementiert. Ein Claim sagt aus, dass jemand Speicherplatz X benötigt, ein Persistent Volume gibt an, dass es sich hierbei um folgenden Speicher handelt. Somit kann ein Persistent Volume einen Claim erfüllen.

Entscheidend hierbei ist, dass die eigentliche Implementierung des Storage komplett ignoriert werden kann. Denn am Ende zäht nur, dass der Entwickler für seine Applikation 10 GB Storage benötigt. Wo dieser tatsächlich herkommt, ist dabei egal.

Die eigentliche Implementierung kann innerhalb von Kubernetes über viele verschiedene Storage-Provider erfolgen. Als Beispiele seien an dieser Stelle GlusterFS, CephFS, Flocker, iSCSI, NFS, Cinder sowie im Cloud-Context AWSElasticBlockStore, AzureFile, AzureDisk oder GCEPersistentDisk genannt.

7. Einfache Integration in CI/CD Pipelines

Eine neue Applikation zu deployen ist nur die halbe Miete. Viel häufiger wird es aber Änderungen an bestehenden Applikationen geben. Diese Änderungen sollten idealerweise über einen Continous Integration und Continous Delivery Prozess geschehen. Hierbei unterstützt uns Kubernetes mit automatischen Rolling Update und Rollback Prozessen.

Eine Änderung in der Applikation und ein Deployment in Kubernetes löst hierbei einen sogenannten Rollout aus. Die neue Version der Applikation wird gestartet, die bereits zuvor erwähnten Liveness- und Readiness- Checks starten und stellen somit sich, dass die neue Applikation korrekt läuft. Erst wenn dies der Fall ist, geht die neue Version tatsächlich online und die alte Version wird gelöscht.

Deployment Pipeline

8. Backup und Recovery

Auch wenn uns Kubernetes grundlegend viel Absicherung gibt, so sollte natürlich das Thema Backup und Recovery nicht vernachlässigt werden. Speziell in diesem Bereich hat sich die Software Velero als Tool der Wahl herausgestellt. Hiermit ist es möglich, nicht nur Backups des gesamten Clusters zu machen, sondern auch komplette Migrationen zwischen verschiedenen Clustern zu ermöglichen.

Ein persönlich sehr oft genutztes Feature von mir ist, dass man einzelne Applikationen in einem anderen Namespace Wiederherstellen kann und somit technisch eine Kopie einer kompletten Applikation durchführt. In dieser Kopie kann dann - ohne das Live-System zu beeinträchtigen - eine Änderung getestet werden.

Natürlich sind innerhalb von Velero auch zeitbasierte Backups möglich, um z.B. täglich ein Backup des gesamten Clusters oder von Teilen des Clusters durchzuführen.

Velero

9. Networking, DNS, Ingress

Das Networking innerhalb von Kubernetes gestaltet sich sehr einfach. Bereits im Standard sind alle erforderlichen Komponenten vorhanden, um sauber arbeiten zu können. Einzelne Applikationen werden über sogenannte Services intern miteinander verbunden. Beispiel: Wir haben eine Applikation mit dem Namen "backend" und eine MySQL Datenbank mit dem Namen "database". Sofern wir nun für beide Applikationen einen Service angelegt haben, so kann das "backend" ganz einfach mit dem Hostnamen "database" mit der Datenbank kommunizieren. Ein umständliches Verwalten von IP-Adressen oder ähnlichem entfällt vollständig.

Für externen Traffic (meist HTTP / HTTPS) wird in der Regel ein sogenannter Ingress Controller verwendet. Hierbei ist der häufigst verwendete Ingress Controller der NGINX-Ingress-Controller. Dieser erlaubt es uns, innerhalb des Clusters verschiedene Ingress-Ressourcen als yaml-Dateien, welche wir anlegen, zu verwenden. Jede Ingress Rule besteht in der Regel aus den folgenden Angaben:

host: Hostname (vHost) der Website

tls: SSL-Offloading über den Ingress Controller

backend: Welcher Service soll mit diesem Ingress verbunden werden?

Der aktuelle Ingress Controller auf dem ihr euch gerade befindet hier einmal als Beispiel:


apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    ingress.kubernetes.io/ssl-redirect: "true"
    kubernetes.io/tls-acme: "true"
  name: cloudpirate-ingress
  namespace: cloudpirate
spec:
  rules:
  - host: www.cloudpirate.io
    http:
      paths:
      - backend:
          serviceName: cloudpirate
          servicePort: 80
        path: /
  - host: cloudpirate.io
    http:
      paths:
      - backend:
          serviceName: cloudpirate
          servicePort: 80
        path: /
  tls:
  - hosts:
    - www.cloudpirate.io
    - cloudpirate.io
    secretName: cloudpirate-ingress-tls

In Verbindung mit dem Cert Manager kann sehr einfach TLS für die Ingress Ressourcen verwendet werden. Hierzu kann innerhalb des Cert Managers z.B. Let´s Encrypt als Certificate-Authority hinterlegt werden.

10. Infrastruktur Verwaltung und Cluster Upgrades

Da Kubernetes mittlerweile sehr häufig aktualisiert wird, ist natürlich auch das Thema Wartung und Upgrade von bestehenden Kubernetes Clustern wichtig. Vierteljährlich erscheinen neue Minor (1.X.X, 1.Y.Y) Versionen. Beinahe monatlich gibt es neue Patchlevel Versionen.

Über Tools wie kubeadm oder kops gestaltet sich das Upgrade sehr einfach. Mit einem einmal fest definierten Upgrade-Pfad kann somit das Cluster regelmäßig innerhalb von wenigen Minuten ohne Downtime der laufenden Applikationen aktualisiert werden. Somit bleibt mehr Zeit für andere Aufgaben und die System-Administration wird entlastet.