← Übersicht  ·  Skripte & Dateien  ·  cloud-host · OpenShift · Betrieb

Cluster-Betrieb in OpenShift

Die Zeichnungen dazu stehen hier bei den jeweiligen Schritten. Vier Admin-Themen, ein roter Faden: oc get co ist der erste Griff bei jeder Störung. Hier spielst du ihn von Hand durch – dazu einen ServiceMonitor live anlegen, ein PVC binden sehen, und verstehen, wie ein Upgrade auf einer OKD-SNO wirklich abläuft. EX280-relevant.

Stand: 4. September 2026 OKD 4.x / OCP 4.x ns library

Voraussetzung: ein Cluster mit oc login als Admin, Namespace library. Das User-Workload-Monitoring muss eingeschaltet sein (Schritt 3 zeigt wie).

1 oc get co lesen

Jede Kern-Fähigkeit – auth, ingress, dns, image-registry, monitoring, network, etcd, kube-apiserver… – ist ein ClusterOperator-Objekt, rund 30 Stück, verwaltet vom Cluster Version Operator.

Jede Kern-Fähigkeit des Clusters – Auth, Ingress, DNS, Registry, Monitoring, Netzwerk, etcd, kube-apiserver – ist ein ClusterOperator-Objekt, verwaltet von seinem Operator. Jedes meldet drei Zustände: Available (nutzbar?), Degraded (läuft, aber ungesund?), Progressing (mitten in einer Änderung?). oc get co ist die Gesundheits-Ampel des Clusters.

Die Gesundheits-Ampel: Available · Degraded · Progressing. Available – ist die Funktion nutzbar? True = die Fähigkeit funktioniert (mindestens teilweise) False = Ausfall – z. B. ingress False → keine Route erreichbar das ist der wichtigste der drei Beispiele: authentication, kube-apiserver, etcd, dns, image-registry, monitoring, network, storage rund 30 Stück – oc get co listet alle Degraded – läuft, aber ungesund? True = die Funktion geht (noch), ist aber nicht im Sollzustand z. B. 2 von 3 Registry-Repliken laufen, ein PVC fehlt = untersuchen, nicht ignorieren – wird oft zu Available: False der CVO (G5) blockiert Upgrades, solange irgendein CO Degraded ist die message am CO nennt fast immer den Grund ClusterOperatorDegraded-Alarm feuert an Alertmanager (G1) Progressing – mitten in einer Änderung? True = der Operator rollt gerade etwas aus normal während eines Upgrades (G5) oder einer Konfig-Änderung bleibt es stundenlang True → es hängt, nachsehen gesund im Ruhezustand: Available=True, Degraded=False, Progressing=False dazu Upgradeable=False heißt: erst was tun, dann upgraden einen kaputten ClusterOperator lesen oc get co → welcher ist nicht True/False/False? oc describe co image-registry → die message + Related Objects 2 · in den genannten Namespace: oc get pods -n openshift-image-registry 3 · oc logs des Operator-Pods, oc get events im Operand-Namespace hier fängt jede „der Cluster fühlt sich komisch an“-Untersuchung an die Operator-Ebenen der CVO verwaltet die ~30 Second-Level-Operatoren jeder Second-Level-Operator verwaltet seine Operand-Pods und meldet Status über sein ClusterOperator-Objekt OLM-Operatoren (Block D) sind eine separate Ebene – nicht in oc get co die Konsole: Home → Overview zeigt dieselbe Ampel grafisch Merksatz: Available=False = Ausfall, Degraded=True = untersuchen, Progressing=True = normal beim Upgrade – alle drei falsch/wahr richtig = gesund ein Degraded-CO blockiert das Upgrade (G5) – darum ist oc get co der erste Schritt vor jeder größeren Aktion Alarme dazu: ClusterOperatorDown / ClusterOperatorDegraded an Alertmanager (G1) OCP-Unterschied: identisch – ClusterOperators sind Kern-OpenShift, die Menge ist in OKD und OCP fast gleich.
Die Ampel des Clusters. Jede Kern-Fähigkeit ist ein ClusterOperator-Objekt mit drei Conditions: Available (nutzbar? False = Ausfall), Degraded (läuft, aber nicht im Soll? True = untersuchen), Progressing (mitten in einer Änderung? normal beim Upgrade). oc get co zeigt sie alle – alles True/False/False = gesund. Ein Degraded-Operator blockiert Upgrades. Man liest ihn über die message → den Operand-Namespace → die Pod-Logs.
  • jede Kern-Fähigkeit (auth, ingress, dns, image-registry, monitoring, network, etcd, kube-apiserver…) ist ein ClusterOperator-Objekt – rund 30 Stück, verwaltet vom CVO
  • die volle Liste mit Operand-Namespace und typischen Pods steht in der Tabelle oben – das sind zugleich die Default-Pods, die oc get pods -A auf jedem frischen Cluster zeigt, bevor auch nur eine eigene App läuft
  • auf einer Bare-Metal-SNO wie dieser sind machine-api, machine-approver, cloud-controller-manager, cloud-credential, control-plane-machine-set und baremetal zwar Available, tun aber praktisch nichts – sie sind für Cloud- oder IPI-Installer gedacht, die hier nicht laufen
  • Available: ist die Funktion nutzbar? False = Ausfall (z. B. ingress False → keine Route erreichbar)
  • Degraded: die Funktion geht noch, ist aber nicht im Sollzustand – True = untersuchen, wird oft zu Available: False
  • Progressing: der Operator rollt gerade etwas aus – normal beim Upgrade, aber stundenlang True = es hängt
  • gesund im Ruhezustand: Available=True, Degraded=False, Progressing=False. Upgradeable=False = erst etwas tun, dann upgraden
  • der CVO (G5) blockiert Upgrades, solange irgendein CO Degraded ist
  • einen kaputten CO lesen: oc get co → wer ist nicht True/False/False? → oc describe co <name> für die message
  • dann in den Related Objects-Namespace: oc get pods -n <operand-ns>, oc logs des Operator-Pods, oc get events
  • hier fängt jede „der Cluster fühlt sich komisch an“-Untersuchung an
  • OLM-Operatoren (Block D) sind eine separate Ebene – sie erscheinen nicht in oc get co
  • Alarme dazu: ClusterOperatorDown / ClusterOperatorDegraded an Alertmanager (G1)
  • nach einem sno.ps1 up steht image-registry oft auf Progressing oder Degraded – der Operator hängt an einer Leader-Lease von vor dem Snapshot. sno-wsl.sh remediate (im up eingebaut) räumt das
  • Bibliothek: schlägt ein helm upgrade mit wirren Fehlern fehl, ist der erste Blick oc get co – ist ingress oder authentication Degraded, weil der Cluster nach dem Restore noch nicht durch ist?
  • OCP-Unterschied: identisch – ClusterOperators sind Kern-OpenShift, die Menge ist in OKD und OCP fast gleich
