← Übersicht  ·  Skripte & Dateien  ·  OpenShift · Operatoren · TLS

Operator-Reconcile und Service-Zertifikate

Du erzeugst mit einer Service-Annotation einen internen TLS-Schlüssel, löschst ihn absichtlich und beobachtest, wie der eingebaute Service-CA-Operator den Sollzustand wiederherstellt. Danach injizierst du die passende CA in eine eigene ConfigMap. Optional folgt eine echte ArgoCD-Custom-Resource.

Stand: 5. September 2026OKD / OCP 4.xAtlas D1, D5, F5ca. 35 Minuten

1 Das Reconcile-Modell

Ein Operator führt nicht nur einmal Befehle aus. Er vergleicht fortlaufend Soll und Ist und korrigiert Abweichungen.

Ein Operator ist ein eigener Controller plus eine CRD. Die CRD führt einen neuen Objekttyp ein (z. B. Kafka), eine Custom Resource davon ist der Sollzustand. Der Operator läuft in einer Reconcile-Schleife: Custom Resources beobachten, mit der Realität vergleichen, handeln – er kodiert das Betriebswissen, das sonst ein Admin von Hand anwendet.

Ein Controller, der einen eigenen Objekttyp verwaltet – und ihn am Leben hält. CRD – führt den Typ ein CustomResourceDefinition registriert kind: Kafka danach ist Kafka gleichwertig zu Pod (A3) oc get crd, oc explain kafka.spec Schema + Versionen + Validierung stecken in der CRD wird generiert von OLM beim Installieren (D2) Custom Resource – der Sollzustand du legst an (oder Helm/GitOps) kind: Kafka spec: {replicas: 3, version: "3.7"} nur was, nicht wie – das Wie kennt der Operator Operator ein Controller-Deployment im Cluster Reconcile-Schleife, endlos: 1 Custom Resources beobachten (watch) 2 Ist gegen Soll vergleichen 3 handeln: anlegen, ändern, löschen reagiert auch auf Pod-Ausfälle, Zeit, externe Events schreibt status.conditions zurück in die CR Go (Operator SDK) · Ansible · Helm-basiert die Realität – was der Operator baut StatefulSet(s) für die Broker (B1) headless Services je Replica (B3) ConfigMaps, Secrets, PVCs (B8/G3) Routes, PodDisruptionBudgets, Rollen (A5) dazu Betriebsaufgaben: rollende Version-Upgrades, Rebalancing, Backups Wiederherstellung, Zertifikat-Rotation alles gehalten per ownerReferences auf die CR CR löschen → der ganze Satz fällt weg (Garbage Collection) ziehst du an einem StatefulSet, dreht es der Operator zurück – die CR ist die einzige Wahrheit beobachtet kennt das Schema gleicht ab Ist-Zustand zurück in die Schleife Operator vs Helm – der Unterschied Helm (B11/B12): rendert, wendet an, hört auf – Drift erst beim nächsten upgrade Operator: läuft im Cluster, gleicht ständig ab, reagiert auf Ausfälle und Zeit Faustregel: einmaliges Deploy → Helm. Etwas, das betrieben werden muss → Operator viele Operatoren nutzen intern selbst ein Helm-Chart als Vorlage – plus die Schleife obendrauf wo Helm aufhört und ein Operator anfängt: B12 Capability Levels I–V – wie viel der Operator abnimmt I Basic Install · II Seamless Upgrades · III Full Lifecycle (Backup/Restore) IV Deep Insights (Metriken, Alerts) · V Auto Pilot (Auto-Scaling, Auto-Tuning) im OperatorHub (D3) steht das Level je Operator – sagt, wie viel du selbst noch machst Bibliothek: Kafka-, Postgres-, Keycloak-Operator verwalten die zustandsbehafteten Teile die 8 zustandslosen Spring-Dienste brauchen keinen Operator – ein Deployment reicht Merksatz: CRD = neuer Typ, Custom Resource = Sollzustand, Operator = die Schleife, die ihn Realität werden lässt und hält wie ein Operator installiert wird (OLM): D2 · hands-on eine Custom Resource anlegen und den Reconcile beobachten: D5 OCP-Unterschied: das Operator-Muster ist Kubernetes – OpenShift liefert OLM (D2) und OperatorHub (D3) mit, in Kubernetes pur muss man beides nachrüsten.
Ein Admin als Code. Eine CRD führt einen neuen Objekttyp ein, eine Custom Resource davon ist der Sollzustand („drei Broker, Version 3.7“). Der Operator ist ein Controller im Cluster, der in einer Reconcile-Schleife die Custom Resources beobachtet, mit der Realität vergleicht und handelt – StatefulSets anlegen, Version-Upgrades rollen, Backups fahren. Anders als Helm (B11) wendet er nicht einmal an, sondern gleicht ständig ab. Die CR ist die einzige Wahrheit – ziehst du direkt am StatefulSet, dreht der Operator es zurück.
  • ein Operator ist ein Controller plus eine CRD – die CRD führt einen neuen Objekttyp ein (kind: Kafka), danach gleichwertig zu Pod (A3)
  • eine Custom Resource dieses Typs ist der Sollzustand – nur was (spec.replicas: 3), nicht wie
  • der Operator läuft in einer Reconcile-Schleife – Custom Resources beobachten, Ist gegen Soll vergleichen, handeln, endlos
  • er reagiert auch auf Pod-Ausfälle, Zeit und externe Events, nicht nur auf CR-Änderungen – das ist der Unterschied zu einem einmaligen Deploy
  • was er baut: StatefulSets, Services, ConfigMaps, PVCs, Rollen – alles per ownerReferences an die CR gebunden, CR weg = alles weg
  • die CR ist die einzige Wahrheit – änderst du direkt am StatefulSet, dreht der Operator es beim nächsten Reconcile zurück
  • Unterschied zu Helm (B11): Helm rendert einmal und hört auf, der Operator gleicht ständig ab und heilt Drift
  • Faustregel: einmaliges Deploy → Helm, etwas das betrieben werden muss → Operator
  • Capability Levels I–V – Basic Install, Seamless Upgrades, Full Lifecycle (Backup/Restore), Deep Insights, Auto Pilot – im OperatorHub je Operator angegeben (D3)
  • Bibliothek heute: Postgres, Redis, Kafka, Keycloak laufen als Bitnami-Helm-Charts, nicht als Operatoren – einmal helm upgrade, danach kein Abgleich und keine Selbstheilung
  • der Operator wäre der nächste Schritt für Kafka oder Postgres, sobald Backup, Failover oder Rebalancing (Capability Level III+) gebraucht werden
  • die 8 Spring-Dienste + config-server sind einfache Deployments – kein Operator, kein StatefulSet, die brauchen nur ein Rolling Update
  • Befehle: oc get crd, oc api-resources, oc explain kafka.spec, oc get kafka -o yaml (Feld status)
  • OCP-Unterschied: das Muster ist Kubernetes – OpenShift liefert OLM (D2) und OperatorHub (D3) mit, reines Kubernetes muss beides nachrüsten
