Diese Anleitung führt durch den Aufbau eines Multi-AZ Kubernetes-Clusters aus 5 Knoten, verteilt über zwei Compute-Availability-Zones der NETWAYS Cloud (HetznerNBG4, NorisNBG3), für rechenzentrumsübergreifende Redundanz innerhalb einer einzigen OpenStack-Region – durchgängig verwaltet von Claudie.

Dieser Artikel wurde in Zusammenarbeit mit Samuel Stoličný von Berops erstellt. Du findest ihn auf LinkedIn, wenn du mehr über Claudie erfahren möchtest.
Warum dieses Setup?
Ein einzelnes Cluster über zwei NWS-Rechenzentren zu betreiben gibt dir geografische Redundanz, ohne ein einzelnes OpenStack-Projekt zu verlassen. Wenn ein Rechenzentrum ausfällt, behält die Control Plane vom anderen RZ aus das Quorum; Workloads, die im gesunden RZ laufen, bleiben verfügbar.
Der gesamte RZ-übergreifende Netzwerkverkehr fließt über eine dedizierte Verbindung zwischen den beiden RZs und ist zusätzlich durch WireGuard verschlüsselt.
Wie funktioniert NWS Multi-AZ?
NWS veröffentlicht zwei Compute-Availability-Zones innerhalb seiner Region: HetznerNBG4 (Hetzner Nürnberg) und NorisNBG3 (Noris Nürnberg). Beide AZs teilen sich einen Keystone-Endpoint und ein Neutron-Netzwerk, sodass ein einziger Application Credential und ein einziger Provider-Eintrag im InputManifest genügen – was sich zwischen den Nodepools unterscheidet, ist das Feld zone:
providers:
- name: netways-1
secretRef: { name: netways-secret, ... }
nodePools:
dynamic:
- { name: nbg4-ctrl, providerSpec: { ..., zone: HetznerNBG4 } }
- { name: noris-ctrl, providerSpec: { ..., zone: NorisNBG3 } }Überprüfe mit folgendem Befehl, welche AZs dein OpenStack-Projekt unterstützt:
openstack availability zone list --compute
+-------------+-------------+
| Zone Name | Zone Status |
+-------------+-------------+
| HetznerNBG4 | available |
| NorisNBG3 | available |
+-------------+-------------+Was du mit diesem Claudie-Setup erreichst
- 3 Control-Plane-Knoten: 2 in
HetznerNBG4+ 1 inNorisNBG3. Mit 3 Control Planes über 2 RZs übersteht etcd entweder einenNorisNBG3-Ausfall oder einen Node-Ausfall inHetznerNBG4. Der komplette Verlust vonHetznerNBG4nimmt das Cluster offline, weil etcd sein Quorum verliert. Siehe Abwägungen unten. - 2 Compute-Knoten: 1 in
HetznerNBG4+ 1 inNorisNBG3. - Ein WireGuard-VPN, das alle fünf Knoten umspannt.
- Cilium CNI und Longhorn-Storage, installiert durch Claudie.
Voraussetzungen
- Ein Kubernetes-Cluster, auf dem Claudie läuft (das „Management-Cluster“).
kubectl, konfiguriert gegen dieses Cluster.- Ein NWS-Account mit Kontingent in der Region
HetznerNBG4(die beide Compute-AZs abdeckt) für mindestens 5 VMs, 3 Floating IPs und 250 GB Storage.
Schritt 1 – Installation von Claudie
Installiere cert-manager und Claudie:
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.19.3/cert-manager.yaml
kubectl apply -f https://github.com/berops/claudie/releases/latest/download/claudie.yamlÜberprüfe, ob die Pods laufen:
kubectl get pods -n claudie
NAME READY STATUS RESTARTS AGE
ansibler-7b5f8c6d49-qvz2w 1/1 Running 0 60s
claudie-operator-59dd646bcf-bjsdr 1/1 Running 0 60s
kube-eleven-bdc799684-xlwws 1/1 Running 0 60s
kuber-7cc7cb797d-bvsrv 1/1 Running 0 60s
manager-69f96bb548-l5wqr 1/1 Running 0 60s
minio-0 1/1 Running 0 60s
minio-1 1/1 Running 0 60s
minio-2 1/1 Running 0 60s
minio-3 1/1 Running 0 60s
mongodb-858994c5cb-x8w77 1/1 Running 0 60s
nats-0 2/2 Running 0 60s
nats-1 2/2 Running 0 60s
nats-2 2/2 Running 0 60s
terraformer-667b9f4556-dkx4x 1/1 Running 0 60sWeitere Details findest du im detaillierten Claudie Guide.
Schritt 2 – Erstellung von Provider-Credentials
Die NWS-Authentifizierung erfolgt normalerweise föderiert über die NWS-ID (OIDC). Claudie benötigt statische Credentials, daher besteht der Ablauf darin, den OpenStack Project User im NWS Customer Interface zu aktivieren und anschließend mit diesem Benutzer ein Application Credential zu erstellen.
Nachdem du den Project User aktiviert und dir dessen Benutzername und Passwort notiert hast, authentifiziere dich mit der OpenStack-CLI und erstelle das Application Credential:
export OS_AUTH_URL=https://cloud.netways.de:5000/v3/
export OS_IDENTITY_API_VERSION=3
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_DOMAIN_NAME=Default
export OS_USERNAME=<your-project-user>
export OS_PROJECT_NAME=<your-project-name>
read -s OS_PASSWORD; export OS_PASSWORD
openstack application credential create --role member claudie -f shell
id="..."
secret="..."
project_id="..."
openstack project show $(openstack token issue -c project_id -f value) \
-c domain_id -f value
defaultDas Application Credential ist auf die Region beschränkt, gegen die du dich authentifiziert hast (HetznerNBG4, wenn du den Standard-Project-User verwendet hast), und es kann mit jeder AZ innerhalb dieser Region kommunizieren, sowohl mit HetznerNBG4 als auch mit NorisNBG3. Ein Credential, ein Secret.
Schritt 3 – Erstellung der Kubernetes Secrets
kubectl create namespace claudie-secrets
kubectl create secret generic netways-secret \
--namespace=claudie-secrets \
--from-literal=authurl='https://cloud.netways.de:5000/v3/' \
--from-literal=domainid='default' \
--from-literal=projectid='<your-nws-project-id>' \
--from-literal=applicationcredentialid='<your-credential-id>' \
--from-literal=applicationcredentialsecret='<your-credential-secret>'Schritt 4 – Erstellung der Claudie Manifest-Datei
Speichere Folgendes als netways-multi-az.yaml:
apiVersion: claudie.io/v1beta1
kind: InputManifest
metadata:
name: netways-multi-az
labels:
app.kubernetes.io/part-of: claudie
spec:
providers:
- name: netways-1
providerType: openstack
secretRef:
name: netways-secret
namespace: claudie-secrets
nodePools:
dynamic:
- name: nbg4-ctrl
providerSpec:
name: netways-1
region: HetznerNBG4
zone: HetznerNBG4
externalNetworkName: public-network
count: 2
serverType: s1.medium
image: "Ubuntu Noble 24.04 LTS"
storageDiskSize: 50
- name: noris-ctrl
providerSpec:
name: netways-1
region: HetznerNBG4
zone: NorisNBG3
externalNetworkName: public-network
count: 1
serverType: s1.medium
image: "Ubuntu Noble 24.04 LTS"
storageDiskSize: 50
- name: nbg4-cmp
providerSpec:
name: netways-1
region: HetznerNBG4
zone: HetznerNBG4
externalNetworkName: public-network
count: 1
serverType: s1.medium
image: "Ubuntu Noble 24.04 LTS"
storageDiskSize: 50
- name: noris-cmp
providerSpec:
name: netways-1
region: HetznerNBG4
zone: NorisNBG3
externalNetworkName: public-network
count: 1
serverType: s1.medium
image: "Ubuntu Noble 24.04 LTS"
storageDiskSize: 50
kubernetes:
clusters:
- name: netways-multi-az
version: v1.32.0
network: 192.168.2.0/24
pools:
control:
- nbg4-ctrl
- noris-ctrl
compute:
- nbg4-cmp
- noris-cmpAnmerkungen:
- Alle vier Nodepools teilen sich
region: HetznerNBG4, weil beide AZs in dieser Region liegen. Nurzoneunterscheidet sich. serverType: s1.medium(4 vCPU, 4 GB RAM, 50 GB lokale Platte) bootet direkt vom Image. Jeder NWS-Flavor mit einer lokalen Disk ist kompatibel.storageDiskSize: 50fügt pro Worker ein zusätzliches Cinder-Volume für Longhorn-Storage hinzu. Controlplane-Nodes ignorieren dieses Feld.- Das Cluster-Netzwerk
192.168.2.0/24ist das WireGuard-Overlay, unabhängig vom Neutron-Netzwerk von NWS.
Schritt 5 – Erstellung des Clusters
kubectl apply -f netways-multi-az.yaml
inputmanifest.claudie.io/netways-multi-az created
kubectl get inputmanifest -n claudie
NAME STATUS
netways-multi-az IN_PROGRESSEin Multi-AZ-Build mit 5 Knoten dauert typischerweise 8 bis 12 Minuten. Wenn er gestartet ist, wechselt das InputManifest den Status:
kubectl get inputmanifest -n claudie
NAME STATUS
netways-multi-az WATCHING_FOR_CHANGESSchritt 6 – Zugriff auf den Cluster
kubectl get secrets -n claudie -l claudie.io/output=kubeconfig \
-o jsonpath='{.items[0].data.kubeconfig}' | base64 -d > netways-multi-az.kubeconfig
export KUBECONFIG=$PWD/netways-multi-az.kubeconfig
kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP OS-IMAGE
nbg4-ctrl-xxxxxxx-01 Ready control-plane 6m v1.32.0 192.168.2.1 Ubuntu 24.04.4 LTS
nbg4-ctrl-xxxxxxx-02 Ready control-plane 6m v1.32.0 192.168.2.2 Ubuntu 24.04.4 LTS
noris-ctrl-yyyyyyy-01 Ready control-plane 6m v1.32.0 192.168.2.3 Ubuntu 24.04.4 LTS
nbg4-cmp-zzzzzzz-01 Ready <none> 4m v1.32.0 192.168.2.4 Ubuntu 24.04.4 LTS
noris-cmp-wwwwwww-01 Ready <none> 4m v1.32.0 192.168.2.5 Ubuntu 24.04.4 LTSJeder Knoten hat eine INTERNAL-IP im WireGuard-Overlay. RZ-übergreifender Verkehr bleibt über diese Adressen verschlüsselt, unabhängig davon, welches physische NWS-Rechenzentrum er durchquert.
Für Workloads, die in einem Rechenzentrum bleiben müssen, versiehst du Pods mit Label und Taint für eine Topology-Zone (topology.kubernetes.io/zone=HetznerNBG4 oder NorisNBG3), damit der Scheduler die Platzierung respektiert.
Schritt 7 – Aufräumen des Clusters
kubectl delete inputmanifest netways-multi-az -n claudieDer Teardown löscht alle VMs, Netzwerke, Router, Security Groups und Floating IPs über beide AZs hinweg.Das dauert üblicherweise 2 bis 5 Minuten.
Abwägungen
- Verlust der Control Plane durch einen kompletten HetznerNBG4-RZ-Ausfall. Mit 2 HetznerNBG4 + 1 NorisNBG3 bringt der Verlust von HetznerNBG4 etcd unter das Quorum, und die Control Plane wird read-only (Workloads laufen weiter, aber es gibt kein neues Scheduling).
- RZ-übergreifende Latenz. Der Round-Trip HetznerNBG4-NorisNBG3 liegt in unseren Test-Builds typischerweise bei 6-9 ms, was ein normaler, etcd-freundlicher Bereich ist.
Weitere Informationen und Material
– Claudie-Dokumentation als Referenz und für Anleitungen.
– Openstack-Provider-Referenz.
– Loadbalancing-Guide, um Services über AZs hinweg via eines von Claudie verwalteten Load Balancers bereitzustellen.
– Autoscaling-Guide, um Compute-Nodepools unabhängig pro AZ zu skalieren.





0 Kommentare