Laptop · Bash
oc get co
oc get co -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.conditions[?(@.type=="Available")].status}{"\t"}{.status.conditions[?(@.type=="Degraded")].status}{"\n"}{end}'
Bedingungbedeutet
Availableist die Funktion nutzbar? False = Ausfall (z. B. ingress False → keine Route erreichbar)
Degradeddie Funktion geht noch, ist aber nicht im Sollzustand – True heißt untersuchen, wird oft zu Available: False
Progressingder Operator rollt gerade etwas aus – normal beim Upgrade, stundenlang True heißt es hängt
UpgradeableFalse = erst etwas tun, dann upgraden

gesund im RuhezustandAvailable=True, Degraded=False, Progressing=False. Der CVO blockiert Upgrades (Schritt 7), solange irgendein CO Degraded ist. OLM-Operatoren (Block D) sind eine separate Ebene – sie erscheinen nicht in oc get co.

2 Einen kaputten ClusterOperator debuggen

Hier fängt jede „der Cluster fühlt sich komisch an“-Untersuchung an.

Laptop · Bash
# wer ist nicht True/False/False?
oc get co | grep -v "True.*False.*False"

# die message lesen:
oc describe co image-registry

# dann in den Related-Objects-Namespace:
oc get pods -n openshift-image-registry
oc logs deployment/cluster-image-registry-operator -n openshift-image-registry --tail=50
oc get events -n openshift-image-registry --sort-by=.lastTimestamp | tail -20

nach sno.ps1 upsteht image-registry oft auf Progressing oder Degraded – der Operator hängt an einer Leader-Lease von vor dem Snapshot. sno-wsl.sh remediate (in sno.ps1 up eingebaut) räumt das automatisch auf.

Alarme zum selben Zustand landen im Alertmanager: ClusterOperatorDown / ClusterOperatorDegraded (Schritt 3).

3 Der Monitoring-Stack

Zwei getrennte Stacks: Plattform-Monitoring (immer an) und User-Workload-Monitoring (opt-in).