SollEin Kubernetes-Objekt beschreibt das gewünschte Ergebnis: hier eine Service-Annotation, später optional eine ArgoCD-CR.
WatchDer Controller beobachtet passende Objekte und Ereignisse.
VergleichExistiert das angeforderte Secret? Ist die CA-ConfigMap befüllt?
ReconcileFehlt etwas, erzeugt oder aktualisiert der Controller es. Danach beginnt die Schleife erneut.

Warum zwei Teile? Der Service-CA-Operator ist bereits Teil von OpenShift und zeigt die Schleife ohne zusätzliche Installation. Er nutzt hier eine normale Service-Annotation statt einer CRD. Der optionale ArgoCD-Teil ergänzt anschließend das klassische Muster CRD → Custom Resource → Operator.

2 Cluster prüfen

Du brauchst einen angemeldeten Benutzer, der ein Projekt anlegen darf. Prüfe zuerst den ClusterOperator und seine Namespaces.

Laptop · PowerShell oder Bash
oc whoami
oc get co service-ca
oc get pods -n openshift-service-ca
oc get pods -n openshift-service-ca-operator

Erwartung: service-ca ist Available=True und Degraded=False. Bei einem anderen Zustand erst mit Schritt 6 diagnostizieren.

3 Sollzustand anlegen

Der Service fordert über eine Annotation ein Serving-Certificate an. Eine getrennte ConfigMap fordert das Trust-Bundle an.

