Kubernetes ist eine leistungsstarke Plattform zur Verwaltung containerisierter Anwendungen. Ihre volle Stärke zeigt sich im Zusammenspiel der verschiedenen Ressourcen, die für Betrieb, Skalierung, Speicherung und Netzwerkkommunikation zuständig sind. Jede Ressource erfüllt eine spezifische Aufgabe und trägt dazu bei, Anwendungen stabil, sicher und flexibel bereitzustellen.
Neben Software-Developern und SaaS-Unternehmen - bei denen sich Kubernetes längst etabliert hat - macht es auch für immer mehr Managed-Service-Provider Sinn, moderne Container-Technologien wie Kubernetes in ihr Dienstleistungsangebot aufzunehmen. Der Aufbau einer stabilen, hochverfügbaren Control Plane erfordert jedoch nicht nur fundiertes Know-how in Container-Orchestrierung, sondern bedeutet auch erheblichen Aufwand für Wartung, Sicherheitsupdates und Skalierung. Mit dem Xelon Kubernetes Service erhalten Managed-Service-Provider nun allerdings eine vollständig verwaltete Kubernetes-Lösung, die sich unter eigener Marke weiterverkaufen lässt.
⚠️Gut zu wissen: Technisch bietet der Xelon Kubernetes Service vollständigen Zugriff auf die Kubernetes-API. Über eine REST-Schnittstelle lässt sich die Plattform in bestehende Systeme integrieren. Mit dem Xelon Kubernetes Service laufen sämtliche Kundendaten und Anwendungen in Schweizer Rechenzentren und unterstehen dem Schweizer Recht. Dies schliesst Zugriffsmöglichkeiten durch ausländische Gesetze wie den US Cloud Act aus. Gerade für Unternehmen in regulierten Branchen wie Finanzen, Gesundheitswesen oder öffentlicher Verwaltung ist dies ein immer wichtigeres Argument.
In diesem Artikel findet ihr einen umfassenden Überblick über zentrale Kubernetes-Ressourcen. Dazu gehören unter anderem Deployments, Pods, ReplicaSets, Services und Speicherkomponenten wie Persistent Volumes.
Deployment
Ein Deployment in Kubernetes ist eine Ressource, die eine Reihe identischer Pods verwaltet und sicherstellt, dass die gewünschte Anzahl von Replikaten ausgeführt wird, und die Aktualisierungen, Rollbacks und Skalierungen ermöglicht.
Beispiel: Bereitstellen einer Webanwendung mit drei Replikaten und automatisches Ausrollen von Updates, wenn das Container-Image aktualisiert wird.
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app-deployment
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web-app
image: web-app:1.0
ports:
- containerPort: 80
Pods
Ein Pod in Kubernetes stellt das kleinste und einfachste Kubernetes-Objekt dar, es ist eine einzelne Instanz einer laufenden Anwendung.
Beispiel: Ausführen eines einzelnen Webservers in einem Pod.
apiVersion: v1
kind: Pod
metadata:
name: my-web-pod
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
Container
Ein Container ist eine Software und ihre Abhängigkeiten, die in einer virtuellen Umgebung verpackt sind und ausgeführt werden können. Container werden innerhalb eines Pods in Kubernetes verwaltet, siehe Teile des obigen Beispiels:
Beispiel: Dies ist das neueste nginx-Image, das innerhalb eines Pods ausgeführt wird.
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
Ressourcenanforderungen und -grenzen
Ressourcenanforderungen und -limits definieren die Mindest- und Höchstmengen an CPU und Speicher, die ein Container verbrauchen kann. Ressourcenlimits verhindern, dass Knoten überlastet werden, während Ressourcenanforderungen sicherstellen, dass ein Container nur auf einem Knoten mit ausreichenden Ressourcen eingeplant wird.
Beachtet, dass Container nicht gestartet werden, wenn keine Knoten mit den angeforderten Ressourcen verfügbar sind.
ReplicaSets
ReplicaSets stellen sicher, dass eine bestimmte Anzahl von Pod-Replikaten zu jeder Zeit ausgeführt wird.
Beispiel: Erstellen eines ReplicaSets, das 5 Replikate einer Webanwendung ausführt.
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: webapp-replicaset
spec:
replicas: 5
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web-app
image: web-app:1.0
Horizonal Pod Autoscaling
Die horizontale Pod-Autoskalierung ermöglicht die Skalierung von Pods auf der Grundlage der Ressourcennutzung, z. B. der CPU- oder Speichernutzung.
Beispiel: Konfigurieren der automatischen Skalierung für eine Webanwendung auf der Grundlage der CPU-Auslastung.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: webapp-hpa
spec:
maxReplicas: 10
metrics:
- resource:
name: cpu
target:
averageUtilization: 50
type: Utilization
type: Resource
minReplicas: 2
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app-deployment
Persistent Volume
Ein persistentes Volume ist eine von einem Administrator bereitgestellte Speicherressource, die von Pods zum Persistieren von Daten verwendet werden kann. In den meisten Fällen wird das Volume automatisch von einem CSI-Treiber bereitgestellt, so dass eine manuelle Volume-Erstellung nicht erforderlich ist.
Beispiel: Definieren eines PV, das von einem Pod beansprucht werden kann.
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-storage
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
PersistentVolumeClaim
Ein PersistentVolumeClaim ist eine Speicheranforderung, die an ein PersistentVolume gebunden ist. Er wird in erster Linie für die dynamische Bereitstellung von Speichervolumen verwendet.
Beispiel: Anforderung eines 50GB-Volumes für einen Datenbank-Pod.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: database-pv-claim
spec:
storageClassName: xelon-persistent-storage
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
StorageClass
StorageClasses definieren verschiedene Arten von Speicher, die dynamisch bereitgestellt werden können.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: xelon-persistent-storage
provisioner: csi.xelon.ch
reclaimPolicy: Delete
volumeBindingMode: Immediate
Networking
Dieser Abschnitt behandelt die grundlegende Kommunikation zwischen Kubernetes-Komponenten, einschliesslich Pods, Diensten und externen Entitäten.
Dienste
Es gibt verschiedene Arten von Diensten, die jeweils eigene Merkmale aufweisen. Alle Diensttypen haben jedoch gemeinsame Merkmale, darunter eine stabile IP-Adresse und einen DNS-Namen für eine ausgewählte Gruppe von Pods.
ClusterIP
ClusterIP ist der gängigste und standardmässige Diensttyp. Er stellt einen Dienst innerhalb des Clusters zur Verfügung und bietet eine IP-Adresse, auf die nur von innerhalb des Clusters zugegriffen werden kann.
apiVersion: v1
kind: Service
metadata:
name: web-app-svc-ci
spec:
selector:
app: web-app
ports:
- protocol: TCP
port: 80
targetPort: 80
NodePort
Der NodePort stellt euren Dienst auf jedem Knoten an einem Port über 30000 zur Verfügung. Er ist nützlich, wenn ihr Dienste direkt in eurem Knotennetzwerk bereitstellen möchten. Dieser Diensttyp wird in der Regel verwendet, wenn eine Firewall mit Lastausgleichsfunktionen vor eurem Cluster steht.
apiVersion: v1
kind: Service
metadata:
name: web-app-svc-np
spec:
selector:
app: web-app
ports:
- port: 80
targetPort: 80
protocol: TCP
type: NodePort
LoadBalancer
Der Diensttyp LoadBalancer ist ein „automatischer“ NodePort. Wenn ihr einen Dienst dieses Typs erstellt, fordert er automatisch einen NodePort an und richtet Weiterleitungsregeln für den LoadBalancer ein. Diese Anfragen werden von der Komponente Cloud-controller-manager bearbeitet. Sie wird häufig verwendet, um Dienste dem World Wide Web zur Verfügung zu stellen.
apiVersion: v1
kind: Service
metadata:
name: web-app-svc-lb
spec:
selector:
app: web-app
ports:
- port: 8000
targetPort: 80
protocol: TCP
type: LoadBalancer
L7 Service Control
Layer 7 Service Control ermöglicht die Verwaltung des Datenverkehrsroutings auf der Anwendungsebene und ermöglicht Funktionen wie URL-basiertes Routing.
Ingress Controller
Der Ingress Controller ist ein veralteter Ansatz (obwohl er immer noch weit verbreitet ist), um den Datenverkehr zu eurer Anwendung zu leiten. Der Ingress Controller selbst ist ein Webserver, der mit Hilfe der Ingress-Ressource dynamisch konfiguriert wird.
Beispiel:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: webapp-ingress
spec:
ingressClassName: cilium
rules:
- host: fqdn.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app-svc-ci
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: web-app-backend-svc-ci
port:
number: 80
GatewayAPI
Die GatewayAPI ist der Nachfolger der Ingress-Ressource. Sie bietet einen stärker standardisierten Ansatz für die Verwaltung von Funktionen wie TLS, gRPC und Sonderfunktionen, die zuvor über Anmerkungen gehandhabt wurden. Letztlich erstellen beide Lösungen eine Konfigurationsdatei für einen Reverse Proxy
Beispiel Gateway:
apiVersion: networking.k8s.io/v1alpha1
kind: Gateway
metadata:
name: webapp-gateway
spec:
gatewayClassName: cilium
listeners:
- protocol: HTTP
port: 80
routes:
kind: HTTPRoute
namespaces:
from: Selector
selector:
matchLabels:
app: web-app
Beispiel HTTPRoute:
apiVersion: networking.k8s.io/v1alpha1
kind: HTTPRoute
metadata:
name: webapp-route
spec:
parentRefs:
- name: webapp-gateway
rules:
- matches:
- path:
type: Prefix
value: /
forwardTo:
- serviceName: web-app-svc-ci
port: 80
- matches:
- path:
type: Prefix
value: /api
forwardTo:
- serviceName: web-app-backend-svc-ci
port: 80
Certificate Manager
Certificate Manager automatisiert die Ausstellung und Erneuerung von TLS-Zertifikaten und implementiert die Funktionalität von Certbot (Let's Encrypt) in Kubernetes. Für weitere Informationen besucht die offizielle Website: cert-manager
Kubernetes DNS
Kubernetes DNS, häufig von CoreDNS implementiert, bietet eine automatische DNS-Auflösung innerhalb des Clusters für alle Pods und Dienste. Es ist von unschätzbarem Wert für den Aufbau skalierbarer Anwendungen, da es den DNS-Lastausgleich und die Zuweisungen übernimmt. In den meisten Fällen müsst ihr innerhalb des Kubernetes-Clusters keine IP-Adressen verwenden, da DNS-Namen immer für die Adressierung verfügbar sind.
Beispiele: Kubernetes DNS in der Praxis
Kommunikation mit demselben Namensraum:
Wenn sich ein Backend und eine Datenbank im selben Namespace befinden, könnt ihr die Datenbank direkt über den Dienstnamen der Datenbank erreichen.
mysql -h <servicename> -u admin -p
# Exmaple with dns records
mysql -h database -u admin -p
Kommunikation zwischen Namespaces:
Wenn ihr ein Backend und eine Datenbank in zwei getrennten Namensräumen haben, könnt ihr die Datenbank über ihren relativen Domänennamen erreichen, der aus besteht:
mysql -h <servicename>.<namespace> -u admin -p
# Exmaple with dns records
mysql -h database.prod -u admin -p
Kommunikation mit voll qualifizierten Domänennamen:
Wenn ihr mehrere Cluster mit weitergeleiteten DNS-Zonen habr, könnt ihr diese über ihre FQDNs erreichen. Wenn ihr es vorzieht, generell FQDNs zu verwenden, können ihr alternativ auch mit den vollständigen Domänennamen auf die Dienste zugreifen. Auf diese Weise können Dienste in verschiedenen Clustern und Netzwerken mit einer standardisierten Namenskonvention ansprechen
mysql mysql -h <servicename>.<namespace>.svc.<cluster-domain> -u admin -p
# Exmaple with dns records
mysql -h database.prod.svc.cluster.local -u admin -p
Namespaces
In Kubernetes ist ein Namespace eine logische Partitionierung von Ressourcen innerhalb eines Clusters. Er hilft bei der Organisation und Isolierung von Ressourcen wie Pods, Diensten und Bereitstellungen und erleichtert so deren Verwaltung und Kontrolle.
Standardmässig trennen Namespaces keine Netzwerke, das heisst Container in verschiedenen Namespaces können weiterhin miteinander kommunizieren.
Der Xelon Kubernetes Service unterstützt Software-Entwickler, SaaS-Unternehmen und Managed-Service-Provider beim Aufbau und dem Betrieb sicherer und hochverfügbarer Applikationen und Microservices. Hier könnt ihr mehr über unseren Kubernetes Service erfahren.