OpenShift bringt zwei getrennte Monitoring-Stacks mit. Der Plattform-Stack läuft immer und überwacht die Control Plane, die Nodes und die Operatoren. Der User-Workload-Stack ist opt-in und überwacht deine Apps – du meldest sie mit einem ServiceMonitor an. Beide zeigen im Observe-Tab und alarmieren über Alertmanager.

Zwei Stacks: Plattform (immer) und deine Apps (opt-in). Plattform-Monitoring – openshift-monitoring läuft immer, kann man nicht abschalten, nur tunen (cluster-monitoring-config) Prometheus (Paar, HA) scrapt: kube-apiserver, etcd, kubelet, node-exporter (DaemonSet), kube-state-metrics, jeder Operator Thanos-Querier – fächert eine Abfrage über alle Prometheus-Instanzen Thanos-Ruler – wertet PrometheusRule-Regeln aus Alertmanager – entprellt, gruppiert, leitet Alarme an receivers PagerDuty · Slack · Webhook · E-Mail · OpsGenie Retention lokal ~15 Tage – länger nur mit externem Speicher (Thanos + Objektspeicher) Alarme wie ClusterOperatorDegraded (G6), KubeletDown, TargetDown oc get prometheus,alertmanager -n openshift-monitoring User-Workload-Monitoring – openshift-user-workload-monitoring opt-in: die ConfigMap cluster-monitoring-config setzen data.config.yaml: enableUserWorkload: true ein eigener Prometheus (getrennt vom Plattform-Stack) du meldest deine App an mit einem ServiceMonitor / PodMonitor-CR: Label-Selektor + Pfad + Port + Intervall eigene Alarme: PrometheusRule-CR im Namespace deiner App Bibliothek: ein ServiceMonitor je Spring-Dienst, scrapt /actuator/prometheus Rechte: die Rolle monitoring-edit im Namespace erlaubt eigene Monitore oc get servicemonitor,prometheusrule -n library deine Alarme laufen über denselben Alertmanager wie die Plattform der Observe-Tab der Konsole Metrics – PromQL-Abfragen & Graphen (über den Thanos-Querier) Alerts – was gerade feuert, Silences setzen Dashboards (mitgelieferte Grafana-artige Ansichten) · Targets (wer wird gescrapt, up/down) API auch für oc adm top pods/nodes und den HPA (B6) was schiefgeht TargetDown: Selektor passt nicht, falscher Port, App bietet den Pfad nicht an Prometheus frisst RAM – hohe Kardinalität (zu viele Label-Werte) begrenzen User-Workload-Prometheus ohne PVC → Daten weg beim Neustart Alertmanager-receiver nicht konfiguriert → Alarme feuern ins Leere Merksatz: Plattform-Stack = der Cluster überwacht sich, User-Workload-Stack = du überwachst deine App über einen ServiceMonitor ServiceMonitor = „scrap diese Pods hinter diesem Service“, PrometheusRule = „alarmiere, wenn dieser Ausdruck wahr wird“ Logging ist ein anderer Stack (G2) · Storage für die Metrik-PVCs: G3 OCP-Unterschied: der Stack ist Kern-OpenShift (bei OKD identisch). Reines Kubernetes installiert man den kube-prometheus-Stack von Hand.
Zwei Stacks, ein Alertmanager. Das Plattform-Monitoring (openshift-monitoring) läuft immer und scrapt Control Plane, Nodes und Operatoren; Thanos vereinheitlicht die Abfrage, Alertmanager leitet die Alarme. Das User-Workload-Monitoring ist opt-in (enableUserWorkload: true) und gibt dir einen eigenen Prometheus – du meldest deine App mit einem ServiceMonitor an und schreibst eigene PrometheusRule-Alarme. Beides erscheint im Observe-Tab.
  • OpenShift hat zwei getrennte Stacks: Plattform-Monitoring (immer an) und User-Workload-Monitoring (opt-in)
  • Plattform (openshift-monitoring): Prometheus-Paar scrapt Control Plane, node-exporter-DaemonSet, kube-state-metrics und jeden Operator – nicht abschaltbar, nur tunen
  • Thanos-Querier fächert eine Abfrage über alle Prometheus-Instanzen, Thanos-Ruler wertet die Regeln aus
  • Alertmanager entprellt, gruppiert und leitet Alarme an receivers: PagerDuty, Slack, Webhook, E-Mail
  • User-Workload aktivieren: die ConfigMap cluster-monitoring-config mit enableUserWorkload: true
  • du meldest deine App an mit einem ServiceMonitor (oder PodMonitor): Label-Selektor, Pfad, Port, Intervall
  • eigene Alarme: ein PrometheusRule-CR im Namespace library – etwa up{job="catalog-service"} == 0 für 5 min, über denselben Alertmanager wie die Plattform
  • Rechte: die Rolle monitoring-edit im Namespace erlaubt eigene Monitore und Regeln
  • der Observe-Tab der Konsole: Metrics (PromQL), Alerts (+ Silences), Dashboards, Targets (up/down)
  • auf der SNO: der User-Workload-Prometheus bekommt per Default keine PVC – nach einem sno.ps1 up sind die App-Metriken von vor dem Snapshot weg, eine volumeClaimTemplate im user-workload-monitoring-config hält dagegen
  • was schiefgeht: TargetDown bei falschem Selektor oder Port, hohe Kardinalität frisst RAM, ein unkonfigurierter receiver schluckt Alarme
  • Bibliothek: ein ServiceMonitor je Spring-Dienst auf /actuator/prometheus (Micrometer) – die Bitnami-Charts von Postgres, Kafka und Redis bringen je einen metrics-Exporter mit, den ein eigener ServiceMonitor abholt
  • Merksatz: ServiceMonitor = „scrap diese Pods“, PrometheusRule = „alarmiere bei diesem Ausdruck“
  • auf SNO ohne HA: der ganze Stack läuft (ServiceMonitor, Observe-Tab, Alertmanager) – nur das Prometheus-Paar und echte Ausfallsicherheit fehlen
  • OCP-Unterschied: identisch – der Stack ist Kern-OpenShift. Reines Kubernetes braucht den kube-prometheus-Stack von Hand