Laptop · PowerShell
oc new-project operator-reconcile-lab

@'
apiVersion: v1
kind: Service
metadata:
  name: echo-tls
  annotations:
    service.beta.openshift.io/serving-cert-secret-name: echo-tls
spec:
  selector:
    app: echo
  ports:
    - name: https
      port: 8443
      targetPort: 8443
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: service-ca-bundle
  annotations:
    service.beta.openshift.io/inject-cabundle: "true"
'@ | oc apply -f -
Bash-Variante anzeigen
Laptop · Bash
oc new-project operator-reconcile-lab

oc apply -f - <<'EOF'
apiVersion: v1
kind: Service
metadata:
  name: echo-tls
  annotations:
    service.beta.openshift.io/serving-cert-secret-name: echo-tls
spec:
  selector:
    app: echo
  ports:
    - name: https
      port: 8443
      targetPort: 8443
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: service-ca-bundle
  annotations:
    service.beta.openshift.io/inject-cabundle: "true"
EOF

Für die Zertifikaterzeugung muss hinter dem Service noch kein Pod laufen. Der leere Selector ist für dieses Lab in Ordnung. Echte TLS-Verbindungen benötigen später natürlich einen Endpoint und einen Prozess, der tls.crt und tls.key einliest.

Wichtig: Verwende für inject-cabundle eine eigene ConfigMap. Beim Injizieren ersetzt der Operator vorhandene Daten in dieser ConfigMap.

4 Ergebnis lesen

Aus zwei Annotationen entstehen zwei verwaltete Ergebnisse. Lies Metadaten und Schlüssel, aber gib den privaten Schlüssel nicht aus.

Laptop · PowerShell oder Bash
oc get service,secret,configmap -n operator-reconcile-lab
oc describe secret echo-tls -n operator-reconcile-lab
oc get configmap service-ca-bundle -n operator-reconcile-lab -o yaml
oc get service echo-tls -n operator-reconcile-lab -o yaml
Eingabevom Operator erzeugtes Ergebnisentscheidende Daten
Service-Annotation serving-cert-secret-nameSecret echo-tls vom Typ kubernetes.io/tlstls.crt, tls.key
ConfigMap-Annotation inject-cabundleaktualisierte ConfigMap service-ca-bundleservice-ca.crt

Das Zertifikat ist für den internen Servicenamen gedacht, zum Beispiel echo-tls.operator-reconcile-lab.svc. Die CA-ConfigMap kommt in den Client-Pod. Das TLS-Secret wird in den Server-Pod gemountet.

5 Drift erzeugen und Rotation beobachten

Das Secret ist abgeleiteter Ist-Zustand. Löschen ist hier eine kontrollierte Störung und löst eine neue Abstimmung aus.

Eine Annotation am Service genügt: der Service-CA-Operator legt ein kubernetes.io/tls-Secret an, mit einem Zertifikat für <svc>.<ns>.svc, signiert von der cluster-internen Service-CA und automatisch erneuert. Der Gegenüber vertraut ihr über service-ca.crt. Das ist für Pod-zu-Pod-TLS, reencrypt-Routes (B4) und Webhooks – nicht für den Browser.

