Cloud-Provisionierung: Kubernetes
1. Zweck
Diese Datei beschreibt, wie du Kubernetes-Cluster in Cloud-Umgebungen provisionierst. Sie ergänzt die lokalen und nativen Umgebungsdokumente um Public-Cloud- und Multi-Cloud-Bereitstellung.
Der Schwerpunkt liegt auf reproduzierbarer Provisionierung für Workshops, Labs und technische Evaluierungen. Du bekommst dafür:
- ein kopierbares Bash-Provisionierungsscript mit Dry-Run-Standard,
- Provider-spezifische CLI-Beispiele für AWS, Azure, Google Cloud und weitere Anbieter,
- Managed-Kubernetes-Varianten wie EKS, AKS, GKE, OKE, DOKS, LKE und IKS,
- selbstverwaltete Varianten auf Cloud-VMs mit kubeadm, k3s, RKE2, k0s und Talos,
- IaC-Pfade mit Terraform/OpenTofu, Pulumi, Cluster API, Crossplane und GitOps,
- Validierung, Troubleshooting, Rückbau und Kostenkontrolle.
Diese Datei ist nicht als blind auszuführendes Produktions-Runbook gedacht. Sie ist ein Workshop- und Architekturleitfaden. Du musst Quotas, Kosten, Netzbereiche, Sicherheitsanforderungen und Organisationsrichtlinien vor jeder echten Ausführung prüfen.
2. Empfehlung
Für die meisten Workshops ist ein verwalteter Kubernetes-Dienst die sauberste Cloud-Variante:
| Ziel | Empfehlung | Begründung |
|---|---|---|
| Schneller Workshop auf AWS | EKS mit eksctl oder Terraform |
Schneller Einstieg, kontrollierbarer Rückbau, gutes Ökosystem. |
| Schneller Workshop auf Azure | AKS mit Azure CLI oder Terraform | Gute Integration mit Resource Groups, Managed Identity, Azure Container Registry und Azure Monitor. |
| Schneller Workshop auf Google Cloud | GKE Autopilot | Wenig Infrastrukturpflege, starke Defaults, Fokus auf Kubernetes-Objekte. |
| Produktionsnaher Clustervergleich | EKS, AKS und GKE jeweils per Terraform | Gleiche Arbeitsweise, vergleichbare Parameter, nachvollziehbarer State. |
| Multi-Cloud-Lifecycle | Cluster API oder Terraform plus GitOps | Deklaratives Flottenmanagement statt manueller Provider-Klickpfade. |
| Cloud-VM-Lab | kubeadm oder k3s auf VMs | Mehr Kontrolle über Control Plane, Runtime, CNI und Node-Betrieb. |
| Edge- oder kleine Cloud-VMs | k3s, RKE2 oder k0s | Schlankere Betriebsmodelle als vollständiges kubeadm-Setup. |
| Immutable OS / starke Härtung | Talos Linux | Betrieb über API statt SSH, klarer Maschinenzustand. |
Wenn du nur Kubernetes-Objekte, Deployments, Services, Probes, RBAC, Ingress und Helm üben willst, nimm Managed Kubernetes. Wenn du Cluster-Bootstrap, Control Plane, etcd, CNI, CSI, kubelet oder Node-Debugging verstehen willst, nimm Cloud-VMs mit kubeadm, k3s, RKE2, k0s oder Talos.
3. Zielbild
Cloud-Provisionierung besteht aus mehreren Ebenen. Ein Kubernetes-Cluster ist nur ein Teil davon.
flowchart TD
Repo[Workshop-Dateien] --> Script[Provisionierungsscript]
Script --> ProviderCLI[Provider CLI]
Script --> IaC[Terraform/OpenTofu oder Pulumi]
ProviderCLI --> Network[Cloud-Netzwerk]
ProviderCLI --> IAM[Identität und Rechte]
ProviderCLI --> Cluster[Managed Kubernetes oder Cloud-VMs]
IaC --> Network
IaC --> IAM
IaC --> Cluster
Cluster --> Kubeconfig[kubeconfig]
Cluster --> Addons[Add-ons]
Addons --> Workloads[Workshop-Workloads]
Workloads --> Validation[Validierung]
Validation --> Cleanup[Rückbau]
Du solltest Cloud-Kubernetes immer als Zusammenspiel aus folgenden Domänen betrachten:
| Domäne | Typische Ressourcen | Fehlerbild bei Vernachlässigung |
|---|---|---|
| Identität | IAM-Rollen, Service Principals, Workload Identity, ServiceAccounts | Cluster kann erstellt werden, aber Nodes oder Add-ons bekommen keine Rechte. |
| Netzwerk | VPC/VNet, Subnetze, Routing, NAT, Security Groups, Firewalls | Nodes joinen nicht, LoadBalancer bleibt ausstehend, Pods erreichen externe Dienste nicht. |
| Cluster | Control Plane, Node Pools, Version, Upgrade-Policy | Version Drift, ungeplante Upgrades, nicht planbare Kapazität. |
| Add-ons | CNI, CSI, DNS, Metrics Server, Ingress Controller, Gateway Controller | Workloads laufen, aber Service Discovery, Storage oder Ingress funktionieren nicht. |
| Betrieb | Logging, Metriken, Alerts, Backup, Audit | Fehler bleiben unsichtbar oder sind nachträglich nicht rekonstruierbar. |
| Sicherheit | RBAC, Pod Security, Secrets, Netzisolation, Image Policies | Labs werden später unabsichtlich als unsichere Blaupause wiederverwendet. |
| Kosten | Tags, Budgets, Quotas, automatische Löschung | Testcluster laufen weiter und verursachen unnötige Kosten. |
4. Entscheidungsmodell
flowchart TD
Start[Du willst Kubernetes in der Cloud provisionieren] --> NeedControl{Willst du Control Plane und Nodes selbst betreiben?}
NeedControl -- Nein --> Managed{Willst du möglichst wenig Node-Betrieb?}
Managed -- Ja --> Auto[Autopilot/Automatic/Auto Mode]
Managed -- Nein --> Standard[Managed Kubernetes mit Node Pools]
NeedControl -- Ja --> VM{Brauchst du volle OS-Kontrolle?}
VM -- Ja --> Kubeadm[kubeadm auf Cloud-VMs]
VM -- Eher schlank --> Dist[k3s/RKE2/k0s/Talos]
Auto --> IaC{Wiederholbar für Teams?}
Standard --> IaC
Kubeadm --> IaC
Dist --> IaC
IaC -- Ja --> Terraform[Terraform/OpenTofu, Pulumi oder Cluster API]
IaC -- Nein --> CLI[Provider CLI für Lab]
4.1 Cloud-Pfade
| Pfad | Beispiel | Du bekommst | Du betreibst selbst | Geeignet für |
|---|---|---|---|---|
| Managed Kubernetes | EKS, AKS, GKE, OKE, DOKS, LKE, IKS | Verwaltete Control Plane, Provider-Integration | Node Pools, Add-ons, Policies, Workloads | Standard-Workshops und produktionsnahe Plattformen. |
| Serverless/Autopilot/Automatic | GKE Autopilot, AKS Automatic, EKS Auto Mode/Fargate | Weniger Node-Management | Policies, Limits, App-Design, Provider-spezifische Einschränkungen | App-orientierte Labs, Kosten-/Ops-Vergleich. |
| VM + kubeadm | EC2, Azure VM, Compute Engine, OCI Compute | Volle Kontrolle über Kubernetes-Komponenten | Alles: OS, Runtime, Control Plane, etcd, CNI, Upgrades | Cluster-Bootstrap, Admin- und Troubleshooting-Labs. |
| VM + k3s/RKE2/k0s | Kleine Cloud-VMs, Edge, Remote-Labs | Vereinfachtes Cluster-Bootstrap | OS, Distribution, Netzwerk, Storage, Add-ons | Leichtgewichtige Umgebungen. |
| Talos | Cloud-VMs mit Talos-Image | Immutable Kubernetes-OS | Talos-Konfiguration, API-Betrieb, Cluster-Lifecycle | Härtung, deklarativer Maschinenbetrieb. |
| kOps | Vor allem AWS, teils weitere Provider | Kubernetes-Cluster plus Cloud-Infrastruktur | kOps-State, Netzwerk, Upgrades | Klassische self-managed Cluster auf AWS. |
| Cluster API | Management-Cluster plus Provider | Deklarative Cluster-Flotte | Management-Cluster, Provider-Controller | Multi-Cluster und Multi-Cloud Lifecycle. |
| Crossplane | Kubernetes als Control Plane für Cloud-Ressourcen | Cloud-Ressourcen über Kubernetes-APIs | Crossplane-Provider, Compositions, RBAC | Plattform-Teams und Self-Service. |
| Terraform/OpenTofu | IaC-State plus Provider | Reproduzierbare Infrastruktur | State, Module, Plan/Apply-Prozess | Standardisierte Provisionierung. |
| Pulumi | IaC in Programmiersprachen | Reproduzierbare Infrastruktur mit Code | Stack State, Secrets, Laufzeit | Teams mit starkem Software-Engineering-Fokus. |
5. Architekturüberblick
5.1 Managed Kubernetes
flowchart LR
Operator[kubectl, Helm, Terraform] --> API[Cloud Provider API]
API --> CP[Verwaltete Kubernetes Control Plane]
API --> NP[Node Pools]
NP --> Nodes[Worker Nodes]
CP --> KubeAPI[Kubernetes API]
KubeAPI --> Addons[Add-ons: DNS, CNI, CSI, Ingress]
Addons --> Apps[Workloads]
Apps --> LB[Cloud Load Balancer]
Apps --> Disk[Cloud Disks]
5.2 Cloud-VMs mit selbstverwaltetem Kubernetes
flowchart TD
Script[Provisionierungsscript] --> VMs[Cloud-VMs]
Script --> Firewall[Security Groups/Firewalls]
Script --> LB[Optionaler API Load Balancer]
VMs --> Runtime[containerd oder Distribution Runtime]
Runtime --> Bootstrap[kubeadm/k3s/RKE2/k0s/Talos]
Bootstrap --> CP[Control Plane]
Bootstrap --> Workers[Worker Nodes]
CP --> Etcd[etcd]
Workers --> Pods[Pods]
Pods --> CNI[CNI]
Pods --> CSI[CSI]
5.3 IaC und GitOps
flowchart TD
Git[Git Repository] --> Plan[Terraform/OpenTofu Plan oder Pulumi Preview]
Plan --> Apply[Apply/Up]
Apply --> Infra[Cloud-Infrastruktur]
Infra --> Cluster[Kubernetes Cluster]
Cluster --> Bootstrap[Bootstrap Namespace]
Bootstrap --> GitOps[Argo CD oder Flux]
GitOps --> Addons[Add-ons]
GitOps --> Apps[Anwendungen]
6. Mindestanforderungen
6.1 Lokaler Arbeitsplatz
Du brauchst mindestens:
- Linux, macOS, WSL2 oder eine Admin-VM,
bash,curl,jq,git,openssl,ssh,tar,unzip,kubectl, passend zur Zielversion des Clusters,helm, wenn du Add-ons installierst,- Provider-CLI für den gewählten Anbieter,
- Zugriff auf ein Cloud-Konto mit Budget und Berechtigungen,
- eine saubere Strategie für Secrets und kubeconfig-Dateien.
6.2 Provider-CLIs
| Provider | CLI | Typischer Zweck |
|---|---|---|
| AWS | aws, eksctl, optional rosa |
EKS, EKS Auto Mode, IAM, VPC, kubeconfig, ROSA. |
| Azure | az |
AKS, Resource Groups, VNets, Managed Identity, kubeconfig. |
| Google Cloud | gcloud |
GKE Autopilot, GKE Standard, IAM, Projekt- und Netzwerkverwaltung. |
| DigitalOcean | doctl |
DOKS, Node Pools, kubeconfig, Load Balancer. |
| Akamai/Linode | linode-cli |
LKE, Node Pools, kubeconfig. |
| Oracle Cloud | oci |
OKE, Compartment, VCN, Node Pools. |
| IBM Cloud | ibmcloud, ks Plugin |
IBM Cloud Kubernetes Service und OpenShift-Cluster. |
| Civo | civo |
Civo Kubernetes. |
| Vultr | vultr-cli |
Vultr Kubernetes Engine. |
| Scaleway | scw |
Scaleway Kapsule/Kosmos. |
| Hetzner | hcloud |
Cloud-VMs für k3s, kubeadm oder Talos; kein klassischer Managed-Kubernetes-Pfad. |
| OVHcloud | ovh oder Terraform |
OVHcloud Managed Kubernetes Service. |
| Alibaba Cloud | aliyun |
ACK. |
| Tencent Cloud | tccli |
TKE. |
6.3 Cloud-Quotas
Prüfe vor dem Workshop:
- vCPU-Limit pro Region,
- Anzahl öffentlicher IPs,
- NAT Gateway oder Egress-Kosten,
- Load-Balancer-Quota,
- Disk-Quota,
- IAM- und Policy-Erstellung,
- verfügbare Kubernetes-Versionen,
- verfügbare VM-Größen,
- erlaubte Regionen,
- Organisationsrichtlinien für öffentliche Endpunkte.
6.4 Versionierung
Pinne Versionen bewusst. Verwende nicht blind latest.
Empfohlene Regeln:
- Für Managed Kubernetes fragst du die unterstützten Versionen pro Provider ab.
- Für kubeadm, k3s, RKE2, k0s und Talos dokumentierst du die Zielversion im Repository.
- Für Terraform/OpenTofu pinnst du Provider- und Modulversionen.
- Für Helm-Charts pinnst du Chart-Version und Image-Tags.
- Für produktionsnahe Labs testest du Upgrade und Rückbau.
Beispiele:
# AWS EKS: verfügbare Add-on- und Versionsinformationen prüfen
aws eks describe-addon-versions --region eu-central-1 | jq '.addons[].addonName' | sort -u
# Azure AKS: verfügbare Versionen je Region prüfen
az aks get-versions --location westeurope -o table
# GKE: verfügbare Versionen je Region prüfen
gcloud container get-server-config --region europe-west3 --format=json | jq '.validMasterVersions[0:5]'
# DigitalOcean Kubernetes: verfügbare Optionen prüfen
doctl kubernetes options versions
# Linode/Akamai LKE: verfügbare Versionen prüfen
linode-cli lke versions-list
7. Sicherheits-, Kosten- und Governance-Regeln
7.1 Kostenregeln
Cloud-Provisionierung erzeugt reale Kosten. Halte dich an diese Regeln:
- Jeder Cluster bekommt Tags/Labels wie
owner,workshop,ttl,environmentundcost-center. - Jeder Lab-Cluster hat einen dokumentierten Rückbaupfad.
- Der Dry-Run ist Standard; echte Ausführung braucht
--execute. - Nutze kleine Node-Größen für Grundlagen-Labs.
- Vermeide NAT Gateways, große Load Balancer, GPU-Nodes und Premium Disks, solange du sie nicht brauchst.
- Setze Budgets und Alerts im Cloud-Konto.
- Räume Load Balancer, Volumes, Snapshots, Public IPs und DNS-Einträge nach dem Cluster-Rückbau explizit auf.
7.2 Sicherheitsregeln
- Keine produktiven Secrets in Workshop-Clustern.
- Keine langfristigen Cloud-Root-Credentials auf Arbeitsstationen.
- Nutze SSO, temporäre Credentials oder Service Principals mit minimalen Rechten.
- kubeconfig-Dateien sind vertraulich zu behandeln.
- Öffentliche Kubernetes-API-Endpunkte müssen bewusst freigegeben und eingeschränkt werden.
- Workload Identity, IRSA, Managed Identity oder vergleichbare Mechanismen sind statischen Cloud-Schlüsseln im Pod vorzuziehen.
- Admin-Rechte werden nicht dauerhaft an Workshop-Teilnehmer verteilt.
- Audit Logging und API-Zugriffe müssen bei produktionsnahen Umgebungen aktiviert werden.
7.3 Governance-Regeln
| Thema | Regel |
|---|---|
| Namensschema | <team>-<zweck>-<provider>-<region>-<nummer> |
| Regionen | Vorab definierte Liste; keine beliebigen Regionen. |
| Tags | Pflicht für Owner, TTL, Umgebung und Kostenstelle. |
| Versionen | Dokumentiert, geprüft, nicht implizit. |
| Netzwerk | CIDR-Kollisionen mit Unternehmensnetzen vermeiden. |
| Zugriff | Rollenbasiert, nicht über gemeinsame Admin-Zugänge. |
| Löschung | Scriptgestützt und validiert. |
8. Werkzeug-Setup
8.1 Basispakete auf Ubuntu/WSL/VM
sudo apt update
sudo apt install -y \
ca-certificates curl gnupg lsb-release git jq unzip tar gzip \
openssh-client openssl make bash-completion
8.2 kubectl installieren
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/kubectl
kubectl version --client
8.3 Helm installieren
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
helm version
8.4 Terraform oder OpenTofu installieren
Beispiel mit Terraform über HashiCorp-Pakete:
sudo apt update
sudo apt install -y gnupg software-properties-common
wget -O- https://apt.releases.hashicorp.com/gpg | \
gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | \
sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update
sudo apt install -y terraform
terraform version
8.5 Provider-CLI-Schnellübersicht
# AWS CLI prüfen
aws --version
aws sts get-caller-identity
# eksctl prüfen
eksctl version
# Azure CLI prüfen
az version
az account show -o table
# Google Cloud CLI prüfen
gcloud version
gcloud auth list
# DigitalOcean CLI prüfen
doctl version
doctl account get
# Linode CLI prüfen
linode-cli --version
linode-cli profile view
# Oracle Cloud CLI prüfen
oci --version
oci iam region list --all
# IBM Cloud CLI prüfen
ibmcloud version
ibmcloud account show
9. Einheitliche Parameter
Für Workshop-Scripts verwendest du einheitliche Variablen. Dadurch kannst du Provider vergleichen, ohne jedes Beispiel komplett umzuschreiben.
export CLOUD_PROVIDER="aws" # aws, azure, gcp, digitalocean, linode, oci, ibm, civo, vultr, scaleway, hetzner
export CLUSTER_MODE="managed" # managed, autopilot, terraform, vm-kubeadm, vm-k3s, vm-rke2, vm-k0s, talos
export CLUSTER_NAME="k8s-workshop-cloud"
export REGION="eu-central-1"
export RESOURCE_GROUP="rg-k8s-workshop"
export PROJECT_ID="my-gcp-project"
export NODE_COUNT="2"
export NODE_SIZE="small"
export K8S_VERSION=""
export OWNER="dein.name@example.com"
export TTL="8h"
export ENVIRONMENT="workshop"
9.1 Mapping typischer Regionen
| Anbieter | Beispielregion Europa | Hinweis |
|---|---|---|
| AWS | eu-central-1 |
Frankfurt. |
| Azure | westeurope oder germanywestcentral |
Region nach Quota und Unternehmensvorgabe wählen. |
| Google Cloud | europe-west3 oder europe-west1 |
Frankfurt oder Belgien. |
| DigitalOcean | fra1, ams3, lon1 |
DOKS-Optionen vorher prüfen. |
| Akamai/Linode | eu-central, eu-west |
Region über linode-cli regions list prüfen. |
| Oracle Cloud | eu-frankfurt-1 |
Compartment- und VCN-IDs erforderlich. |
| IBM Cloud | eu-de |
Zone/Region nach Service prüfen. |
| Civo | FRA1, LON1 |
Region über CLI prüfen. |
| Vultr | fra, ams, lhr |
Region über CLI prüfen. |
| Scaleway | fr-par, nl-ams, pl-waw |
Kapsule-Konfiguration prüfen. |
| Hetzner | fsn1, nbg1, hel1 |
Für VM-basierte Cluster. |
10. Zentrales Provisionierungsscript
Dieses Script ist für Workshops gebaut. Es ist absichtlich defensiv:
- Standard ist Dry-Run.
- Echte Ausführung erfordert
--execute. - Provider-spezifische Abhängigkeiten werden geprüft.
- Kubeconfig wird nach der Provisionierung validiert.
- Rückbau ist explizit über
--action deletemöglich. - Unvollständige Provider-Varianten geben klare Hinweise statt halbfertige Ressourcen anzulegen.
10.1 Beispielaufrufe
# Nur anzeigen, was passieren würde
bash cloud-kubernetes-provision.sh --provider aws --mode managed --cluster workshop-eks
# EKS mit eksctl tatsächlich erstellen
bash cloud-kubernetes-provision.sh \
--provider aws \
--mode managed \
--cluster workshop-eks \
--region eu-central-1 \
--nodes 2 \
--node-size t3.medium \
--execute
# AKS tatsächlich erstellen
bash cloud-kubernetes-provision.sh \
--provider azure \
--mode managed \
--cluster workshop-aks \
--region westeurope \
--resource-group rg-workshop-aks \
--nodes 2 \
--node-size Standard_B2s \
--execute
# GKE Autopilot tatsächlich erstellen
bash cloud-kubernetes-provision.sh \
--provider gcp \
--mode autopilot \
--cluster workshop-gke \
--region europe-west3 \
--project my-gcp-project \
--execute
# DigitalOcean Kubernetes erstellen
bash cloud-kubernetes-provision.sh \
--provider digitalocean \
--mode managed \
--cluster workshop-doks \
--region fra1 \
--nodes 2 \
--node-size s-2vcpu-4gb \
--execute
# Cluster validieren
bash cloud-kubernetes-provision.sh --provider aws --action validate --cluster workshop-eks --region eu-central-1
# Cluster löschen
bash cloud-kubernetes-provision.sh --provider aws --action delete --cluster workshop-eks --region eu-central-1 --execute
10.2 Script
Speichere den folgenden Inhalt als scripts/cloud-kubernetes-provision.sh.
#!/usr/bin/env bash
set -Eeuo pipefail
# Cloud-Kubernetes-Provisionierung für Workshops.
# Standard: Dry-Run. Echte Ausführung nur mit --execute.
ACTION="create"
PROVIDER="${CLOUD_PROVIDER:-aws}"
MODE="${CLUSTER_MODE:-managed}"
CLUSTER_NAME="${CLUSTER_NAME:-k8s-workshop-cloud}"
REGION="${REGION:-eu-central-1}"
RESOURCE_GROUP="${RESOURCE_GROUP:-rg-k8s-workshop}"
PROJECT_ID="${PROJECT_ID:-}"
NODE_COUNT="${NODE_COUNT:-2}"
NODE_SIZE="${NODE_SIZE:-}"
K8S_VERSION="${K8S_VERSION:-}"
OWNER="${OWNER:-unknown}"
TTL="${TTL:-8h}"
ENVIRONMENT="${ENVIRONMENT:-workshop}"
DRY_RUN="true"
log() { printf '[%s] %s\n' "$(date +%H:%M:%S)" "$*"; }
fail() { printf 'FEHLER: %s\n' "$*" >&2; exit 1; }
need() { command -v "$1" >/dev/null 2>&1 || fail "Benötigtes Kommando fehlt: $1"; }
run() {
if [[ "$DRY_RUN" == "true" ]]; then
printf '[dry-run] %s\n' "$*"
else
log "Ausführung: $*"
"$@"
fi
}
usage() {
cat <<'USAGE'
Nutzung:
cloud-kubernetes-provision.sh [Optionen]
Optionen:
--provider <aws|azure|gcp|digitalocean|linode|oci|ibm|civo|vultr|scaleway|hetzner>
--mode <managed|autopilot|terraform|vm-kubeadm|vm-k3s|vm-rke2|vm-k0s|talos>
--action <create|validate|delete|versions|kubeconfig>
--cluster <name>
--region <region>
--resource-group <name> Azure Resource Group
--project <id> Google Cloud Project ID
--nodes <anzahl>
--node-size <größe>
--k8s-version <version>
--owner <name oder e-mail>
--ttl <dauer>
--environment <name>
--execute Dry-Run deaktivieren
-h, --help
Beispiele:
./cloud-kubernetes-provision.sh --provider aws --mode managed --cluster demo
./cloud-kubernetes-provision.sh --provider azure --mode managed --cluster demo --execute
./cloud-kubernetes-provision.sh --provider gcp --mode autopilot --cluster demo --project my-project --execute
USAGE
}
while [[ $# -gt 0 ]]; do
case "$1" in
--provider) PROVIDER="$2"; shift 2 ;;
--mode) MODE="$2"; shift 2 ;;
--action) ACTION="$2"; shift 2 ;;
--cluster) CLUSTER_NAME="$2"; shift 2 ;;
--region) REGION="$2"; shift 2 ;;
--resource-group) RESOURCE_GROUP="$2"; shift 2 ;;
--project) PROJECT_ID="$2"; shift 2 ;;
--nodes) NODE_COUNT="$2"; shift 2 ;;
--node-size) NODE_SIZE="$2"; shift 2 ;;
--k8s-version) K8S_VERSION="$2"; shift 2 ;;
--owner) OWNER="$2"; shift 2 ;;
--ttl) TTL="$2"; shift 2 ;;
--environment) ENVIRONMENT="$2"; shift 2 ;;
--execute) DRY_RUN="false"; shift ;;
-h|--help) usage; exit 0 ;;
*) fail "Unbekannte Option: $1" ;;
esac
done
print_context() {
cat <<EOF
Kontext:
Provider: $PROVIDER
Modus: $MODE
Aktion: $ACTION
Cluster: $CLUSTER_NAME
Region: $REGION
ResourceGroup: $RESOURCE_GROUP
Project: ${PROJECT_ID:-nicht gesetzt}
Nodes: $NODE_COUNT
Node Size: ${NODE_SIZE:-provider-default}
K8s Version: ${K8S_VERSION:-provider-default}
Owner: $OWNER
TTL: $TTL
Environment: $ENVIRONMENT
Dry-Run: $DRY_RUN
EOF
}
common_validate() {
need kubectl
run kubectl cluster-info
run kubectl get nodes -o wide
run kubectl get namespaces
run kubectl get pods -A
}
aws_default_node_size() { [[ -n "$NODE_SIZE" ]] && printf '%s' "$NODE_SIZE" || printf 't3.medium'; }
azure_default_node_size() { [[ -n "$NODE_SIZE" ]] && printf '%s' "$NODE_SIZE" || printf 'Standard_B2s'; }
gcp_default_node_size() { [[ -n "$NODE_SIZE" ]] && printf '%s' "$NODE_SIZE" || printf 'e2-standard-2'; }
do_default_node_size() { [[ -n "$NODE_SIZE" ]] && printf '%s' "$NODE_SIZE" || printf 's-2vcpu-4gb'; }
linode_default_node_size() { [[ -n "$NODE_SIZE" ]] && printf '%s' "$NODE_SIZE" || printf 'g6-standard-2'; }
aws_versions() {
need aws
run aws eks describe-addon-versions --region "$REGION"
}
aws_kubeconfig() {
need aws
run aws eks update-kubeconfig --region "$REGION" --name "$CLUSTER_NAME"
}
aws_create_managed() {
need eksctl
local size; size="$(aws_default_node_size)"
local args=(eksctl create cluster --name "$CLUSTER_NAME" --region "$REGION" --nodes "$NODE_COUNT" --node-type "$size" --managed)
[[ -n "$K8S_VERSION" ]] && args+=(--version "$K8S_VERSION")
args+=(--tags "owner=$OWNER,environment=$ENVIRONMENT,ttl=$TTL")
run "${args[@]}"
aws_kubeconfig
}
aws_create_autopilot() {
need aws
cat <<'INFO'
EKS Auto Mode benötigt mehrere IAM-, Netzwerk- und Cluster-Parameter. Für produktionsnahe Nutzung ist ein separates IaC-Modul empfehlenswert.
Dieses Script führt bewusst keinen halbvollständigen Auto-Mode-Cluster aus. Nutze das AWS-Kapitel in der Markdown-Datei oder Terraform.
INFO
}
aws_delete() {
if command -v eksctl >/dev/null 2>&1; then
run eksctl delete cluster --name "$CLUSTER_NAME" --region "$REGION"
else
need aws
run aws eks delete-cluster --name "$CLUSTER_NAME" --region "$REGION"
fi
}
azure_versions() {
need az
run az aks get-versions --location "$REGION" -o table
}
azure_kubeconfig() {
need az
run az aks get-credentials --resource-group "$RESOURCE_GROUP" --name "$CLUSTER_NAME" --overwrite-existing
}
azure_create_managed() {
need az
local size; size="$(azure_default_node_size)"
run az group create --name "$RESOURCE_GROUP" --location "$REGION" --tags owner="$OWNER" environment="$ENVIRONMENT" ttl="$TTL"
local args=(az aks create --resource-group "$RESOURCE_GROUP" --name "$CLUSTER_NAME" --location "$REGION" --node-count "$NODE_COUNT" --node-vm-size "$size" --generate-ssh-keys --enable-managed-identity --tags owner="$OWNER" environment="$ENVIRONMENT" ttl="$TTL")
[[ -n "$K8S_VERSION" ]] && args+=(--kubernetes-version "$K8S_VERSION")
run "${args[@]}"
azure_kubeconfig
}
azure_create_autopilot() {
need az
cat <<'INFO'
AKS Automatic hat eigene Anforderungen und Optionen, die sich schnell ändern können.
Nutze das AKS-Automatic-Kapitel als Grundlage und prüfe vor der Ausführung die aktuelle Azure-CLI-Hilfe: az aks create --help
INFO
}
azure_delete() {
need az
run az aks delete --resource-group "$RESOURCE_GROUP" --name "$CLUSTER_NAME" --yes --no-wait
}
gcp_versions() {
need gcloud
[[ -n "$PROJECT_ID" ]] && run gcloud config set project "$PROJECT_ID"
run gcloud container get-server-config --region "$REGION" --format=json
}
gcp_kubeconfig() {
need gcloud
[[ -n "$PROJECT_ID" ]] && run gcloud config set project "$PROJECT_ID"
run gcloud container clusters get-credentials "$CLUSTER_NAME" --region "$REGION"
}
gcp_create_managed() {
need gcloud
[[ -n "$PROJECT_ID" ]] && run gcloud config set project "$PROJECT_ID"
local size; size="$(gcp_default_node_size)"
local args=(gcloud container clusters create "$CLUSTER_NAME" --region "$REGION" --num-nodes "$NODE_COUNT" --machine-type "$size" --labels "owner=$OWNER,environment=$ENVIRONMENT,ttl=$TTL")
[[ -n "$K8S_VERSION" ]] && args+=(--cluster-version "$K8S_VERSION")
run "${args[@]}"
gcp_kubeconfig
}
gcp_create_autopilot() {
need gcloud
[[ -n "$PROJECT_ID" ]] && run gcloud config set project "$PROJECT_ID"
local args=(gcloud container clusters create-auto "$CLUSTER_NAME" --region "$REGION" --labels "owner=$OWNER,environment=$ENVIRONMENT,ttl=$TTL")
[[ -n "$K8S_VERSION" ]] && args+=(--cluster-version "$K8S_VERSION")
run "${args[@]}"
gcp_kubeconfig
}
gcp_delete() {
need gcloud
[[ -n "$PROJECT_ID" ]] && run gcloud config set project "$PROJECT_ID"
run gcloud container clusters delete "$CLUSTER_NAME" --region "$REGION" --quiet
}
do_versions() {
need doctl
run doctl kubernetes options versions
}
do_kubeconfig() {
need doctl
run doctl kubernetes cluster kubeconfig save "$CLUSTER_NAME"
}
do_create_managed() {
need doctl
local size; size="$(do_default_node_size)"
local args=(doctl kubernetes cluster create "$CLUSTER_NAME" --region "$REGION" --size "$size" --count "$NODE_COUNT" --tag "owner:$OWNER" --tag "environment:$ENVIRONMENT" --tag "ttl:$TTL")
[[ -n "$K8S_VERSION" ]] && args+=(--version "$K8S_VERSION")
run "${args[@]}"
do_kubeconfig
}
do_delete() {
need doctl
run doctl kubernetes cluster delete "$CLUSTER_NAME" --dangerous --force
}
linode_versions() {
need linode-cli
run linode-cli lke versions-list
}
linode_create_managed() {
need linode-cli
local size; size="$(linode_default_node_size)"
[[ -z "$K8S_VERSION" ]] && fail "Für LKE musst du --k8s-version setzen. Verfügbare Versionen: linode-cli lke versions-list"
run linode-cli lke cluster-create --label "$CLUSTER_NAME" --region "$REGION" --k8s_version "$K8S_VERSION" --node_pools.type "$size" --node_pools.count "$NODE_COUNT" --tags "$ENVIRONMENT" --tags "$OWNER"
cat <<'INFO'
Hinweis: Ermittle danach die Cluster-ID mit:
linode-cli lke clusters-list
und speichere die kubeconfig mit:
linode-cli lke kubeconfig-view <cluster-id> --text | base64 -d > ./kubeconfig-lke.yaml
export KUBECONFIG="$PWD/kubeconfig-lke.yaml"
INFO
}
linode_delete() {
need linode-cli
cat <<'INFO'
LKE-Löschung benötigt die Cluster-ID, nicht nur das Label:
linode-cli lke clusters-list
linode-cli lke cluster-delete <cluster-id>
INFO
}
oci_create_hint() {
need oci
cat <<'INFO'
OKE benötigt Compartment-, VCN- und Subnet-OCIDs. Setze diese Werte bewusst, bevor du Cluster erstellst.
Beispiel:
oci ce cluster create \
--compartment-id "$OCI_COMPARTMENT_ID" \
--name "$CLUSTER_NAME" \
--kubernetes-version "$K8S_VERSION" \
--vcn-id "$OCI_VCN_ID" \
--endpoint-subnet-id "$OCI_ENDPOINT_SUBNET_ID" \
--service-lb-subnet-ids '["ocid1.subnet..."]'
INFO
}
ibm_create_hint() {
need ibmcloud
cat <<'INFO'
IBM Cloud Kubernetes Service verwendet das ks-Plugin. Installiere und prüfe es zuerst:
ibmcloud plugin install container-service
ibmcloud ks cluster versions
ibmcloud ks cluster create --help
INFO
}
terraform_hint() {
need terraform
mkdir -p "generated/$PROVIDER-$CLUSTER_NAME"
cat > "generated/$PROVIDER-$CLUSTER_NAME/README.md" <<EOF
# Terraform-Startpunkt für $PROVIDER / $CLUSTER_NAME
Dieses Verzeichnis wurde als Platzhalter erzeugt. Ergänze Provider-, Netzwerk- und Clusterressourcen passend zum Provider-Kapitel.
Empfohlener Ablauf:
\`\`\`bash
terraform init
terraform fmt -recursive
terraform validate
terraform plan
terraform apply
\`\`\`
EOF
log "Terraform-Startpunkt: generated/$PROVIDER-$CLUSTER_NAME"
}
vm_hint() {
cat <<EOF
Der Modus $MODE benötigt zuerst Cloud-VMs, SSH-Zugriff, Firewall-Regeln und interne IP-Adressen.
Nutze danach das Kapitel zu VM-basierten Cloud-Clustern:
- kubeadm: vollständiger Kubernetes-Bootstrap
- k3s/RKE2/k0s: schlankere Distributionen
- Talos: deklarativer OS- und Cluster-Betrieb
EOF
}
create() {
case "$MODE" in
terraform) terraform_hint ;;
vm-kubeadm|vm-k3s|vm-rke2|vm-k0s|talos) vm_hint ;;
managed)
case "$PROVIDER" in
aws) aws_create_managed ;;
azure) azure_create_managed ;;
gcp) gcp_create_managed ;;
digitalocean) do_create_managed ;;
linode) linode_create_managed ;;
oci) oci_create_hint ;;
ibm) ibm_create_hint ;;
*) fail "Managed-Modus für Provider '$PROVIDER' ist im Script nicht direkt implementiert. Nutze Provider-Kapitel oder Terraform." ;;
esac ;;
autopilot)
case "$PROVIDER" in
aws) aws_create_autopilot ;;
azure) azure_create_autopilot ;;
gcp) gcp_create_autopilot ;;
*) fail "Autopilot/Automatic-Modus ist für '$PROVIDER' nicht definiert." ;;
esac ;;
*) fail "Unbekannter Modus: $MODE" ;;
esac
}
versions() {
case "$PROVIDER" in
aws) aws_versions ;;
azure) azure_versions ;;
gcp) gcp_versions ;;
digitalocean) do_versions ;;
linode) linode_versions ;;
*) log "Keine Versionsabfrage für Provider '$PROVIDER' implementiert. Nutze die Provider-CLI-Hilfe." ;;
esac
}
kubeconfig() {
case "$PROVIDER" in
aws) aws_kubeconfig ;;
azure) azure_kubeconfig ;;
gcp) gcp_kubeconfig ;;
digitalocean) do_kubeconfig ;;
linode) linode_create_managed ;;
*) fail "kubeconfig-Aktion für '$PROVIDER' nicht implementiert." ;;
esac
}
delete() {
case "$PROVIDER" in
aws) aws_delete ;;
azure) azure_delete ;;
gcp) gcp_delete ;;
digitalocean) do_delete ;;
linode) linode_delete ;;
*) fail "Delete-Aktion für '$PROVIDER' nicht implementiert. Nutze Provider-Kapitel und prüfe Restressourcen manuell." ;;
esac
}
print_context
case "$ACTION" in
create) create ;;
validate) common_validate ;;
delete) delete ;;
versions) versions ;;
kubeconfig) kubeconfig ;;
*) fail "Unbekannte Aktion: $ACTION" ;;
esac
10.3 Grenzen des Scripts
Das Script ist ein gemeinsamer Einstiegspunkt, aber keine vollständige Plattform-Engine. Es eignet sich für:
- Workshop-Cluster,
- Demo-Cluster,
- reproduzierbare Lab-Umgebungen,
- Einordnung der Provider-Tools,
- kontrollierte Dry-Runs.
Für produktionsnahe Umgebungen verwendest du stattdessen:
- Terraform/OpenTofu mit Remote State und Review-Prozess,
- Pulumi mit Stack-Konfiguration und Secrets-Backend,
- Cluster API mit Management-Cluster,
- Crossplane mit sauberem Composition-Design,
- GitOps für Add-ons und Workloads,
- dedizierte Security-, Logging-, Backup- und Upgrade-Prozesse.
11. AWS: Amazon EKS und EC2-basierte Varianten
AWS bietet mehrere Kubernetes-Pfade:
| Variante | Werkzeug | Geeignet für |
|---|---|---|
EKS mit eksctl |
eksctl, aws, kubectl |
Schnelle Workshops und reproduzierbare CLI-Labs. |
| EKS mit AWS CLI | aws eks, aws iam, aws ec2 |
Feingranulare Kontrolle, aber deutlich mehr Setup. |
| EKS Auto Mode | aws, Terraform |
Weniger Routinebetrieb für Compute, Storage und Netzwerk. |
| EKS Fargate | eksctl, aws |
Pod-Ausführung ohne eigene Worker Nodes für passende Workloads. |
| EKS mit Terraform/OpenTofu | Terraform AWS Provider, EKS-Module | Teamfähige Infrastruktur mit Review und State. |
| kOps auf AWS | kops, S3-State, Route 53 |
Self-managed Kubernetes plus AWS-Infrastruktur. |
| EC2 + kubeadm | aws, ssh, kubeadm |
Tiefe Admin-Labs mit Control Plane und etcd. |
| EC2 + k3s/RKE2/k0s/Talos | Provider CLI, SSH oder Talos API | Leichtgewichtige oder gehärtete Cluster auf VMs. |
| ROSA | rosa, oc, aws |
Managed OpenShift auf AWS. |
11.1 EKS mit eksctl
eksctl ist für Workshops meistens der schnellste EKS-Pfad.
export AWS_REGION="eu-central-1"
export CLUSTER_NAME="workshop-eks"
aws sts get-caller-identity
eksctl create cluster \
--name "$CLUSTER_NAME" \
--region "$AWS_REGION" \
--nodes 2 \
--node-type t3.medium \
--managed \
--tags owner="$USER",environment=workshop,ttl=8h
aws eks update-kubeconfig \
--region "$AWS_REGION" \
--name "$CLUSTER_NAME"
kubectl get nodes -o wide
Rückbau
eksctl delete cluster \
--name "$CLUSTER_NAME" \
--region "$AWS_REGION"
Prüfe danach Restressourcen:
aws elbv2 describe-load-balancers --region "$AWS_REGION" | jq '.LoadBalancers[].LoadBalancerName'
aws ec2 describe-volumes --region "$AWS_REGION" --filters Name=status,Values=available | jq '.Volumes[].VolumeId'
aws ec2 describe-addresses --region "$AWS_REGION" | jq '.Addresses[].PublicIp'
11.2 EKS mit eksctl-Konfigurationsdatei
Für wiederholbare Labs ist eine YAML-Konfiguration besser als lange CLI-Kommandos.
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: workshop-eks
region: eu-central-1
tags:
owner: workshop
environment: lab
ttl: "8h"
managedNodeGroups:
- name: system
instanceType: t3.medium
desiredCapacity: 2
minSize: 1
maxSize: 3
volumeSize: 40
privateNetworking: true
eksctl create cluster -f eksctl-workshop.yaml
11.3 EKS mit AWS CLI
Der reine AWS-CLI-Pfad ist absichtlich ausführlicher, weil du IAM-Rollen, Netzwerk, Cluster und Node Groups getrennt verwaltest.
Typischer Ablauf:
# 1. IAM-Rolle für die EKS-Control-Plane erstellen.
# 2. VPC, Subnetze, Security Groups und Routing bereitstellen.
# 3. EKS-Cluster erstellen.
# 4. Node Group oder Fargate Profile erstellen.
# 5. kubeconfig schreiben.
# 6. Add-ons prüfen.
Minimaler Cluster-Aufruf, wenn IAM und Netzwerk bereits existieren:
aws eks create-cluster \
--region eu-central-1 \
--name workshop-eks \
--role-arn arn:aws:iam::<account-id>:role/EKSClusterRole \
--resources-vpc-config subnetIds=subnet-a,subnet-b,securityGroupIds=sg-a,endpointPublicAccess=true,endpointPrivateAccess=true
aws eks wait cluster-active \
--region eu-central-1 \
--name workshop-eks
aws eks update-kubeconfig \
--region eu-central-1 \
--name workshop-eks
Node Group:
aws eks create-nodegroup \
--region eu-central-1 \
--cluster-name workshop-eks \
--nodegroup-name system \
--node-role arn:aws:iam::<account-id>:role/EKSNodeRole \
--subnets subnet-a subnet-b \
--scaling-config minSize=1,maxSize=3,desiredSize=2 \
--instance-types t3.medium \
--disk-size 40
11.4 EKS Auto Mode
EKS Auto Mode reduziert Routineaufgaben für Compute, Storage und Networking. Verwende diesen Pfad, wenn du im Workshop stärker App- und Plattformverhalten üben willst und weniger Node-Betrieb zeigen musst.
Prüfpunkte:
- IAM-Rollen und Clusterrolle müssen zum Auto-Mode-Modell passen.
- Networking und Subnetze müssen passend getaggt sein.
- Workload-Anforderungen müssen zu den unterstützten Betriebsgrenzen passen.
- Kostenmodell und automatische Kapazitätsbereitstellung müssen verstanden sein.
11.5 EKS Fargate
EKS Fargate kann Pods ohne eigene EC2-Worker Nodes ausführen. Das ist nützlich für bestimmte Lab- oder isolierte Workloads, aber nicht für alle Kubernetes-Funktionen geeignet.
eksctl create fargateprofile \
--cluster workshop-eks \
--region eu-central-1 \
--name fp-demo \
--namespace demo
11.6 EKS mit Terraform/OpenTofu
Empfohlene Struktur:
infra/aws-eks/
├── versions.tf
├── providers.tf
├── variables.tf
├── network.tf
├── eks.tf
├── outputs.tf
└── terraform.tfvars.example
Beispiel mit Modulansatz:
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 21.0"
name = var.cluster_name
kubernetes_version = var.kubernetes_version
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
eks_managed_node_groups = {
system = {
instance_types = ["t3.medium"]
min_size = 1
max_size = 3
desired_size = 2
}
}
tags = var.tags
}
Ablauf:
terraform init
terraform fmt -recursive
terraform validate
terraform plan -out tfplan
terraform apply tfplan
aws eks update-kubeconfig --region eu-central-1 --name workshop-eks
kubectl get nodes -o wide
11.7 kOps auf AWS
kOps eignet sich, wenn du einen selbstverwalteten Kubernetes-Cluster auf AWS bauen willst und kOps die AWS-Infrastruktur mitverwalten soll.
export KOPS_STATE_STORE=s3://my-kops-state-store
export NAME=workshop.example.com
kops create cluster \
--name "$NAME" \
--zones eu-central-1a,eu-central-1b,eu-central-1c \
--node-count 2 \
--node-size t3.medium \
--control-plane-size t3.medium \
--dns-zone example.com
kops update cluster --name "$NAME" --yes --admin
kops validate cluster --wait 10m
Rückbau:
kops delete cluster --name "$NAME" --yes
11.8 EC2 + kubeadm
Du brauchst mindestens:
- drei EC2-Instanzen für ein kleines HA-Lab oder eine Control Plane plus Worker für ein Grundlagen-Lab,
- Security Groups für SSH, Kubernetes API, kubelet, CNI und Pod-Netzwerk,
- interne DNS-Namen oder feste private IPs,
- optional einen Network Load Balancer vor der Control Plane,
containerd,kubeadm,kubelet,kubectlauf den Nodes.
Bootstrap-Grundmuster:
sudo kubeadm init \
--control-plane-endpoint "api.workshop.internal:6443" \
--pod-network-cidr "10.244.0.0/16" \
--upload-certs
mkdir -p "$HOME/.kube"
sudo cp /etc/kubernetes/admin.conf "$HOME/.kube/config"
sudo chown "$(id -u):$(id -g)" "$HOME/.kube/config"
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
11.9 ROSA
ROSA ist relevant, wenn du OpenShift statt Upstream-Kubernetes auf AWS bereitstellen willst.
Typischer Ablauf:
rosa login
rosa verify quota
rosa create account-roles --mode auto --hosted-cp
rosa create cluster --hosted-cp --cluster-name workshop-rosa --region eu-central-1
rosa describe cluster --cluster workshop-rosa
Für Kubernetes-Workshops ohne OpenShift-Fokus ist EKS meist passender. Für Plattform-Workshops mit OpenShift-Konzepten, Operators, Routes, Security Context Constraints und oc ist ROSA sinnvoll.
12. Azure: AKS und VM-basierte Varianten
Azure bietet für Kubernetes mehrere Hauptpfade:
| Variante | Werkzeug | Geeignet für |
|---|---|---|
| AKS Standard | az aks |
Standard-Workshops, produktionsnahe Cluster, Node Pools. |
| AKS Automatic | Azure CLI, Portal, Terraform je nach Support | App-fokussierte Cluster mit stärkerer Plattformautomatisierung. |
| AKS + ACR | az acr, az aks |
Image-Build- und Deployment-Labs. |
| AKS + Azure CNI Overlay | az aks |
Netzwerknahe Labs mit Azure-Integration. |
| Azure VM + kubeadm | az vm, ssh, kubeadm |
Admin- und Bootstrap-Labs. |
| Azure VM + k3s/RKE2/k0s/Talos | az vm, SSH oder Talos API |
Leichtgewichtige und Spezialvarianten. |
| AKS mit Terraform/OpenTofu | Terraform AzureRM Provider | Reproduzierbarer Team- und Plattformbetrieb. |
| Azure Arc-enabled Kubernetes | az connectedk8s |
Registrierung externer Cluster in Azure. |
12.1 AKS mit Azure CLI
export LOCATION="westeurope"
export RESOURCE_GROUP="rg-workshop-aks"
export CLUSTER_NAME="workshop-aks"
az login
az account show -o table
az group create \
--name "$RESOURCE_GROUP" \
--location "$LOCATION" \
--tags owner="$USER" environment=workshop ttl=8h
az aks create \
--resource-group "$RESOURCE_GROUP" \
--name "$CLUSTER_NAME" \
--location "$LOCATION" \
--node-count 2 \
--node-vm-size Standard_B2s \
--generate-ssh-keys \
--enable-managed-identity \
--tags owner="$USER" environment=workshop ttl=8h
az aks get-credentials \
--resource-group "$RESOURCE_GROUP" \
--name "$CLUSTER_NAME" \
--overwrite-existing
kubectl get nodes -o wide
12.2 AKS mit ACR-Integration
export ACR_NAME="acrworkshop$RANDOM"
az acr create \
--resource-group "$RESOURCE_GROUP" \
--name "$ACR_NAME" \
--sku Basic
az aks update \
--resource-group "$RESOURCE_GROUP" \
--name "$CLUSTER_NAME" \
--attach-acr "$ACR_NAME"
12.3 AKS Node Pools
az aks nodepool add \
--resource-group "$RESOURCE_GROUP" \
--cluster-name "$CLUSTER_NAME" \
--name apps \
--node-count 2 \
--node-vm-size Standard_D2s_v5 \
--labels workload=apps \
--tags owner="$USER" environment=workshop
kubectl get nodes --show-labels
12.4 AKS Automatic
AKS Automatic ist für Szenarien gedacht, in denen du weniger Plattformdetails selbst konfigurieren willst. Prüfe vor einem Workshop die aktuelle CLI-Unterstützung und ob deine Organisation diese Variante erlaubt.
Prüfpunkte:
- Unterstützte Regionen,
- Netzwerkmodell,
- Identitätsmodell,
- erlaubte Add-ons,
- Einschränkungen für Node-Konfiguration,
- Kostenmodell,
- Kompatibilität mit Ingress, Gateway API, CSI und Observability.
12.5 AKS mit Terraform/OpenTofu
resource "azurerm_resource_group" "this" {
name = var.resource_group_name
location = var.location
tags = var.tags
}
resource "azurerm_kubernetes_cluster" "this" {
name = var.cluster_name
location = azurerm_resource_group.this.location
resource_group_name = azurerm_resource_group.this.name
dns_prefix = var.cluster_name
kubernetes_version = var.kubernetes_version
default_node_pool {
name = "system"
node_count = 2
vm_size = "Standard_B2s"
}
identity {
type = "SystemAssigned"
}
tags = var.tags
}
Ablauf:
terraform init
terraform validate
terraform plan -out tfplan
terraform apply tfplan
az aks get-credentials --resource-group rg-workshop-aks --name workshop-aks --overwrite-existing
kubectl get nodes -o wide
12.6 Azure VM + kubeadm
Beispiel für VM-Erzeugung:
az network vnet create \
--resource-group "$RESOURCE_GROUP" \
--name vnet-k8s \
--address-prefixes 10.50.0.0/16 \
--subnet-name subnet-k8s \
--subnet-prefixes 10.50.1.0/24
az vm create \
--resource-group "$RESOURCE_GROUP" \
--name cp-1 \
--image Ubuntu2404 \
--size Standard_B2s \
--vnet-name vnet-k8s \
--subnet subnet-k8s \
--admin-username azureuser \
--generate-ssh-keys
Danach installierst du containerd, kubelet, kubeadm und kubectl, initialisierst die Control Plane und joinst Worker Nodes.
12.7 Rückbau
az aks delete \
--resource-group "$RESOURCE_GROUP" \
--name "$CLUSTER_NAME" \
--yes --no-wait
# Für reine Workshop-Resource-Groups ist der komplette Rückbau oft sauberer:
az group delete \
--name "$RESOURCE_GROUP" \
--yes --no-wait
Prüfe, ob noch Public IPs, Disks oder Load Balancer existieren:
az resource list --resource-group "$RESOURCE_GROUP" -o table
13. Google Cloud: GKE und Compute-Engine-Varianten
Google Cloud bietet mit GKE zwei sehr wichtige Modi: Autopilot und Standard.
| Variante | Werkzeug | Geeignet für |
|---|---|---|
| GKE Autopilot | gcloud container clusters create-auto |
App-fokussierte Workshops mit wenig Node-Betrieb. |
| GKE Standard zonal | gcloud container clusters create --zone |
Kleine Labs, nicht für hohe Verfügbarkeit. |
| GKE Standard regional | gcloud container clusters create --region |
Produktionsnähere Labs und regionale Control Plane. |
| GKE mit Terraform/OpenTofu | Google Provider | Reproduzierbare Cluster und Netzwerkressourcen. |
| Compute Engine + kubeadm | gcloud compute, SSH, kubeadm |
Tiefe Admin-Labs. |
| Compute Engine + k3s/RKE2/k0s/Talos | gcloud compute, SSH oder Talos API |
Spezial- und Edge-Labs. |
| GKE Enterprise / Fleet | gcloud container fleet |
Multi-Cluster- und Enterprise-Verwaltung. |
13.1 Projekt vorbereiten
export PROJECT_ID="my-gcp-project"
export REGION="europe-west3"
export CLUSTER_NAME="workshop-gke"
gcloud auth login
gcloud config set project "$PROJECT_ID"
gcloud services enable container.googleapis.com compute.googleapis.com iam.googleapis.com
13.2 GKE Autopilot
gcloud container clusters create-auto "$CLUSTER_NAME" \
--region "$REGION" \
--labels owner="$USER",environment=workshop,ttl=8h
gcloud container clusters get-credentials "$CLUSTER_NAME" \
--region "$REGION"
kubectl get nodes -o wide
Autopilot ist gut, wenn du Kubernetes-Objekte, Ressourcenanforderungen, Workload-Sicherheit und Services üben willst, ohne Node Pools zu betreiben.
13.3 GKE Standard regional
gcloud container clusters create "$CLUSTER_NAME" \
--region "$REGION" \
--num-nodes 1 \
--machine-type e2-standard-2 \
--enable-ip-alias \
--labels owner="$USER",environment=workshop,ttl=8h
gcloud container clusters get-credentials "$CLUSTER_NAME" \
--region "$REGION"
Für Workshops ist --num-nodes 1 bei regionalen Clustern vorsichtig zu bewerten, weil GKE die Node-Anzahl pro Zone interpretiert. Prüfe die tatsächliche Anzahl Nodes nach dem Erstellen:
kubectl get nodes -o wide
gcloud container node-pools list --cluster "$CLUSTER_NAME" --region "$REGION"
13.4 GKE Node Pool ergänzen
gcloud container node-pools create apps \
--cluster "$CLUSTER_NAME" \
--region "$REGION" \
--machine-type e2-standard-2 \
--num-nodes 1 \
--node-labels workload=apps
13.5 GKE mit Terraform/OpenTofu
resource "google_container_cluster" "this" {
name = var.cluster_name
location = var.region
remove_default_node_pool = true
initial_node_count = 1
release_channel {
channel = "REGULAR"
}
ip_allocation_policy {}
}
resource "google_container_node_pool" "system" {
name = "system"
location = var.region
cluster = google_container_cluster.this.name
node_count = 2
node_config {
machine_type = "e2-standard-2"
labels = {
workload = "system"
}
}
}
13.6 Compute Engine + kubeadm
VM-Grundlage:
gcloud compute networks create k8s-workshop --subnet-mode custom
gcloud compute networks subnets create k8s-workshop-eu \
--network k8s-workshop \
--region "$REGION" \
--range 10.60.1.0/24
gcloud compute firewall-rules create k8s-workshop-ssh \
--network k8s-workshop \
--allow tcp:22
gcloud compute instances create cp-1 \
--zone europe-west3-a \
--machine-type e2-standard-2 \
--image-family ubuntu-2404-lts-amd64 \
--image-project ubuntu-os-cloud \
--subnet k8s-workshop-eu
Danach folgt der gleiche kubeadm-, k3s-, RKE2-, k0s- oder Talos-Bootstrap wie bei anderen VM-Providern.
13.7 Rückbau
gcloud container clusters delete "$CLUSTER_NAME" \
--region "$REGION" \
--quiet
# Restressourcen prüfen
gcloud compute forwarding-rules list
gcloud compute disks list
gcloud compute addresses list
14. Weitere Managed-Kubernetes-Anbieter
Die großen drei Provider decken viele Umgebungen ab, aber für Workshops, Preisvergleiche, Edge-Labs oder regionale Vorgaben sind weitere Anbieter relevant. Die folgenden Beispiele sind bewusst als Startpunkte formuliert. Prüfe immer aktuelle Regionen, Versionen, Preise, Quotas und CLI-Hilfe.
14.1 DigitalOcean Kubernetes (DOKS)
DOKS ist ein pragmatischer Managed-Kubernetes-Pfad für kleine bis mittlere Labs.
Primäres Werkzeug: doctl
export CLUSTER_NAME="workshop-doks"
export REGION="fra1"
doctl auth init
doctl kubernetes options regions
doctl kubernetes options sizes
doctl kubernetes options versions
doctl kubernetes cluster create "$CLUSTER_NAME" \
--region "$REGION" \
--size s-2vcpu-4gb \
--count 2 \
--tag environment:workshop \
--tag ttl:8h
doctl kubernetes cluster kubeconfig save "$CLUSTER_NAME"
kubectl get nodes -o wide
Rückbau:
doctl kubernetes cluster delete "$CLUSTER_NAME" --dangerous --force
14.2 Akamai/Linode Kubernetes Engine (LKE)
LKE ist ein Managed-Kubernetes-Angebot mit CLI-, API- und Terraform-Pfaden.
Primäres Werkzeug: linode-cli
export CLUSTER_NAME="workshop-lke"
export REGION="eu-central"
export K8S_VERSION="<version-aus-linode-cli-lke-versions-list>"
linode-cli lke versions-list
linode-cli regions list
linode-cli lke cluster-create \
--label "$CLUSTER_NAME" \
--region "$REGION" \
--k8s_version "$K8S_VERSION" \
--node_pools.type g6-standard-2 \
--node_pools.count 2 \
--tags workshop
linode-cli lke clusters-list
# Danach Cluster-ID einsetzen:
linode-cli lke kubeconfig-view <cluster-id> --text | base64 -d > kubeconfig-lke.yaml
export KUBECONFIG="$PWD/kubeconfig-lke.yaml"
kubectl get nodes -o wide
Rückbau:
linode-cli lke cluster-delete <cluster-id>
14.3 Oracle Kubernetes Engine (OKE)
OKE benötigt OCI-spezifische IDs für Compartment, VCN und Subnetze. Für Workshops solltest du diese Werte vorab vorbereiten.
Primäres Werkzeug: oci
export OCI_COMPARTMENT_ID="ocid1.compartment..."
export OCI_VCN_ID="ocid1.vcn..."
export OCI_ENDPOINT_SUBNET_ID="ocid1.subnet..."
export OCI_LB_SUBNET_ID="ocid1.subnet..."
export CLUSTER_NAME="workshop-oke"
export K8S_VERSION="<unterstützte-version>"
oci ce cluster create \
--compartment-id "$OCI_COMPARTMENT_ID" \
--name "$CLUSTER_NAME" \
--kubernetes-version "$K8S_VERSION" \
--vcn-id "$OCI_VCN_ID" \
--endpoint-subnet-id "$OCI_ENDPOINT_SUBNET_ID" \
--service-lb-subnet-ids "[\"$OCI_LB_SUBNET_ID\"]"
Kubeconfig erzeugst du über die OCI-Konsole oder CLI nach Cluster-Erstellung. Für reale Umgebungen ergänzt du Node Pools, Netzwerkregeln, IAM-Policies und Load-Balancer-Subnets bewusst.
14.4 IBM Cloud Kubernetes Service (IKS)
IKS wird über die IBM Cloud CLI und das Kubernetes-Service-Plugin verwaltet.
Primäres Werkzeug: ibmcloud
ibmcloud login --sso
ibmcloud plugin install container-service
ibmcloud ks cluster versions
ibmcloud ks locations
ibmcloud ks flavors
# Beispielstruktur; genaue Optionen an Account, Region, VPC und Cluster-Typ anpassen:
ibmcloud ks cluster create vpc-gen2 \
--name workshop-iks \
--zone eu-de-1 \
--flavor bx2.4x16 \
--workers 2
ibmcloud ks cluster config --cluster workshop-iks
kubectl get nodes -o wide
Rückbau:
ibmcloud ks cluster rm --cluster workshop-iks
14.5 Civo Kubernetes
Civo eignet sich für schnelle Labs mit einfacher CLI. Prüfe Region, verfügbare Versionen und Marketplace-Add-ons vorab.
Primäres Werkzeug: civo
civo apikey add workshop <api-key>
civo apikey current workshop
civo region ls
civo kubernetes versions
civo kubernetes create workshop-civo \
--region FRA1 \
--nodes 2 \
--size g4s.kube.medium \
--save \
--switch
kubectl get nodes -o wide
Rückbau:
civo kubernetes delete workshop-civo --yes
14.6 Vultr Kubernetes Engine (VKE)
VKE ist ein Managed-Kubernetes-Pfad für einfache Lab-Cluster. Prüfe Pläne und Regionen vorab.
Primäres Werkzeug: vultr-cli
vultr-cli account info
vultr-cli kubernetes versions
vultr-cli regions list
vultr-cli kubernetes create \
--region fra \
--label workshop-vke \
--version <version> \
--node-pools '[{"node_quantity":2,"label":"system","node_plan":"vc2-2c-4gb"}]'
vultr-cli kubernetes list
vultr-cli kubernetes config <cluster-id> > kubeconfig-vke.yaml
export KUBECONFIG="$PWD/kubeconfig-vke.yaml"
kubectl get nodes -o wide
Rückbau:
vultr-cli kubernetes delete <cluster-id>
14.7 Scaleway Kapsule/Kosmos
Scaleway bietet Kapsule als Managed Kubernetes und Kosmos für Multi-Cloud-Node-Pools. Nutze die CLI-Hilfe für aktuelle Parameter.
Primäres Werkzeug: scw
scw init
scw k8s version list
scw k8s cluster create \
name=workshop-kapsule \
region=fr-par \
version=<version> \
cni=cilium
scw k8s pool create \
cluster-id=<cluster-id> \
name=system \
node-type=DEV1-M \
size=2
scw k8s kubeconfig get <cluster-id> > kubeconfig-scaleway.yaml
export KUBECONFIG="$PWD/kubeconfig-scaleway.yaml"
kubectl get nodes -o wide
Rückbau:
scw k8s cluster delete <cluster-id> with-additional-resources=true
14.8 OVHcloud Managed Kubernetes Service
OVHcloud Managed Kubernetes wird häufig über das Portal, API oder Terraform provisioniert. Für Workshops ist Terraform meist sauberer als manuelle API-Aufrufe.
Primäres Werkzeug: ovh oder Terraform
# Typischer IaC-Pfad:
terraform init
terraform plan
terraform apply
# Danach kubeconfig aus Output oder Provider-Resource schreiben und validieren:
kubectl get nodes -o wide
Halte Projekt-ID, Region, Node-Pool-Flavors und Netzbereiche im Terraform-State nachvollziehbar.
14.9 Alibaba Cloud ACK
ACK ist der Alibaba-Cloud-Pfad für Managed Kubernetes. In internationalen Workshops musst du Account-, Region- und Compliance-Vorgaben besonders genau prüfen.
Primäres Werkzeug: aliyun
aliyun configure
aliyun cs GET /api/v1/clusters
# Cluster-Erstellung benötigt je nach Modus VPC, Subnetze, Worker-Konfiguration und RAM-Rollen.
# Nutze für reproduzierbare Umgebungen bevorzugt Terraform oder die offiziellen ACK-CLI-Beispiele.
14.10 Tencent Kubernetes Engine (TKE)
TKE ist der Tencent-Cloud-Pfad für Managed Kubernetes. Prüfe Region, VPC, Subnetze, Cluster-Typ und IAM vorab.
Primäres Werkzeug: tccli
tccli configure
tccli tke DescribeClusters
# Für reproduzierbare Umgebungen bevorzugst du Terraform oder ein freigegebenes Organisationsmodul.
14.11 Hetzner Cloud mit k3s, kubeadm oder Talos
Hetzner Cloud ist typischerweise kein klassischer Managed-Kubernetes-Pfad, sondern eine sehr beliebte VM-Basis für k3s, kubeadm, RKE2, k0s oder Talos.
Primäres Werkzeug: hcloud
export HCLOUD_TOKEN="<token>"
hcloud server-type list
hcloud image list
hcloud server create \
--name cp-1 \
--type cx22 \
--image ubuntu-24.04 \
--location fsn1 \
--ssh-key <ssh-key-name> \
--label environment=workshop \
--label ttl=8h
hcloud server list
Danach installierst du k3s, kubeadm, RKE2, k0s oder Talos wie im VM-Kapitel.
Rückbau:
hcloud server delete cp-1 worker-1 worker-2
hcloud load-balancer list
hcloud volume list
15. VM-basierte Cloud-Cluster mit kubeadm, k3s, RKE2, k0s und Talos
Managed Kubernetes ist nicht immer das richtige Lernziel. Für Admin-, Architektur- und Troubleshooting-Workshops brauchst du häufig echte Nodes, Systemdienste und kontrollierbare Control-Plane-Komponenten.
15.1 Gemeinsames VM-Zielbild
flowchart TD
Cloud[Cloud Provider] --> Net[VPC/VNet/Subnetze]
Net --> FW[Security Groups oder Firewalls]
Net --> LB[Optionaler API Load Balancer]
FW --> CP1[Control Plane 1]
FW --> CP2[Control Plane 2]
FW --> CP3[Control Plane 3]
FW --> W1[Worker 1]
FW --> W2[Worker 2]
LB --> CP1
LB --> CP2
LB --> CP3
CP1 --> Etcd[etcd]
CP2 --> Etcd
CP3 --> Etcd
W1 --> Pods[Workloads]
W2 --> Pods
15.2 Mindestports
| Zweck | Port | Richtung | Hinweis |
|---|---|---|---|
| SSH | 22/tcp | Admin zu Nodes | Möglichst nur eigene Admin-IP. |
| Kubernetes API | 6443/tcp | Admin/Nodes zu Control Plane | Öffentlich nur stark eingeschränkt. |
| etcd | 2379-2380/tcp | Control Plane intern | Nicht öffentlich freigeben. |
| kubelet | 10250/tcp | Control Plane zu Nodes | Nicht öffentlich freigeben. |
| NodePort | 30000-32767/tcp | Optional extern | Für Labs sparsam nutzen. |
| CNI | variabel | Node zu Node | Abhängig von Flannel, Calico, Cilium, Weave, Canal. |
| Ingress | 80/443/tcp | Client zu Load Balancer | Über Cloud Load Balancer oder NodePort. |
15.3 kubeadm auf Cloud-VMs
kubeadm eignet sich für produktionsnahe Lernziele, weil du Control Plane, etcd, kubelet, Container Runtime und CNI explizit siehst.
Vorbereitung auf allen Nodes
sudo swapoff -a
sudo sed -i.bak '/ swap / s/^/#/' /etc/fstab
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
Container Runtime:
sudo apt update
sudo apt install -y containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml >/dev/null
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd
Kubernetes-Pakete:
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl gpg
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.36/deb/Release.key | \
sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.36/deb/ /' | \
sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt update
sudo apt install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
Control Plane:
sudo kubeadm init \
--control-plane-endpoint "api.k8s.internal:6443" \
--pod-network-cidr "10.244.0.0/16" \
--upload-certs
mkdir -p "$HOME/.kube"
sudo cp /etc/kubernetes/admin.conf "$HOME/.kube/config"
sudo chown "$(id -u):$(id -g)" "$HOME/.kube/config"
CNI-Beispiel Flannel:
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
CNI-Beispiel Cilium:
helm repo add cilium https://helm.cilium.io/
helm repo update
helm install cilium cilium/cilium \
--namespace kube-system \
--set kubeProxyReplacement=false
Worker Join:
sudo kubeadm join api.k8s.internal:6443 \
--token <token> \
--discovery-token-ca-cert-hash sha256:<hash>
15.4 k3s auf Cloud-VMs
k3s ist sehr gut für kleine Remote-Labs.
Single Node:
curl -sfL https://get.k3s.io | sh -
sudo k3s kubectl get nodes
sudo cat /etc/rancher/k3s/k3s.yaml
Server mit explizitem Token:
export K3S_TOKEN="$(openssl rand -hex 24)"
curl -sfL https://get.k3s.io | \
K3S_TOKEN="$K3S_TOKEN" \
sh -s - server --cluster-init
Agent:
curl -sfL https://get.k3s.io | \
K3S_URL="https://<server-ip>:6443" \
K3S_TOKEN="<token>" \
sh -
15.5 RKE2 auf Cloud-VMs
RKE2 ist interessant, wenn du Rancher-nah, stärker sicherheitsorientiert oder Enterprise-nah arbeiten willst.
Server:
curl -sfL https://get.rke2.io | sudo sh -
sudo systemctl enable rke2-server.service
sudo systemctl start rke2-server.service
sudo journalctl -u rke2-server -f
Kubeconfig:
sudo cp /etc/rancher/rke2/rke2.yaml ./rke2.yaml
sudo chown "$USER:$USER" ./rke2.yaml
export KUBECONFIG="$PWD/rke2.yaml"
kubectl get nodes
15.6 k0s auf Cloud-VMs
k0s ist eine schlanke Kubernetes-Distribution mit einfacher Installation.
curl -sSLf https://get.k0s.sh | sudo sh
sudo k0s install controller --single
sudo k0s start
sudo k0s status
sudo k0s kubeconfig admin > kubeconfig-k0s.yaml
export KUBECONFIG="$PWD/kubeconfig-k0s.yaml"
kubectl get nodes
15.7 Talos auf Cloud-VMs
Talos verwaltest du nicht primär per SSH, sondern über talosctl und Maschinenkonfigurationen.
Grundablauf:
talosctl gen config workshop-talos https://<api-endpoint>:6443
talosctl apply-config \
--insecure \
--nodes <control-plane-ip> \
--file controlplane.yaml
talosctl bootstrap --nodes <control-plane-ip>
talosctl kubeconfig --nodes <control-plane-ip>
kubectl get nodes
Talos passt gut, wenn du Immutable Infrastructure, klare Maschinenzustände und härtungsnahe Betriebsmodelle zeigen willst.
16. Infrastructure as Code
16.1 Warum IaC?
Manuelle CLI-Kommandos sind gut zum Lernen. Für wiederholbare Workshops und Teams brauchst du IaC.
| Kriterium | CLI | Terraform/OpenTofu | Pulumi | Cluster API |
|---|---|---|---|---|
| Einstieg | Schnell | Mittel | Mittel | Hoch |
| Reproduzierbarkeit | Mittel | Hoch | Hoch | Hoch |
| Reviewbarkeit | Mittel | Hoch | Hoch | Hoch |
| Multi-Cloud | Mittel | Hoch | Hoch | Hoch |
| Cluster-Lifecycle | Providerabhängig | Gut | Gut | Sehr gut für Flotten |
| Drift-Erkennung | Schwach | Gut | Gut | Kubernetes-nativ |
| Secret-Handling | Manuell | Backendabhängig | Stackabhängig | Kubernetes-nativ plus externe Systeme |
16.2 Terraform/OpenTofu Standardstruktur
infra/cloud-kubernetes/
├── README.md
├── versions.tf
├── providers.tf
├── variables.tf
├── locals.tf
├── network.tf
├── cluster.tf
├── nodepools.tf
├── addons.tf
├── outputs.tf
├── terraform.tfvars.example
└── environments/
├── aws-dev.tfvars
├── azure-dev.tfvars
└── gcp-dev.tfvars
16.3 Gemeinsame Terraform-Variablen
variable "cluster_name" {
type = string
description = "Name des Kubernetes-Clusters."
}
variable "region" {
type = string
description = "Cloud-Region."
}
variable "kubernetes_version" {
type = string
description = "Gewünschte Kubernetes-Version."
default = null
}
variable "node_count" {
type = number
description = "Gewünschte Anzahl Nodes für einfache Labs."
default = 2
}
variable "tags" {
type = map(string)
description = "Pflichttags für Governance und Kostenkontrolle."
default = {
environment = "workshop"
ttl = "8h"
}
}
16.4 Terraform-Workflow
terraform fmt -recursive
terraform init
terraform validate
terraform plan -out tfplan
terraform apply tfplan
terraform output
Rückbau:
terraform plan -destroy -out destroy.tfplan
terraform apply destroy.tfplan
16.5 Remote State
Für Teams gehört der State nicht auf die lokale Festplatte.
| Cloud | Typisches Backend |
|---|---|
| AWS | S3 mit DynamoDB Locking oder HCP Terraform. |
| Azure | Azure Storage Account mit Blob Container. |
| Google Cloud | GCS Bucket. |
| Multi-Cloud | HCP Terraform, GitLab/OpenTofu-Backend, S3-kompatibles Backend. |
16.6 Pulumi
Pulumi ist sinnvoll, wenn dein Team Infrastruktur lieber in TypeScript, Python, Go, C# oder YAML beschreibt.
Beispielstruktur:
pulumi/cloud-kubernetes/
├── Pulumi.yaml
├── Pulumi.dev.yaml
├── index.ts
└── package.json
Typischer Ablauf:
pulumi login
pulumi stack init dev
pulumi config set cloud:region eu-central-1
pulumi preview
pulumi up
pulumi stack output kubeconfig --show-secrets > kubeconfig.yaml
export KUBECONFIG="$PWD/kubeconfig.yaml"
kubectl get nodes
16.7 IaC-Abnahmekriterien
Eine IaC-Provisionierung ist workshop- und teamfähig, wenn:
fmt,validateundplanreproduzierbar laufen,- keine echten Secrets im Repository liegen,
- Provider- und Modulversionen gepinnt sind,
- State-Backend und Locking definiert sind,
- Tags und Namensschema erzwungen werden,
- Rückbau getestet ist,
- Outputs kubeconfig, Clustername, Region und wichtige Endpunkte liefern,
- Add-ons nicht ungeprüft über Ad-hoc-Kommandos installiert werden.
17. Cluster API, Crossplane und GitOps
17.1 Cluster API
Cluster API ist ein Kubernetes-nativer Ansatz, um Cluster deklarativ zu erstellen, zu aktualisieren und zu betreiben. Du brauchst dafür einen Management-Cluster, in dem Cluster-API-Controller und Provider laufen.
flowchart TD
Admin[kubectl auf Management-Cluster] --> Mgmt[Management Cluster]
Mgmt --> CAPI[Cluster API Controller]
CAPI --> Provider[Infrastructure Provider: AWS/Azure/GCP/OpenStack/vSphere/...]
Provider --> Infra[Cloud-Infrastruktur]
CAPI --> Workload[Workload Cluster]
Workload --> Apps[Apps und Add-ons]
Grundidee:
clusterctl init --infrastructure aws
clusterctl generate cluster workshop-capi \
--kubernetes-version v1.36.0 \
--control-plane-machine-count=1 \
--worker-machine-count=2 \
> workshop-capi.yaml
kubectl apply -f workshop-capi.yaml
kubectl get clusters
kubectl get machines
Nutze Cluster API, wenn du viele Cluster standardisiert betreiben willst. Für einen einzelnen Einsteiger-Workshop ist es oft zu viel Infrastruktur.
17.2 Crossplane
Crossplane macht Cloud-Ressourcen über Kubernetes-APIs verfügbar. Plattformteams können damit abstrahierte Ressourcen anbieten, etwa CompositeCluster, XNetwork oder XPostgresInstance.
flowchart LR
User[Entwicklerteam] --> Claim[Claim: KubernetesCluster]
Claim --> Crossplane[Crossplane]
Crossplane --> Composition[Composition]
Composition --> ProviderAWS[AWS Provider]
Composition --> ProviderAzure[Azure Provider]
Composition --> ProviderGCP[GCP Provider]
ProviderAWS --> EKS[EKS]
ProviderAzure --> AKS[AKS]
ProviderGCP --> GKE[GKE]
Crossplane passt gut für Self-Service-Plattformen. Für reine Cluster-Grundlagen ist es ein Fortgeschrittenenthema.
17.3 GitOps nach der Provisionierung
Nach der Cluster-Erstellung sollte nicht alles per Hand installiert werden. Ein sauberer Weg ist:
- Cluster provisionieren.
- kubeconfig validieren.
- Bootstrap-Namespace erstellen.
- Argo CD oder Flux installieren.
- Add-on-Repository verbinden.
- Workload-Repository verbinden.
- Drift über GitOps erkennen und korrigieren.
Argo CD Schnellstart:
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
kubectl -n argocd rollout status deployment/argocd-server
Flux Schnellstart:
flux check --pre
flux bootstrap github \
--owner=<github-user-oder-org> \
--repository=<repo> \
--branch=main \
--path=clusters/workshop
18. Netzwerk, DNS, Ingress und Gateway API
18.1 Cloud-Netzwerkentscheidungen
| Entscheidung | Fragen |
|---|---|
| Öffentlich oder privat | Ist die Kubernetes API öffentlich erreichbar oder nur über VPN/Bastion? |
| Subnetze | Trennst du Control Plane, Nodes, Load Balancer und Datenbanken? |
| NAT | Brauchen private Nodes ausgehenden Internetzugriff? |
| Pod-IP-Modell | Nutzt der Provider native Pod-IPs, Overlay oder CNI-spezifische Modelle? |
| DNS | Wer erstellt DNS-Einträge für Load Balancer? |
| TLS | Wo endet TLS: Load Balancer, Ingress, Gateway oder Pod? |
| Egress | Wie wird ausgehender Traffic kontrolliert und protokolliert? |
18.2 Ingress Controller
Für Workshops sind diese Controller typisch:
| Controller | Geeignet für |
|---|---|
| ingress-nginx | Allgemeine Labs, portabel, gut dokumentiert. |
| AWS Load Balancer Controller | EKS mit AWS ALB/NLB-Integration. |
| Application Gateway Ingress Controller | AKS mit Azure Application Gateway. |
| GKE Ingress | GKE-native Load-Balancer-Integration. |
| Traefik | k3s und kleine Lab-Umgebungen. |
| HAProxy Ingress | Fortgeschrittene Routing- und Performance-Szenarien. |
Beispiel ingress-nginx:
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--create-namespace
kubectl -n ingress-nginx get svc
18.3 Gateway API
Gateway API trennt Verantwortlichkeiten besser als klassisches Ingress:
flowchart TD
Infra[Platform/Infra Team] --> GatewayClass[GatewayClass]
Platform[Platform Team] --> Gateway[Gateway]
App[App Team] --> Route[HTTPRoute]
GatewayClass --> Controller[Gateway Controller]
Gateway --> Controller
Route --> Gateway
Controller --> LB[Cloud Load Balancer]
Route --> Service[Service]
Service --> Pods[Pods]
Beispielstruktur:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: public
namespace: ingress
spec:
gatewayClassName: nginx
listeners:
- name: http
protocol: HTTP
port: 80
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: demo
namespace: demo
spec:
parentRefs:
- name: public
namespace: ingress
rules:
- backendRefs:
- name: demo
port: 80
18.4 ExternalDNS
ExternalDNS kann DNS-Einträge aus Kubernetes-Objekten erzeugen. Verwende es nur mit klar begrenzten Zonen und Rechten.
Prüfpunkte:
- Darf der Cluster DNS-Zonen ändern?
- Welche Record-Typen sind erlaubt?
- Werden private und öffentliche Zonen getrennt?
- Sind TTLs passend?
- Gibt es Schutz vor versehentlichen Wildcard- oder Root-Zonenänderungen?
18.5 cert-manager
cert-manager automatisiert Zertifikate. Für Cloud-Workshops sind HTTP-01 und DNS-01 relevant.
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm upgrade --install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--set crds.enabled=true
kubectl -n cert-manager rollout status deployment/cert-manager
19. Storage und Datenhaltung
19.1 Cloud-Storage-Matrix
| Provider | Block Storage | Typischer CSI-Pfad |
|---|---|---|
| AWS | EBS | Amazon EBS CSI Driver. |
| Azure | Managed Disks | Azure Disk CSI Driver. |
| Google Cloud | Persistent Disk | GCE Persistent Disk CSI Driver. |
| DigitalOcean | Volumes Block Storage | DigitalOcean CSI. |
| Akamai/Linode | Block Storage | Linode CSI. |
| Oracle Cloud | Block Volumes | OCI CSI. |
| IBM Cloud | Block/File Storage | IBM Cloud CSI. |
| Hetzner | Volumes | hcloud CSI für VM-basierte Cluster. |
19.2 StorageClasses prüfen
kubectl get storageclass
kubectl describe storageclass
19.3 PVC-Test
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data
namespace: demo
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
kubectl create namespace demo
kubectl apply -f pvc.yaml
kubectl -n demo get pvc
kubectl -n demo describe pvc data
19.4 Stateful Workloads
Für produktionsnahe Cloud-Workloads brauchst du:
- klare StorageClass-Auswahl,
- Backup- und Restore-Test,
- Verschlüsselung,
- Snapshot-Strategie,
- Zonenkonzept,
- PDBs und Wartungsfenster,
- Monitoring für IOPS, Latenz und Kapazität.
20. Observability und Betrieb
20.1 Mindeststandard
kubectl get nodes -o wide
kubectl top nodes
kubectl top pods -A
kubectl get events -A --sort-by=.lastTimestamp | tail -50
20.2 Metrics Server
Viele Managed-Cluster bringen Metrics Server mit oder bieten ihn als Add-on. Prüfe zuerst:
kubectl get deployment metrics-server -n kube-system
kubectl top nodes
Installation, falls nötig:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
20.3 Prometheus und Grafana
Für Workshops kann kube-prometheus-stack genügen:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm upgrade --install monitoring prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace
20.4 Logs
Cloud-native Optionen:
| Provider | Typischer Dienst |
|---|---|
| AWS | CloudWatch Container Insights, EKS add-ons, Fluent Bit. |
| Azure | Azure Monitor Container Insights. |
| Google Cloud | Cloud Logging und Cloud Monitoring. |
| DigitalOcean | Externe Stacks oder Marketplace-Add-ons. |
| IBM/Oracle/Akamai | Provider-Logging plus eigener Stack. |
Portabler Workshop-Pfad:
- Loki,
- Promtail oder Grafana Alloy,
- Grafana,
- strukturierte App-Logs.
20.5 Betriebssignale
| Signal | Werkzeug |
|---|---|
| Node Ready | kubectl get nodes, Cloud-Konsole. |
| Pod Scheduling | Events, Scheduler-Logs. |
| Rollouts | kubectl rollout status. |
| Ressourcen | Metrics Server, Prometheus. |
| Netzwerk | Debug-Pods, CNI-Metriken. |
| Storage | PVC Events, CSI-Controller-Logs. |
| API-Zugriff | Audit Logs, Cloud IAM Logs. |
21. Security Baseline
21.1 Identität
| Provider | Workload-Identity-Modell |
|---|---|
| AWS | IAM Roles for Service Accounts oder EKS Pod Identity. |
| Azure | Microsoft Entra Workload ID / Managed Identity. |
| Google Cloud | Workload Identity Federation for GKE. |
| Andere | Provider-spezifische Service Accounts oder externe Secret-Systeme. |
Regel: Vermeide statische Cloud-Schlüssel in Kubernetes Secrets. Nutze kurzlebige Tokens und Workload Identity, wenn möglich.
21.2 RBAC-Minimum
kubectl auth can-i get pods -A
kubectl auth can-i '*' '*' --as system:serviceaccount:demo:app
kubectl get clusterrolebinding
Ein Workshop-ServiceAccount sollte keine Cluster-Admin-Rechte bekommen.
21.3 Pod Security Standards
Namespace mit Restricted-Profil:
kubectl label namespace demo \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/warn=restricted
21.4 SecurityContext-Beispiel
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo
namespace: demo
spec:
replicas: 2
selector:
matchLabels:
app: demo
template:
metadata:
labels:
app: demo
spec:
serviceAccountName: demo
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: nginx:1.27-alpine
ports:
- containerPort: 8080
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 256Mi
21.5 Netzisolation
Default Deny:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: demo
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
DNS erlauben:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: demo
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
21.6 Image-Sicherheit
- Keine
latest-Tags für Workshops, die reproduzierbar sein sollen. - Images aus vertrauenswürdigen Registries verwenden.
- Signaturen und SBOMs in fortgeschrittenen Labs einführen.
- Admission Policies für Registries und SecurityContext prüfen.
22. Validierung
22.1 Cluster-Basis
kubectl version
kubectl cluster-info
kubectl get nodes -o wide
kubectl get namespaces
kubectl get pods -A
kubectl get events -A --sort-by=.lastTimestamp | tail -50
22.2 Workload-Test
kubectl create namespace demo
kubectl create deployment web -n demo --image=nginx:1.27-alpine --replicas=2
kubectl expose deployment web -n demo --port=80 --target-port=80 --type=ClusterIP
kubectl rollout status deployment/web -n demo
kubectl get pods,svc -n demo -o wide
22.3 Service-Test intern
kubectl run curl -n demo --rm -it --image=curlimages/curl:8.10.1 --restart=Never -- \
curl -sS http://web.demo.svc.cluster.local
22.4 LoadBalancer-Test
kubectl patch svc web -n demo -p '{"spec":{"type":"LoadBalancer"}}'
kubectl get svc web -n demo -w
Wenn EXTERNAL-IP dauerhaft pending bleibt, prüfst du:
- Cloud Controller Manager,
- Load-Balancer-Quota,
- Subnet-Tags,
- Security Groups oder Firewalls,
- Provider-spezifische Controller,
- Kubernetes Events des Services.
22.5 Storage-Test
kubectl get storageclass
kubectl apply -f pvc.yaml
kubectl -n demo get pvc
22.6 RBAC-Test
kubectl auth can-i get pods -n demo
kubectl auth can-i create deployments -n demo
kubectl auth can-i '*' '*' --all-namespaces
22.7 Validierungsprotokoll
| Prüfung | Kommando | Erwartung |
|---|---|---|
| API erreichbar | kubectl cluster-info |
API Server antwortet. |
| Nodes bereit | kubectl get nodes |
Alle Nodes Ready. |
| System Pods | kubectl get pods -n kube-system |
CoreDNS und CNI laufen. |
| DNS | Curl-Pod zu Service-DNS | DNS löst Service auf. |
| Scheduling | Test-Deployment | Pods werden geplant. |
| Service | ClusterIP-Test | Service routet zu Pods. |
| LoadBalancer | Service Typ LoadBalancer | Externe IP oder Hostname erscheint. |
| Storage | PVC | PVC wird Bound. |
| Metriken | kubectl top nodes |
Metriken verfügbar. |
| Rückbau | Provider-CLI oder IaC Destroy | Keine Restressourcen. |
23. Rückbau
23.1 Grundregeln
- Zuerst Kubernetes-LoadBalancer-Services löschen.
- Dann Add-ons entfernen, die Cloud-Ressourcen verwalten.
- Dann Cluster löschen.
- Dann Restressourcen prüfen.
- Dann State, kubeconfig und temporäre Secrets bereinigen.
23.2 Provider-Kommandos
# AWS EKS
eksctl delete cluster --name workshop-eks --region eu-central-1
# Azure AKS
az aks delete --resource-group rg-workshop-aks --name workshop-aks --yes --no-wait
# Google GKE
gcloud container clusters delete workshop-gke --region europe-west3 --quiet
# DigitalOcean DOKS
doctl kubernetes cluster delete workshop-doks --dangerous --force
# Linode LKE
linode-cli lke cluster-delete <cluster-id>
# Terraform/OpenTofu
terraform plan -destroy -out destroy.tfplan
terraform apply destroy.tfplan
23.3 Restressourcen suchen
# Kubernetes-Seite
kubectl get svc -A --field-selector spec.type=LoadBalancer
kubectl get pvc -A
# AWS
aws elbv2 describe-load-balancers --region eu-central-1
aws ec2 describe-volumes --region eu-central-1 --filters Name=status,Values=available
aws ec2 describe-addresses --region eu-central-1
# Azure
az resource list --tag environment=workshop -o table
# Google Cloud
gcloud compute forwarding-rules list
gcloud compute disks list
gcloud compute addresses list
# DigitalOcean
doctl compute load-balancer list
doctl compute volume list
doctl compute floating-ip list
23.4 Lokale Spuren bereinigen
kubectl config get-contexts
kubectl config delete-context <context>
kubectl config delete-cluster <cluster>
kubectl config unset users.<user>
rm -f kubeconfig-*.yaml
rm -rf generated/*
24. Troubleshooting
24.1 Cluster wird nicht erstellt
| Symptom | Wahrscheinliche Ursache | Prüfung |
|---|---|---|
| Quota-Fehler | Zu wenig vCPUs, IPs, Load Balancer oder Disks | Provider Quota-Seite und CLI prüfen. |
| IAM-Fehler | Fehlende Rechte für Rollen, Cluster, Netzwerk | aws sts get-caller-identity, az account show, gcloud auth list. |
| Region nicht unterstützt | Kubernetes-Version oder Node-Größe in Region nicht verfügbar | Versions- und Größenlisten abfragen. |
| Netzwerkfehler | CIDR-Kollision, fehlende Subnetze, blockiertes Routing | VPC/VNet/Subnetze prüfen. |
| Node Group bleibt fehlerhaft | Node-Rolle, Image, Subnetz oder Security Group fehlerhaft | Provider-Events und Node-Logs prüfen. |
24.2 kubectl verbindet sich nicht
kubectl config current-context
kubectl config view --minify
kubectl cluster-info
Prüfe:
- Ist die kubeconfig geschrieben?
- Zeigt der Kontext auf den richtigen Cluster?
- Ist die Cloud-Authentifizierung noch gültig?
- Ist die API öffentlich oder nur privat erreichbar?
- Benötigst du VPN, Bastion oder Cloud Shell?
24.3 Nodes sind nicht Ready
kubectl describe node <node>
kubectl get pods -n kube-system -o wide
kubectl get events -A --sort-by=.lastTimestamp | tail -100
Häufige Ursachen:
- CNI nicht installiert oder fehlerhaft,
- kubelet kann Runtime nicht erreichen,
- Security Groups blockieren Node-Kommunikation,
- DNS oder Egress fehlt,
- Cloud Controller Manager oder CSI hat keine Rechte,
- DiskPressure, MemoryPressure oder PIDPressure.
24.4 Pods bleiben Pending
kubectl -n demo describe pod <pod>
kubectl get nodes -o wide
kubectl describe node <node>
Prüfe:
- Ressourcenrequests zu hoch,
- keine passenden Node Labels,
- Taints ohne Tolerations,
- PVC nicht gebunden,
- Pod Security Admission blockiert,
- Image Pull Secret fehlt.
24.5 LoadBalancer bleibt Pending
kubectl -n demo describe svc web
kubectl get events -n demo --sort-by=.lastTimestamp
Provider-spezifisch prüfen:
- AWS: Subnet-Tags, AWS Load Balancer Controller, Security Groups, IAM.
- Azure: Public IP, Load Balancer SKU, Managed Identity, Subnet-Rechte.
- GKE: Firewall, Service Annotation, Quota.
- DOKS/LKE: Load-Balancer-Quota und Region.
- VM-Cluster: MetalLB oder eigener Load Balancer fehlt.
24.6 PVC bleibt Pending
kubectl describe pvc -n demo data
kubectl get storageclass
kubectl get events -n demo --sort-by=.lastTimestamp
Prüfe:
- StorageClass existiert,
- Default StorageClass gesetzt,
- CSI-Controller läuft,
- Cloud-Rollen erlauben Disk-Erzeugung,
- Zone/Region passt zu Node und Volume,
- Quota für Disks reicht.
24.7 Terraform apply schlägt fehl
terraform fmt -recursive
terraform validate
terraform plan
terraform state list
Typische Ursachen:
- Provider-Version nicht kompatibel,
- State-Lock hängt,
- lokale Credentials abgelaufen,
- Ressource existiert bereits,
- Namenskonflikt,
- Organisationsrichtlinie blockiert öffentliche Ressourcen,
- Provider-API hat eventual consistency.
25. Workshop-Labs
25.1 Lab 1: Provider-Kontext prüfen
Ziel: Du validierst deine lokale CLI-Umgebung.
Aufgaben:
- Installiere
kubectl,helm,jqund die passende Provider-CLI. - Melde dich beim Provider an.
- Prüfe Account, Region, Quotas und verfügbare Kubernetes-Versionen.
- Dokumentiere Region, Clustername und Rückbaukommando.
Abnahme:
kubectl version --client
helm version
aws sts get-caller-identity || true
az account show -o table || true
gcloud auth list || true
25.2 Lab 2: Managed Cluster erstellen
Ziel: Du erstellst einen kleinen Managed-Kubernetes-Cluster.
Aufgaben:
- Wähle EKS, AKS, GKE, DOKS oder LKE.
- Führe das Provisionierungsscript zuerst ohne
--executeaus. - Führe die echte Provisionierung aus.
- Schreibe die kubeconfig.
- Validiere Nodes und System Pods.
Abnahme:
kubectl get nodes -o wide
kubectl get pods -A
25.3 Lab 3: Workload, Service und LoadBalancer
Ziel: Du prüfst, ob Workloads und Cloud-LoadBalancer funktionieren.
Aufgaben:
- Erstelle Namespace
demo. - Deploye
nginx. - Exponiere den Service als
LoadBalancer. - Prüfe externe Erreichbarkeit.
- Lösche den Service und prüfe Cloud-Restressourcen.
Abnahme:
kubectl -n demo get deploy,pod,svc -o wide
curl -I http://<external-ip-oder-hostname>
25.4 Lab 4: Storage
Ziel: Du prüfst dynamische Volume-Provisionierung.
Aufgaben:
- Liste StorageClasses.
- Erstelle PVC.
- Mount den PVC in einen Pod.
- Schreibe Testdaten.
- Lösche Pod und prüfe Persistenz.
25.5 Lab 5: VM-basierter Cluster
Ziel: Du vergleichst Managed Kubernetes mit einem selbstverwalteten VM-Cluster.
Aufgaben:
- Erstelle drei kleine Cloud-VMs.
- Öffne nur notwendige Ports.
- Installiere kubeadm oder k3s.
- Installiere CNI.
- Validiere Nodes, DNS und Service Routing.
25.6 Lab 6: IaC-Workflow
Ziel: Du erzeugst denselben Cluster reproduzierbar über Terraform/OpenTofu.
Aufgaben:
- Erstelle
versions.tf,providers.tf,variables.tfundcluster.tf. - Führe
terraform fmt,validate,planundapplyaus. - Schreibe kubeconfig.
- Validiere Cluster.
- Führe
terraform destroyaus.
25.7 Lab 7: Security Baseline
Ziel: Du härtst einen Workshop-Namespace.
Aufgaben:
- Erstelle Namespace
secure-demo. - Aktiviere Pod Security Restricted.
- Erstelle ServiceAccount, Role und RoleBinding.
- Setze Default-Deny-NetworkPolicy.
- Deploye eine App mit SecurityContext.
26. Checklisten
26.1 Vor Provisionierung
- Cloud-Konto und Budget sind freigegeben.
- Region ist erlaubt.
- Quotas sind ausreichend.
- Namensschema ist definiert.
- Tags sind definiert.
- Netzwerk-CIDRs kollidieren nicht.
- Öffentliche API-Endpunkte sind bewertet.
- CLI-Login funktioniert.
- Kubernetes-Version ist geprüft.
- Rückbaupfad ist dokumentiert.
26.2 Nach Provisionierung
- kubeconfig zeigt auf den richtigen Cluster.
- Nodes sind
Ready. - System Pods laufen.
- DNS funktioniert.
- Test-Deployment funktioniert.
- Service funktioniert.
- LoadBalancer funktioniert oder ist bewusst nicht installiert.
- StorageClass ist vorhanden oder bewusst nicht vorhanden.
- Metrics funktionieren oder sind als Add-on geplant.
- Tags sind auf Cloud-Ressourcen sichtbar.
26.3 Vor produktionsnaher Nutzung
- Netzwerkdesign ist reviewt.
- Private API oder Zugriffsbeschränkung ist umgesetzt.
- IAM/RBAC ist nach Least Privilege umgesetzt.
- Pod Security Standards sind aktiv.
- Secrets-Strategie ist definiert.
- Audit Logs sind aktiv.
- Observability ist installiert.
- Backup und Restore sind getestet.
- Upgrade-Pfad ist dokumentiert.
- Kostenmonitoring ist aktiv.
26.4 Rückbau
- LoadBalancer-Services gelöscht.
- PVCs und Volumes geprüft.
- Cluster gelöscht.
- Node Pools gelöscht.
- Public IPs gelöscht.
- Disks und Snapshots geprüft.
- DNS-Einträge entfernt.
- kubeconfig-Kontexte gelöscht.
- IaC-State aktualisiert.
- Kostenansicht geprüft.
27. Quellen und Referenzen
Diese Datei ist fachlich an Primärquellen und offiziellen Dokumentationen orientiert. Prüfe vor echter Provisionierung immer die aktuellen Provider-Seiten, weil CLI-Optionen, Versionen, Regionen und Produktvarianten sich ändern können.
| Thema | Referenz |
|---|---|
| Kubernetes Produktionsumgebungen | https://kubernetes.io/docs/setup/production-environment/ |
| kubeadm | https://kubernetes.io/docs/reference/setup-tools/kubeadm/ |
| kubeadm Cluster erstellen | https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/ |
| AWS EKS | https://docs.aws.amazon.com/eks/latest/userguide/ |
| EKS mit eksctl | https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html |
| EKS kubeconfig | https://docs.aws.amazon.com/eks/latest/userguide/create-kubeconfig.html |
| Azure AKS | https://learn.microsoft.com/azure/aks/ |
| AKS mit Azure CLI | https://learn.microsoft.com/azure/aks/learn/quick-kubernetes-deploy-cli |
| Google Kubernetes Engine | https://cloud.google.com/kubernetes-engine/docs |
| GKE gcloud cluster commands | https://cloud.google.com/sdk/gcloud/reference/container/clusters |
| DigitalOcean Kubernetes | https://docs.digitalocean.com/products/kubernetes/ |
| doctl Kubernetes | https://docs.digitalocean.com/reference/doctl/reference/kubernetes/ |
| Akamai/Linode LKE | https://techdocs.akamai.com/cloud-computing/docs/linode-kubernetes-engine |
| Oracle Kubernetes Engine | https://docs.oracle.com/en-us/iaas/Content/ContEng/Concepts/contengoverview.htm |
| IBM Cloud Kubernetes Service | https://cloud.ibm.com/docs/containers |
| kOps | https://kops.sigs.k8s.io/ |
| Cluster API | https://cluster-api.sigs.k8s.io/ |
| Terraform EKS Tutorial | https://developer.hashicorp.com/terraform/tutorials/kubernetes/eks |
| Terraform AWS EKS Module | https://registry.terraform.io/modules/terraform-aws-modules/eks/aws/latest |
| Pulumi Kubernetes | https://www.pulumi.com/docs/integrations/clouds/kubernetes/ |
| Gateway API | https://gateway-api.sigs.k8s.io/ |
| Helm | https://helm.sh/docs/ |
| cert-manager | https://cert-manager.io/docs/ |
| Argo CD | https://argo-cd.readthedocs.io/ |
| Flux | https://fluxcd.io/ |