Plattformopenshift-monitoring: Prometheus-Paar scrapt die Control Plane, jeden Operator, node-exporter – nicht abschaltbar, nur tunen
ThanosQuerier fächert eine Abfrage über alle Prometheus-Instanzen, Ruler wertet Regeln aus
User-Workloadopt-in über die ConfigMap cluster-monitoring-config – erst danach zählen eigene ServiceMonitore
Laptop · Bash
cat <<'YAML' | oc apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: cluster-monitoring-config
  namespace: openshift-monitoring
data:
  config.yaml: |
    enableUserWorkload: true
YAML

oc get pods -n openshift-user-workload-monitoring -w

4 Einen ServiceMonitor live anlegen

Anmelden bei Prometheus, dann eine eigene Alarmregel.

Laptop · Bash
oc create deployment demo-metrics -n library --image=registry.access.redhat.com/ubi9/httpd-24
oc expose deployment demo-metrics -n library --port=8080

cat <<'YAML' | oc apply -f -
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: demo-metrics
  namespace: library
spec:
  selector:
    matchLabels: { app: demo-metrics }
  endpoints:
    - port: 8080-tcp
      path: /metrics
      interval: 30s
YAML

cat <<'YAML' | oc apply -f -
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: demo-metrics-alerts
  namespace: library
spec:
  groups:
    - name: demo.rules
      rules:
        - alert: DemoTargetDown
          expr: up{job="demo-metrics"} == 0
          for: 5m
          labels: { severity: warning }
          annotations: { summary: "demo-metrics antwortet nicht" }
YAML

oc get servicemonitor,prometheusrule -n library

Im Konsolen-Tab Observe: Metrics (PromQL), Alerts (+ Silences), Dashboards, Targets (up/down – genau hier sieht man, ob der ServiceMonitor wirklich scrapt). Rechte dafür: die Rolle monitoring-edit im Namespace. Merksatz: ServiceMonitor = „scrap diese Pods“, PrometheusRule = „alarmiere bei diesem Ausdruck“.

5 Storage: PVC, StorageClass, RWO/RWX

Ein PersistentVolumeClaim ist der Antrag, eine StorageClass die clusterweite Vorlage.

Ein Pod will einen Datenträger – er stellt einen PersistentVolumeClaim (den Antrag). Eine StorageClass ist die Vorlage, nach der ein PersistentVolume dynamisch entsteht und an den PVC gebunden wird. Der Zugriffsmodus entscheidet, ob mehrere Pods gleichzeitig schreiben dürfen – und die meiste Blockspeicherung kann das nicht.