Eine Annotation am Service → ein fertiges TLS-Secret, von der Cluster-CA signiert, selbsterneuernd. 1 · du annotierst den Service kind: Service metadata: name: catalog annotations: service.beta.openshift.io/ serving-cert-secret-name: catalog-tls mehr ist auf deiner Seite nicht zu tun kein CSR, kein Key erzeugen, kein Ablaufdatum pflegen Bibliothek: am catalog- und am keycloak-Service 2 · der Service-CA-Operator legt an Secret catalog-tls type: kubernetes.io/tls tls.crt tls.key SAN: catalog.bib.svc und catalog.bib.svc.cluster.local signiert von der cluster-internen Service-CA gültig ~2 Jahre, vor Ablauf automatisch erneuert löschst du das Secret, wird es neu erzeugt 3 · der Gegenüber vertraut der CA ConfigMap annotieren: service.beta.openshift.io/inject-cabundle: "true" → Operator schreibt service-ca.crt hinein Client-Pod mountet die ConfigMap als CA-Bundle CA rotiert ~alle 13 Monate – das neue Bundle kommt automatisch bei den Consumern an gleiche Annotation geht auf ein ValidatingWebhook, APIService, CRD-conversion-Feld wofür man es nimmt reencrypt-Route (B4): der Router spricht per HTTPS zum Pod, destinationCACertificate = Service-CA Webhook-Server (Validating/Mutating) – die API verlangt HTTPS mit vertrauter CA Prometheus-Scrape über HTTPS, Operator-Metriken, andere In-Cluster-Endpunkte Pod-zu-Pod: App → DB, App → interner Dienst mit echtem TLS statt Klartext Kurz: überall, wo zwei Sachen innerhalb des Clusters TLS sprechen sollen leichter als cert-manager (B4), wenn dir die interne CA als Vertrauensanker reicht wofür nicht nicht für Browser-TLS an der Route kein Browser kennt die Service-CA → Warnung öffentliches TLS = Ingress-Cert / cert-manager (B4) SAN ist nur *.svc – kein externer DNS-Name nicht zwischen Clustern nutzbar (CA je Cluster) CA-Neustart-Rotation: Pods ggf. neu rollen Merksatz: serving-cert-secret-name erzeugt den Server-Cert, inject-cabundle verteilt die CA zum Vertrauen – beide vom selben Operator, beide selbsterneuernd nachsehen: oc get secret catalog-tls -o yaml · oc get co service-ca · CA in openshift-service-ca / openshift-config-managed oc get configmap <cm> -o jsonpath='{.data.service-ca\.crt}' zeigt das injizierte Bundle OCP-Unterschied: der Service-CA-Operator ist OpenShift-eigen – unter Kubernetes pur nimmt man cert-manager mit einem internen Issuer oder rollt eine eigene CA.
Eine Annotation, ein Secret. service.beta.openshift.io/serving-cert-secret-name am Service lässt den Service-CA-Operator ein kubernetes.io/tls-Secret anlegen – Zertifikat für <svc>.<ns>.svc, signiert von der Cluster-Service-CA, vor Ablauf automatisch erneuert. Der Client vertraut über eine mit inject-cabundle annotierte ConfigMap (service-ca.crt). Gedacht für reencrypt-Routes (B4), Webhooks, Prometheus-Scrapes und Pod-zu-Pod-TLS – nicht für den Browser, der die interne CA nicht kennt.
  • Ziel: TLS für Verkehr innerhalb des Clusters, ohne selbst CSRs, Keys oder Ablaufdaten zu verwalten
  • du annotierst den Service mit service.beta.openshift.io/serving-cert-secret-name und dem gewünschten Secret-Namen – mehr nicht
  • der Service-CA-Operator legt daraufhin ein kubernetes.io/tls-Secret an (tls.crt, tls.key)
  • das Zertifikat gilt für <svc>.<ns>.svc und <svc>.<ns>.svc.cluster.localkeine externen DNS-Namen
  • signiert von der cluster-internen Service-CA, gültig rund 2 Jahre und vor Ablauf automatisch erneuert
  • der Gegenüber vertraut der CA über eine mit service.beta.openshift.io/inject-cabundle annotierte ConfigMap → der Operator schreibt service-ca.crt hinein
  • die CA rotiert etwa alle 13 Monate – das neue Bundle kommt automatisch bei allen Consumern an
  • Verwendung: reencrypt-Route (B4, destinationCACertificate = Service-CA), Webhook-Server, Prometheus-Scrape, Operator-Metriken, Pod-zu-Pod-DB-TLS
  • Bibliothek heute: die 8 Spring-Dienste reden intern per HTTP über die Service-Namen – im Overlay auf einem Node vertretbar, aber unverschlüsselt
  • der Service-CA-Weg dorthin: catalog-service bekommt die Annotation, mountet das TLS-Secret, Spring läuft auf server.sslapi-gateway vertraut über das injizierte service-ca.crt. Kein Let's Encrypt, keine Route beteiligt
  • nicht für Browser-TLS an der Route – kein Browser kennt die Service-CA, das gibt eine Zertifikatswarnung. Die edge-Routes der Bibliothek bleiben Sache der Router-Wildcard (B4)
  • die inject-cabundle-Annotation geht auch auf ValidatingWebhookConfiguration, APIService und CRD-conversion-Felder
  • nachsehen: oc get secret <name> -n library -o yaml, oc get co service-ca – die CA-Objekte liegen in openshift-service-ca und openshift-config-managed
  • OCP-Unterschied: der Service-CA-Operator ist OpenShift-eigen – unter Kubernetes pur nimmt man cert-manager mit internem Issuer oder eine selbstgebaute CA

