1 Drei Zustandsketten
Alle drei Themen beantworten dieselbe Betriebsfrage: Wo entsteht Zustand, wer hält ihn und wie kommst du im Fehlerfall wieder daran?
ClusterLogForwarder leitet ihn an Loki oder ein externes Ziel weiter.MachineConfig-Objekte beschreiben den Sollzustand. Der MCO erzeugt daraus eine rendered-master-…-Konfiguration. Der Machine Config Daemon wendet sie am Node an.etcd. Das Skript cluster-backup.sh erzeugt Snapshot und Static-Pod-Ressourcen. Erst die externe Kopie macht daraus ein belastbares Backup.Begriffe: Ein Daemon ist ein ständig laufender Hintergrundprozess. Ein MachineConfigPool, kurz MCP, fasst Nodes mit derselben Betriebssystem-Konfiguration zusammen. etcd ist die verteilte Schlüssel-Wert-Datenbank für alle API-Objekte des Clusters.
2 Gesundheit vor der Diagnose prüfen
Das Lab benötigt cluster-admin. Alle Befehle in diesem Abschnitt lesen nur.
oc whoami oc auth can-i '*' '*' --all-namespaces oc get nodes oc get co machine-config etcd oc get mcp oc get pods -n openshift-etcd -o wide
Startzustand: Die ClusterOperatoren machine-config und etcd sollten Available=True und Degraded=False melden. Ein MCP ist vollständig abgeglichen, wenn UPDATED=True und UPDATING=False ist.
3 Einen Logpfad untersuchen
OpenShift kann aktuelle Container-Logs ohne zentralen Logging-Stack anzeigen. Diese Logs liegen zunächst am Node und verschwinden mit Rotation, Pod-Löschung oder Node-Verlust.
oc get pods -n library oc logs -n library deployment/catalog-service --tail=50 oc logs -n library deployment/catalog-service --since=10m --timestamps # nach einem Container-Neustart den vorherigen Container lesen oc logs -n library pod/<pod-name> --previous --tail=50
oc logs fragt über den API-Server den Kubelet des Nodes ab. Der Kubelet ist der Node-Prozess, der Pods startet und ihren Zustand meldet. Er ist keine dauerhafte Logdatenbank.
Node- und Plattform-Logs
$node = oc get node -l node-role.kubernetes.io/control-plane -o jsonpath='{.items[0].metadata.name}'
oc adm node-logs $node --unit=kubelet --tail=50
oc adm node-logs $node --unit=crio --tail=50Bash-Variante anzeigen
node=$(oc get node -l node-role.kubernetes.io/control-plane -o jsonpath='{.items[0].metadata.name}')
oc adm node-logs "$node" --unit=kubelet --tail=50
oc adm node-logs "$node" --unit=crio --tail=50| Quelle | zeigt | Überlebensgrenze |
|---|---|---|
oc logs | Standardausgabe eines aktuellen oder vorherigen Containers | lokale Rotation und Node-Lebensdauer |
kubelet-Journal | Pod-Start, Mounts, Probes und Node-Ausführung | Journal-Rotation am Node |
crio-Journal | Image, Sandbox und Container-Runtime | Journal-Rotation am Node |
| Loki oder externes Ziel | zentral gesammelte Anwendungs-, Infrastruktur- und Audit-Logs | Aufbewahrungsregel des Zielsystems |
4 Erkennen, ob zentrales Logging installiert ist
OpenShift Logging ist nicht automatisch Bestandteil jedes Clusters. In Logging 6 verwaltet der Logging Operator Sammlung und Weiterleitung, der Loki Operator den Speicher und der Cluster Observability Operator die Anzeige.
oc api-resources | Select-String -Pattern 'ClusterLogForwarder|LokiStack' oc get csv -A | Select-String -Pattern 'logging|loki|observability' oc get clusterlogforwarder -A oc get lokistack -A oc get pods -n openshift-logging
Bash-Variante anzeigen
oc api-resources | grep -E 'ClusterLogForwarder|LokiStack' oc get csv -A | grep -Ei 'logging|loki|observability' oc get clusterlogforwarder -A oc get lokistack -A oc get pods -n openshift-logging
Versionsgrenze: Logging 6 verwendet für ClusterLogForwarder die API-Gruppe observability.openshift.io und Vector als Collector. Ältere Beispiele mit logging.openshift.io, ClusterLogging, Fluentd oder Elasticsearch gehören zur früheren Architektur. Prüfe immer zuerst oc api-resources | Select-String ClusterLogForwarder und oc explain clusterlogforwarder.spec.
Auf der kleinen SNO ist kein Logging-Stack die vernünftige Vorgabe. Loki benötigt dauerhaften Objektspeicher und zusätzliche Ressourcen. Für kurze Diagnose reicht oc logs. Für Aufbewahrung oder Audit muss ein zentraler Zielpfad geplant werden.
5 Node-Konfiguration zum Ursprung zurückverfolgen
Der Machine Config Operator, kurz MCO, verwaltet das Betriebssystem der RHCOS- oder SCOS-Nodes. Direkte SSH-Änderungen sind Drift und keine dauerhafte Konfiguration.
oc get co machine-config
oc get mcp
oc get mc -o 'custom-columns=NAME:.metadata.name,GENERATED-BY:.metadata.ownerReferences[0].kind'
$node = oc get node -l node-role.kubernetes.io/control-plane -o jsonpath='{.items[0].metadata.name}'
oc get node $node -o jsonpath='{.metadata.annotations.machineconfiguration\.openshift\.io/currentConfig}{"\n"}{.metadata.annotations.machineconfiguration\.openshift\.io/desiredConfig}{"\n"}{.metadata.annotations.machineconfiguration\.openshift\.io/state}{"\n"}{.metadata.annotations.machineconfiguration\.openshift\.io/reason}{"\n"}'
$rendered = oc get mcp master -o jsonpath='{.status.configuration.name}'
oc get mc $rendered -o yamlBash-Variante anzeigen
oc get co machine-config
oc get mcp
oc get mc -o 'custom-columns=NAME:.metadata.name,GENERATED-BY:.metadata.ownerReferences[0].kind'
node=$(oc get node -l node-role.kubernetes.io/control-plane -o jsonpath='{.items[0].metadata.name}')
oc get node "$node" -o jsonpath='{.metadata.annotations.machineconfiguration\.openshift\.io/currentConfig}{"\n"}{.metadata.annotations.machineconfiguration\.openshift\.io/desiredConfig}{"\n"}{.metadata.annotations.machineconfiguration\.openshift\.io/state}{"\n"}{.metadata.annotations.machineconfiguration\.openshift\.io/reason}{"\n"}'
rendered=$(oc get mcp master -o jsonpath='{.status.configuration.name}')
oc get mc "$rendered" -o yaml| Kategorie | Beispiel | deine Aufgabe |
|---|---|---|
| du legst an | machineconfig-mco-lab.yaml | gewollte Node-Änderung als deklaratives Manifest beschreiben |
| wird generiert | rendered-master-… | nur lesen. Der MCO kombiniert alle zur Rolle passenden MachineConfigs |
| wichtig | /etc/mco-lab-marker am Node | Wirkung prüfen, aber nicht per SSH als dauerhafte Konfiguration anlegen |
6 Eine MachineConfig sicher proben
Du legst lokal ein Manifest an und lässt nur API-Schema und Admission prüfen. Der Dry-Run erzeugt kein Clusterobjekt und löst keinen Node-Neustart aus.
@'
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
metadata:
name: 99-master-mco-lab
labels:
machineconfiguration.openshift.io/role: master
spec:
config:
ignition:
version: 3.4.0
storage:
files:
- path: /etc/mco-lab-marker
mode: 420
overwrite: true
contents:
source: data:text/plain;charset=utf-8,mco-lab%0A
'@ | Set-Content -LiteralPath .\machineconfig-mco-lab.yaml -Encoding utf8
oc apply --dry-run=server -f .\machineconfig-mco-lab.yaml
oc diff -f .\machineconfig-mco-lab.yamlBash-Variante anzeigen
cat > machineconfig-mco-lab.yaml <<'EOF'
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
metadata:
name: 99-master-mco-lab
labels:
machineconfiguration.openshift.io/role: master
spec:
config:
ignition:
version: 3.4.0
storage:
files:
- path: /etc/mco-lab-marker
mode: 420
overwrite: true
contents:
source: data:text/plain;charset=utf-8,mco-lab%0A
EOF
oc apply --dry-run=server -f machineconfig-mco-lab.yaml
oc diff -f machineconfig-mco-lab.yamlmachineconfig-mco-lab.yaml ist eine Datei, die du anlegst. /etc/mco-lab-marker würde erst bei einem echten Apply vom MCO generiert. Der Rückgabecode 1 von oc diff bedeutet normalerweise „Unterschied gefunden“ und ist hier kein Fehler.
Nicht im Lab ausführen: Ein echtes Apply auf die Rolle master erzeugt eine neue gerenderte Konfiguration. Der MCO kann den Node entleeren und neu starten. Auf einer SNO bedeutet das vollständige Unterbrechung. Ein pausierter MCP verhindert den sofortigen Rollout, sammelt aber ausstehende Änderungen, die beim Entpausieren gemeinsam wirksam werden.
Die lokale Übungsdatei kannst du danach mit Remove-Item -LiteralPath .\machineconfig-mco-lab.yaml oder unter Bash mit rm -- machineconfig-mco-lab.yaml entfernen.
7 etcd vor dem Backup untersuchen
Ein etcd-Snapshot schützt Kubernetes- und OpenShift-API-Objekte. Er enthält keine Daten aus Persistent Volumes und ersetzt kein Anwendungsbackup.
oc get co etcd
oc get etcd cluster -o yaml
oc get pods -n openshift-etcd -l app=etcd -o wide
oc get --raw='/readyz?verbose'
oc get clusterversion version -o jsonpath='{.status.desired.version}{"\n"}'Vorbedingungen für das Backup: Der Cluster muss gesund sein. Die erste Zertifikatsrotation 24 Stunden nach der Installation muss abgeschlossen sein. Das Backup wird nur auf einem Control-Plane-Node und möglichst außerhalb hoher Last erzeugt. Ein Restore benötigt dieselbe z-Stream-Version.
8 Ein echtes etcd-Backup erzeugen
Das offizielle Skript ist Teil des etcd Cluster Operators. Es erzeugt einen Datenbank-Snapshot und ein Archiv mit den Static-Pod-Ressourcen.
Control-Plane-Node ermitteln
$node = oc get node -l node-role.kubernetes.io/control-plane -o jsonpath='{.items[0].metadata.name}'
$node
oc debug --as-root node/$nodeBash-Variante anzeigen
node=$(oc get node -l node-role.kubernetes.io/control-plane -o jsonpath='{.items[0].metadata.name}')
printf '%s\n' "$node"
oc debug --as-root "node/$node"Im Debug-Pod ausführen
chroot /host mkdir -p /home/core/assets/etcd-backup /usr/local/bin/cluster-backup.sh /home/core/assets/etcd-backup ls -lh /home/core/assets/etcd-backup exit exit
| Datei | Herkunft | Bedeutung |
|---|---|---|
snapshot_<zeit>.db | wird generiert | etcd-Datenbank mit dem Clusterzustand |
static_kuberesources_<zeit>.tar.gz | wird generiert | Static-Pod-Ressourcen, die der Restore zusätzlich benötigt |
/home/core/assets/etcd-backup/ | wichtig | Zwischenablage auf der Node-Disk. Noch keine externe Sicherung |
9 Backup außerhalb des Clusters sichern
Eine Datei auf derselben SNO hilft nicht bei Node- oder Disk-Verlust. Kopiere beide erzeugten Dateien auf den Laptop und danach in deinen verschlüsselten Backup-Speicher.
$node = oc get node -l node-role.kubernetes.io/control-plane -o jsonpath='{.items[0].metadata.name}'
$nodeIp = oc get node $node -o jsonpath='{.status.addresses[?(@.type=="InternalIP")].address}'
$destination = ".\backups\etcd-$(Get-Date -Format yyyyMMdd-HHmmss)"
New-Item -ItemType Directory -Path $destination -Force
scp -r "core@${nodeIp}:/home/core/assets/etcd-backup/*" $destination
Get-ChildItem -LiteralPath $destination
Get-FileHash -Algorithm SHA256 -Path "$destination\*"Bash-Variante anzeigen
node=$(oc get node -l node-role.kubernetes.io/control-plane -o jsonpath='{.items[0].metadata.name}')
node_ip=$(oc get node "$node" -o jsonpath='{.status.addresses[?(@.type=="InternalIP")].address}')
destination="./backups/etcd-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$destination"
scp -r "core@${node_ip}:/home/core/assets/etcd-backup/." "$destination/"
find "$destination" -maxdepth 1 -type f -print
sha256sum "$destination"/*Falls die ermittelte InternalIP vom Laptop nicht erreichbar ist, verwendest du stattdessen die erreichbare Tailscale- oder Host-Adresse desselben Nodes. Der Node-Name und die Zieladresse müssen weiterhin zum gleichen Control-Plane-Node gehören.
Der Ordner backups/etcd-<zeit>/ wird von dir angelegt. Er gehört nicht ins Git-Repository. Der Snapshot enthält Clusterobjekte und damit möglicherweise Secrets. Verschlüssele und schütze ihn wie Zugangsdaten.
Restore hier nicht üben: cluster-restore.sh ersetzt den Zustand der Steuerungsebene und startet Static Pods neu. Das ist ein Disaster-Recovery-Vorgang für ein Wartungsfenster oder einen isolierten Übungscluster, kein Gesundheitstest für die laufende SNO.
10 Die drei Sicherungsarten nicht verwechseln
| Sicherung | enthält | enthält nicht | typischer Zweck |
|---|---|---|---|
| etcd-Backup | API-Objekte und Static-Pod-Ressourcen | PV-Inhalte, externe Datenbanken und Registry-Blobs | Control-Plane-Restore derselben z-Stream-Version |
| gestoppter Hetzner-Disk-Snapshot | gesamte Node-Disk einschließlich etcd und lokaler PVs | externe Systeme und spätere Änderungen | pragmatisches Wiederaufwecken der SNO mit sno.ps1 |
| Anwendungsbackup | Datenbank-Dumps, Objekte und fachliche Daten | Clusterkonfiguration | einzelne Anwendung wiederherstellen oder migrieren |
- Logs sind keine Backups. Sie erklären Ereignisse, stellen aber keinen Zustand wieder her.
- MachineConfig ist gewünschte Node-Konfiguration. Sie sichert keine Daten und gehört als selbst angelegtes Manifest ins Git.
- etcd-Backup ist versionsgebunden. Dokumentiere die genaue Cluster-Version zusammen mit den Prüfsummen.
- Ein SNO-Snapshot ersetzt keine externe Kopie. Provider-, Konto- oder Regionsverlust bleibt sonst derselbe Ausfallbereich.
11 Lernkontrolle
- Du kannst erklären, warum
oc logsauch ohne Loki funktioniert und wann die Logzeile verloren geht. - Du erkennst Logging-6-Ressourcen und verwechselst sie nicht mit der früheren Fluentd- und Elasticsearch-Architektur.
- Du kannst
currentConfig,desiredConfigundrendered-master-…eines Nodes zusammenführen. - Du weißt, warum ein echtes MachineConfig-Apply auf einer SNO einen Wartungsfall auslösen kann.
- Du kannst die zwei erzeugten etcd-Backup-Dateien benennen und ihren Speicherort außerhalb des Clusters nachweisen.
- Du kannst etcd-, Disk- und Anwendungsbackup voneinander abgrenzen.