PVC (Antrag) → StorageClass (Vorlage) → PV (der Datenträger), gebunden. PersistentVolumeClaim du legst an (oder Helm / ein StatefulSet) verlangt: storage: 20Gi accessModes: [ReadWriteOnce] storageClassName: (optional) namespaced – gehört zum Projekt StorageClass – die Vorlage clusterweit · eine ist Default (Annotation) provisioner – welcher CSI-Treiber parameters – Disk-Typ, fsType, Verschlüsselung reclaimPolicyDelete / Retain volumeBindingMode   Immediate vs WaitForFirstConsumer (PV landet in der Zone des Pods) allowVolumeExpansion: true – PVC nachträglich vergrößern CSI-Treiber = ein Operator je Speichersystem (*-csi-driver) PersistentVolume wird generiert (dynamisch) oder statisch angelegt clusterweit, nicht namespaced an genau einen PVC gebunden (Bound) bei Retain bleibt es nach PVC-Löschung (Released) der Pod mountet es über den PVC-Namen nach welcher Class? provisioniert + bindet Zugriffsmodi – wer darf gleichzeitig schreiben RWO (ReadWriteOnce) – ein Node zur Zeit, die meiste Blockspeicherung RWOP (ReadWriteOncePod) – genau ein Pod ROX (ReadOnlyMany) – viele Nodes lesend RWX (ReadWriteMany) – viele Nodes schreibend – braucht ein Netzwerk-FS (NFS, CephFS, ODF) die meiste Block-CSI (AWS EBS, Hetzner Cloud Volume, iSCSI) kann kein RWX ein Deployment mit >1 Replica und einem RWO-PVC → nur ein Pod läuft, der Rest bleibt Pending Snapshots, Erweitern, Atlas-Praxis VolumeSnapshot + VolumeSnapshotClass – Point-in-Time-Kopie, Basis für Backups (Velero) PVC vergrößern: den Wert unter spec.resources.requests.storage hochsetzen (oc edit pvc) nur größer, nie kleiner · nur wenn allowVolumeExpansion Atlas: auf SNO ein local-path-Provisioner (Daten am Node, keine echte HA) der local-path-provisioner-SA bekommt hostmount-anyuid (A7) – echte Cloud-CSI nur an einem echten Cluster oc get sc,pv,pvc · oc describe pvc <n> (Events nennen den Grund für Pending) Merksatz: PVC = Antrag, StorageClass = Vorlage, PV = der Datenträger – und RWX braucht ein Netzwerk-Dateisystem WaitForFirstConsumer ist fast immer richtig – sonst landet das PV in der falschen Zone und der Pod scheduled nie (B6) Bibliothek: Postgres, Kafka, Redis wollen je ein RWO-Block-PVC über ihre StatefulSets (B1) · das Log-Objektspeicher-Backend (G2) ist S3, kein PVC OCP-Unterschied: identisch – CSI ist Kubernetes. OpenShift Data Foundation (ODF/Ceph) ist ein zusätzliches Produkt für RWX + Objektspeicher im Cluster.
Antrag, Vorlage, Datenträger. Ein PVC verlangt Größe und Zugriffsmodus. Die StorageClass sagt, welcher CSI-Treiber mit welchen Parametern ein PV dynamisch erzeugt und daran bindet. volumeBindingMode: WaitForFirstConsumer wartet, bis der Pod geschedult ist, damit das PV in dessen Zone landet. Der Zugriffsmodus entscheidet: RWO = ein Node, RWX = viele – und RWX braucht ein Netzwerk-Dateisystem, das die meiste Blockspeicherung nicht bietet.
  • ein PersistentVolumeClaim ist der Antrag (Größe, accessModes, optional storageClassName) – namespaced
  • eine StorageClass ist die clusterweite Vorlage: provisioner (der CSI-Treiber, kommt als Operator), reclaimPolicy, volumeBindingMode, allowVolumeExpansion
  • dynamisches Provisioning erzeugt ein PersistentVolume und bindet es an den PVC (Bound) – oder es bindet an ein passendes statisches PV
  • volumeBindingMode: WaitForFirstConsumer wartet, bis der Pod geschedult ist – sonst landet das PV in der falschen Zone und der Pod scheduled nie (B6)
  • reclaimPolicy: Delete löscht das PV mit dem PVC, Retain behält es (Released) für manuelle Rettung
  • RWO (ein Node zur Zeit) – die meiste Blockspeicherung. RWOP = genau ein Pod
  • RWX (viele Nodes schreibend) braucht ein Netzwerk-Dateisystem (NFS, CephFS, ODF) – AWS EBS, Hetzner Volume, iSCSI können es nicht
  • ein Deployment mit >1 Replica an einem RWO-PVC → nur ein Pod läuft, der Rest bleibt Pending
  • VolumeSnapshot + VolumeSnapshotClass für Point-in-Time-Kopien (Basis für Velero-Backups, E4)
  • PVC vergrößern geht nur größer, nie kleiner, und nur bei allowVolumeExpansion
  • auf der SNO: ein local-path-Provisioner statt echtem CSI (Daten am Node, keine HA). Sein SA braucht die SCC hostmount-anyuid (A7), und das Basis-Verzeichnis muss chcon -t container_file_t bekommen – SCOS-SELinux lässt sonst auch root dort nicht schreiben
  • Bibliothek: Postgres, Kafka und Redis wollen je ein RWO-Block-PVC über ihre StatefulSets (B1)
  • Stolperstein: der image-registry-Operator will eine RWX-PVC, local-path kann nur RWO – die image-registry-storage-PVC von Hand als RWO vorab anlegen, sonst startet die Registry nicht
  • ein geteiltes Verzeichnis (etwa Buchcover für alle catalog-service-Replicas) bräuchte RWX – mit local-path unmöglich, also Objekt-Storage (MinIO, S3) oder ein NFS-Volume
  • OCP-Unterschied: identisch – CSI ist Kubernetes. OpenShift Data Foundation (Ceph) ist ein Zusatzprodukt für RWX und Objektspeicher im Cluster