Terminal 1: beobachten

Laptop · PowerShell oder Bash
oc get secret echo-tls -n operator-reconcile-lab --watch

Terminal 2: UID merken und Secret löschen

Laptop · PowerShell
$before = oc get secret echo-tls -n operator-reconcile-lab -o jsonpath='{.metadata.uid}'
oc delete secret echo-tls -n operator-reconcile-lab
for ($i = 0; $i -lt 60; $i++) {
  $after = oc get secret echo-tls -n operator-reconcile-lab -o jsonpath='{.metadata.uid}' 2>$null
  if ($LASTEXITCODE -eq 0 -and $after) { break }
  Start-Sleep -Seconds 1
}
if (-not $after) { throw "Secret wurde nicht innerhalb von 60 Sekunden neu erzeugt." }
"vorher: $before"
"nachher: $after"
Bash-Variante anzeigen
Laptop · Bash
before=$(oc get secret echo-tls -n operator-reconcile-lab -o jsonpath='{.metadata.uid}')
oc delete secret echo-tls -n operator-reconcile-lab
after=''
for i in $(seq 1 60); do
  after=$(oc get secret echo-tls -n operator-reconcile-lab -o jsonpath='{.metadata.uid}' 2>/dev/null) && break
  sleep 1
done
test -n "$after" || { echo 'Secret wurde nicht innerhalb von 60 Sekunden neu erzeugt.' >&2; exit 1; }
printf 'vorher: %s\nnachher: %s\n' "$before" "$after"

Beweis: Das Secret erscheint wieder und hat eine andere UID. Du hast keinen Erzeugungsbefehl wiederholt. Der Operator hat die fehlende Realität aus dem weiterhin vorhandenen Sollzustand rekonstruiert. Das ist zugleich die manuelle Rotation eines Service-Zertifikats.

6 Vom Ergebnis zum Controller zurückverfolgen

Status, Events und Logs beantworten drei verschiedene Fragen: Ist der ClusterOperator gesund? Was geschah im Projekt? Was meldet der Controller selbst?

Laptop · PowerShell oder Bash
oc get co service-ca -o yaml
oc get events -n operator-reconcile-lab --sort-by=.lastTimestamp
oc get deploy,pods -n openshift-service-ca
oc logs -n openshift-service-ca deployment/service-ca --since=10m

Falls der Deployment-Name in deiner Version abweicht, zuerst mit oc get deploy -n openshift-service-ca ermitteln und dann an oc logs deployment/<name> übergeben.

EbeneFrageBefehl
ClusterOperatorIst die Plattformfunktion verfügbar oder degradiert?oc get co service-ca
NamespaceWelche Objektänderungen wurden sichtbar?oc get events -n operator-reconcile-lab
ControllerWarum konnte ein Reconcile nicht abgeschlossen werden?oc logs -n openshift-service-ca deployment/service-ca --since=10m

7 Optional: eine echte Custom Resource

Nur ausführen, wenn OpenShift GitOps bereits installiert ist. Dieser Teil kann auf einer kleinen SNO zusätzliche CPU und RAM belegen.

Jetzt der Nutzen aus D1–D4. Du legst eine Custom Resource an (kind: Kafka, spec.replicas: 3) und siehst zu, wie der Operator daraus StatefulSets, Services und ConfigMaps baut. Änderst du die CR, gleicht er nach. Löschst du sie, räumt er alles weg.