Begriffist
PVCAntrag: Grösse, accessModes, optional storageClassName – namespaced
StorageClassprovisioner (der CSI-Treiber), reclaimPolicy, volumeBindingMode, allowVolumeExpansion
RWOein Node zur Zeit – die meiste Blockspeicherung. RWOP = genau ein Pod
RWXviele Nodes schreibend – braucht ein Netzwerk-Dateisystem (NFS, CephFS, ODF). Cloud-Blockspeicher (EBS, Hetzner Volume) kann das nicht

volumeBindingMode: WaitForFirstConsumer wartet, bis der Pod geschedult ist – sonst landet das PV in der falschen Zone und der Pod scheduled nie (B6). reclaimPolicy: Delete löscht das PV mit dem PVC, Retain behält es (Released) für manuelle Rettung.

6 Ein PVC anlegen und binden sehen

Ein Deployment mit zwei Replicas an einem RWO-PVC – und live sehen, warum nur ein Pod läuft.

Laptop · Bash
cat <<'YAML' | oc apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: demo-data
  namespace: library
spec:
  accessModes: [ReadWriteOnce]
  resources: { requests: { storage: 1Gi } }
YAML

oc get pvc demo-data -n library -w
# Pending -> Bound (mit WaitForFirstConsumer erst, sobald ein Pod ihn nutzt)

oc get pv $(oc get pvc demo-data -n library -o jsonpath='{.spec.volumeName}')

Falleein Deployment mit replicas: 2, das denselben RWO-PVC mountet, lässt nur den ersten Pod laufen – der zweite bleibt dauerhaft Pending (oc describe pod zeigt multi-attach error oder „volume is already used“).

PVC vergrössern geht nur grösser, nie kleiner, und nur bei allowVolumeExpansion: true an der StorageClass. VolumeSnapshot/VolumeSnapshotClass sind die Basis für Point-in-Time-Kopien (Velero-Backups, E4).

7 Cluster-Upgrades

Ein Upgrade ist ein Release-Image – der Cluster Version Operator (CVO) gleicht den Cluster darauf ab: erst die ClusterOperatoren in Abhängigkeitsreihenfolge, dann die Nodes (G4).

Ein OpenShift-Upgrade ist ein Ziel: ein Release-Image, das die Manifeste aller Komponenten enthält. Der Cluster Version Operator (CVO) gleicht den ganzen Cluster darauf ab – er geht die ClusterOperatoren der Reihe nach durch, dann rollt der MCO die Nodes. Du wählst nur den Channel und das Ziel, den Rest macht der CVO. Ein Rollback gibt es nicht.

Ein Release-Image, ein CVO, der alles der Reihe nach abgleicht – nur vorwärts. Channel wählen stable-4.16 – getestet, empfohlen fast-4.16 – früher, weniger Vorlauf candidate-4.16 – Vorschau, nicht Prod eus-4.x – gerade Minors, längerer Support der Channel = ein Graph erlaubter Upgrade-Pfade oc adm upgrade channel stable-4.16 Cluster Version Operator reconciled den Cluster auf ein Release-Image (ein Digest: alle Component-Manifeste + Operator-Images) geht die ClusterOperatoren in Abhängigkeitsreihenfolge durch jeder Operator hebt sein Operand-Deployment (G6) dann rollt der MCO die Nodes (G4) – darum dauert es oc get clusterversion zeigt Fortschritt in Prozent Vorbedingungen & Regeln kein ClusterOperator Degraded (G6) – sonst blockiert der CVO alle PodDisruptionBudgets erfüllbar, genug Kapazität für drain admin-acks bestätigen: bekannte Breaking Changes zwischen Minors deprecated APIs prüfen (APIRemovedInNextReleaseInUse-Alarm) kein Rollback – nur vorwärts, in einer niedrigeren Umgebung testen immer nur ein Minor auf einmal (4.15 → 4.16, nicht 4.15 → 4.17) der Ablauf in Befehlen oc adm upgrade zeigt aktuelle Version + verfügbare Ziele oc adm upgrade --to=4.16.7 oder --to-latest Fortschritt: oc get clusterversion -w, oc get co (was ist noch Progressing) Console: Administration → Cluster Settings → Update (mit Fortschrittsbalken) nach Start: nicht abbrechen – ein halb-upgradeter Cluster ist der schlechteste Zustand EUS-zu-EUS (4.14 → 4.16) Worker-Pools paused (G4) → die Control Plane über 4.15 auf 4.16 hopsen → dann Worker-Pools entpausen → sie springen direkt auf 4.16 spart einen kompletten Node-Rollout-Zyklus EUS = Extended Update Support, gerade Minors (4.14, 4.16…), ~24 Monate für Cluster, die selten upgraden dürfen – nicht der Normalfall Merksatz: du wählst Channel + Ziel, der CVO gleicht alles ab (Operatoren zuerst, dann Nodes), Rollback gibt es nicht ein Degraded-ClusterOperator (G6) blockiert das Upgrade – darum ist oc get co der erste Schritt der Node-Teil ist G4 (MCO) · die Health-Ampel ist G6 · etcd-Backup vor dem Upgrade: G7 OCP-Unterschied: OCP hat Subscription-gebundene Channels und OpenShift Update Service (OSUS) für disconnected. OKD nutzt eigene, community-gepflegte Update-Graphen.
Ein Ziel, ein Operator, eine Richtung. Der CVO gleicht den ganzen Cluster auf ein Release-Image ab – er hebt die ClusterOperatoren in Reihenfolge, dann rollt der MCO die Nodes (G4). Du wählst den Channel (stable-4.16, eus-4.x…) und das Ziel mit oc adm upgrade --to=. Vorbedingung: kein Degraded-ClusterOperator (G6), admin-acks bestätigt. Ein Rollback wird nicht unterstützt – man testet in einer niedrigeren Umgebung.
  • ein Upgrade ist ein Release-Image – ein Digest mit den Manifesten jeder Komponente und den Operator-Images
  • der Cluster Version Operator (CVO) gleicht den Cluster darauf ab: erst die ClusterOperatoren in Abhängigkeitsreihenfolge, dann rollt der MCO die Nodes (G4)
  • Channels: stable-4.16 (empfohlen), fast, candidate, dazu eus-4.x – jeder Channel ist ein Graph erlaubter Pfade, immer nur ein Minor auf einmal
  • oc adm upgrade zeigt aktuelle Version und verfügbare Ziele, oc adm upgrade --to=4.16.7 startet
  • Vorbedingung: kein ClusterOperator Degraded (G6) – sonst blockiert der CVO
  • admin-acks bestätigen für bekannte Breaking Changes zwischen Minors, deprecated APIs prüfen (APIRemovedInNextReleaseInUse-Alarm)
  • PodDisruptionBudgets müssen erfüllbar sein und genug Kapazität für drain vorhanden
  • kein Rollback – nur vorwärts, in einer niedrigeren Umgebung testen
  • nach dem Start nicht abbrechen – ein halb-upgradeter Cluster ist der schlechteste Zustand
  • Fortschritt: oc get clusterversion -w, oc get co (was ist noch Progressing), oder die Console unter Cluster Settings
  • etcd-Backup vor dem Upgrade (G7) · der Node-Teil ist G4 · die Health-Ampel ist G6
  • real auf der SNO: OKD-SCOS-Update-Graphen sind community-gepflegt und dünn – oft ist der Weg nicht oc adm upgrade, sondern sno.ps1 destroy und dann sno.ps1 install mit der neueren Version (der Rebuild aus dem Plan)
  • wenn doch ein Upgrade: erst sno.ps1 down als Sicherung, dann oc adm upgrade --to, rund 40 min – der eine Node rebootet, die API ist während des Control-Plane-Reboots kurz weg
  • auf SNO ohne HA: ein oc adm upgrade läuft und der CVO geht die COs durch – nur der EUS-Worker-Pool-Tanz braucht Worker
  • OCP-Unterschied: OCP hat Subscription-Channels und OpenShift Update Service (disconnected). OKD nutzt community-gepflegte Update-Graphen