Du schreibst die CR – der Operator baut und hält den ganzen Satz. 1 · Custom Resource anlegen apiVersion: kafka.strimzi.io/v1beta2 kind: Kafka metadata: {name: events, namespace: library} spec: {kafka: {replicas: 3, version: "3.7"}} oc apply -f kafka.yaml das Schema prüft die CRD (D1) – Tippfehler in spec = sofort abgewiesen Beispiel-CRs liefert die CSV mit (oc get csv <n> -o jsonpathalm-examples) Operator 2 · reconcile sieht die neue CR, liest spec rechnet aus, was fehlt legt die Objekte an, in Reihenfolge schreibt status.conditions zurück in die CR Ready: True / Reconciling: True 3 · was entsteht (Label des Operators) StatefulSet events-kafka – 3 Broker-Pods mit stabiler Identität (B1) headless Service events-kafka-brokers – ein DNS-Name je Pod (B3) Service events-kafka-bootstrap – der Einstiegspunkt für Clients ConfigMaps (Broker-Config), Secrets (TLS), PVCs je Broker (G3) PodDisruptionBudget, NetworkPolicy, RBAC alles mit ownerReferences auf die Kafka-CR beobachten: oc get kafka,statefulset,svc,pvc -l strimzi.io/cluster=events -w der Operator managt auch die Broker-Rolling-Updates bei Version-Wechsel plus: KafkaTopic- und KafkaUser-CRs für Topics und Zugänge watch apply 4 · ändern und löschen CR auf replicas: 5 patchen → der Operator skaliert das StatefulSet hoch und rebalanced CR löschen → der ganze Satz fällt weg (Garbage Collection über ownerReferences) direkt am StatefulSet ziehen → der Operator dreht es beim nächsten Reconcile zurück (D1) Bibliothek / cloud-host eine Kafka-CR für das Event-Rückgrat, eine PostgresCluster-CR für die DB KafkaTopic-CRs je Fachdomäne – die Topics stehen dann auch im Git (E3) die 8 Spring-Dienste bleiben normale Deployments – kein Operator nötig Merksatz: CR anlegen → Operator reconciled → ein ganzer Objektsatz → CR ändern skaliert, CR löschen räumt weg Debugging: oc describe kafka events (Events + Conditions), oc logs deploy/<operator> -n <ns> OCP-Unterschied: keiner – sobald der Operator (D2/D3) läuft, ist das reine Custom-Resource-Mechanik, in OKD und OCP gleich.
Die CR ist der ganze Auftrag. Du schreibst kind: Kafka, spec.replicas: 3 und oc apply. Der Operator sieht die CR, rechnet aus, was fehlt, und legt StatefulSets, headless Services, ConfigMaps, Secrets und PVCs an – alles per ownerReferences an die CR gebunden. Er schreibt status.conditions zurück. replicas: 5 → er skaliert. CR löschen → alles fällt weg. Direkt am StatefulSet ziehen → er dreht es zurück.
  • du legst eine Custom Resource an (oc apply -f kafka.yamlkind: Kafka, spec.kafka.replicas: 3) – das Schema prüft die CRD (D1)
  • Beispiel-CRs liefert die CSV mit (Annotation alm-examples) – ein guter Startpunkt
  • der Operator reconciled – sieht die CR, rechnet aus was fehlt, legt die Objekte in Reihenfolge an
  • was entsteht: StatefulSets (B1), headless Services (B3), ConfigMaps, Secrets, PVCs (G3), PDB, NetworkPolicy, RBAC
  • alles mit ownerReferences auf die CR – CR löschen räumt den ganzen Satz weg (Garbage Collection)
  • der Operator schreibt status.conditions zurück in die CRReady: True, Reconciling: True
  • wo die Operator-Config liegt: in der CR selbst (oc get kafka events -o yaml), nicht in einer ConfigMap – die ConfigMaps darunter erzeugt und überschreibt der Operator
  • CR ändern (replicas: 5) → der Operator skaliert die StatefulSets hoch und rebalanced – beim Helm-Chart wäre das values.yaml + helm upgrade
  • direkt am StatefulSet ziehen → der Operator dreht es beim nächsten Reconcile zurück – die CR ist die einzige Wahrheit (D1)
  • nur der Operator merkt, wenn ein Broker wegfällt, und ersetzt ihn – das Bitnami-Helm-Chart tut das nicht
  • oft bringt der Operator weitere CRDs mit (KafkaTopic, KafkaUser) – auch die gehören dann ins Git (E3)
  • Bibliothek heute: keine Operator-CRs – Kafka und Postgres kommen aus Bitnami-Helm-Charts. Der Umbau wäre helm uninstall, Strimzi-Operator, eine Kafka-CR – und die Helm-Werte weichen CRD-Feldern
  • Debugging: oc describe kafka events (Events + Conditions), oc logs deploy/<operator> -n <ns>
  • OCP-Unterschied: keiner – sobald der Operator läuft, ist das reine Custom-Resource-Mechanik
  • von Hand durchspielen: Reconcile beobachten – ein verwaltetes TLS-Secret löschen und seine Neuerzeugung beweisen; optional danach eine ArgoCD-Custom-Resource anlegen