Laptop · Bash
oc get clusterversion
oc adm upgrade
# zeigt aktuelle Version und verfuegbare Ziele
oc adm upgrade --to=4.16.7
oc get clusterversion -w

Vorbedingung: kein ClusterOperator Degraded (Schritt 1), sonst blockiert der CVO. admin-acks bestätigen für bekannte Breaking Changes zwischen Minors, deprecated APIs vorher prüfen. Kein Rollback – nur vorwärts. Nach dem Start nicht abbrechen, ein halb-upgradeter Cluster ist der schlechteste Zustand.

real auf der SNOOKD-SCOS-Update-Graphen sind community-gepflegt und dünn – oft ist der Weg nicht oc adm upgrade, sondern sno.ps1 destroy und dann install mit der neueren Version (der Rebuild aus dem Plan). Wenn doch: erst sno.ps1 down als Sicherung, dann oc adm upgrade --to, rund 40 Min – der eine Node rebootet, die API ist während des Control-Plane-Reboots kurz weg.

OCP-Unterschied: OCP hat Subscription-Channels und den OpenShift Update Service (disconnected). OKD nutzt community-gepflegte Update-Graphen. etcd-Backup vorher (G7).

8 Typische Fallen

Symptommeist
Upgrade startet nichtein ClusterOperator ist Degraded – erst Schritt 2
Targets zeigen „down“falscher Port/Selektor im ServiceMonitor, oder eine NetworkPolicy sperrt den Scrape (F2)
zweiter Replica bleibt PendingRWO-PVC von zwei Pods gleichzeitig verlangt – braucht RWX oder nur 1 Replica
PV in falscher ZonevolumeBindingMode: Immediate statt WaitForFirstConsumer
hohe RAM-Last durch Prometheuszu hohe Kardinalität in eigenen Metrik-Labels

9 Wie die Bibliothek es macht

Bausteinreal
Monitoringein ServiceMonitor je Spring-Dienst auf /actuator/prometheus (Micrometer) – die Bitnami-Charts von Postgres, Kafka und Redis bringen je einen metrics-Exporter mit, den ein eigener ServiceMonitor abholt
StoragePostgres, Kafka und Redis wollen je ein RWO-Block-PVC über ihre StatefulSets – auf der SNO ein local-path-Provisioner statt echtem CSI (Daten am Node, keine HA)
Storage-Stolpersteinder image-registry-Operator will eine RWX-PVC, local-path kann nur RWO – die image-registry-storage-PVC von Hand als RWO vorab anlegen, sonst startet die Registry nicht
SNO ohne HAbei G1/G3/G6 läuft der ganze Stack normal – nur das Prometheus-Paar und echte Ausfallsicherheit fehlen. Bei G5 fehlt vor allem der EUS-Worker-Pool-Tanz, den es ohne Worker-Nodes nicht gibt

Fehlschlag-Reflex: schlägt ein helm upgrade mit wirren Fehlern fehl, ist der erste Blick oc get co – ist ingress oder authentication Degraded, weil der Cluster nach einem sno.ps1 up noch nicht ganz durch ist?

+ Die Kurzfassung

ClusterOperators~30 Objekte, der Gesundheitszustand des Clusters – erster Griff bei jeder Störung
MonitoringServiceMonitor = wen scrapen, PrometheusRule = wann alarmieren – User-Workload ist opt-in
StorageRWO reicht fast immer, RWX nur mit Netzwerk-Dateisystem – WaitForFirstConsumer vor Zonen-Fallen
Upgradesder CVO blockiert bei Degraded, kein Rollback – auf OKD-SNO oft eher ein Rebuild als ein oc adm upgrade
⌂ Cockpit