Die Installation des Operators steht in Einen Operator installieren mit OLM. Prüfe anschließend API und Schema, statt eine Version blind anzunehmen:

Laptop · PowerShell
oc api-resources | Select-String -Pattern 'argocd'
oc explain argocd
oc explain argocd.spec.server.route
Bash-Variante anzeigen
Laptop · Bash
oc api-resources | grep -i argocd
oc explain argocd
oc explain argocd.spec.server.route

Wenn argocds.argoproj.io vorhanden ist und oc explain die Felder bestätigt, lege eine minimale CR an:

Laptop · PowerShell
oc new-project argocd-reconcile-lab

@'
apiVersion: argoproj.io/v1beta1
kind: ArgoCD
metadata:
  name: lab
  namespace: argocd-reconcile-lab
spec:
  server:
    route:
      enabled: false
'@ | oc apply -f -

oc get argocd lab -n argocd-reconcile-lab -o yaml
oc get deploy,pods,service -n argocd-reconcile-lab --watch

Hier ist die ArgoCD-CR der Sollzustand. Der GitOps-Operator erzeugt daraus Deployments, Pods, Services, Secrets und Statusbedingungen. Vergleiche metadata.generation mit status und prüfe die ownerReferences eines erzeugten Objekts.

Laptop · PowerShell oder Bash
oc get argocd lab -n argocd-reconcile-lab -o jsonpath='{.metadata.generation}{"\n"}{.status}{"\n"}'
oc get deployment -n argocd-reconcile-lab -o yaml

Versionsgrenze: CRD-Schema und erzeugte Namen können sich zwischen GitOps-Versionen ändern. Deshalb sind oc api-resources und oc explain Teil des Labs und kein optionales Beiwerk.

8 Grenzen und typische Fallen

Symptom oder AnnahmeEinordnung
„Das Zertifikat kann ich an einer öffentlichen Route verwenden.“Nein. Es ist für clusterinterne Service-DNS-Namen und die OpenShift Service CA gedacht, nicht für öffentliche Browser-Vertrauensketten.
Die ConfigMap enthält meine alten Schlüssel nicht mehr.Die CA-Injektion ersetzt vorhandene Daten. Immer eine dedizierte ConfigMap verwenden.
Ich editiere das generierte Secret direkt.Das ist Ist-Zustand. Ändere den anfordernden Service oder rotiere durch Löschen des Secrets.
Der Service hat keine Endpoints.Für die Zertifikaterzeugung okay. Für eine echte Verbindung muss der Selector passende Pods finden.
Service CA wurde über OLM installiert.Nein. Sie ist ein eingebauter ClusterOperator der OpenShift-Plattform.
Eine ArgoCD-CR bleibt ohne Pods.CRD, Operator-Pods, Namespace-Scope, CR-Status und Operator-Logs prüfen.

9 Sauber aufräumen

Beide Labs sind in eigenen Projekten isoliert. Das Löschen der Projekte entfernt ihre erzeugten Ressourcen.

Laptop · PowerShell oder Bash
oc delete project operator-reconcile-lab

# nur falls der optionale ArgoCD-Teil ausgeführt wurde:
oc delete project argocd-reconcile-lab

Der OpenShift-GitOps-Operator selbst bleibt installiert. Wenn du auch ihn entfernen möchtest, folge dem Aufräumabschnitt der OLM-Anleitung.

10 Lernkontrolle

  • Du kannst Sollzustand, Watch, Ist-Vergleich und Reconcile an den konkreten Objekten zeigen.
  • Du kannst erklären, warum das gelöschte Secret wiederkommt und warum sich seine UID ändert.
  • Du kennst die Rollen von tls.crt, tls.key und service-ca.crt.
  • Du verwechselst interne Serving-Certificates nicht mit öffentlichem Route-TLS.
  • Du kannst vor dem Anlegen einer CR API-Ressource und Schema mit oc api-resources und oc explain prüfen.
⌂ Cockpit