← Übersicht  ·  Skripte & Dateien  ·  OpenShift · SNO · CRC · Topologie

SNO, CRC und Deploy-Weg praktisch einordnen

Du inventarisierst die lokale CRC-Umgebung, den Hetzner-Single-Node und den Weg einer Anwendung von Git über Jenkins bis OpenShift. Alle Kernschritte lesen nur. So erkennst du sicher, welcher Rechner gerade welche Aufgabe übernimmt und welcher Cluster mit oc angesprochen wird.

Stand: 5. September 2026Windows + OKD / OCP 4.xAtlas 01, 02, 03ca. 40 Minuten

1 Drei Orte, zwei Cluster, ein Deploy-Weg

CRC und SNO sind zwei getrennte OpenShift-Cluster. Git und Jenkins stehen außerhalb beider Cluster und liefern nur Quelltext, Images und Manifeste.

Laptop
CRC-VM mit einem OpenShift-Node
Podman-Maschine mit Jenkins
PowerShell, WSL, oc, Tailscale
Git-Plattform
Anwendungs-Repository und Commit
Webhook oder manueller Pipeline-Start
führt die Anwendung nicht aus
Hetzner
OKD-SNO mit SCOS
Router über Port 80 und 443
SSH und API über Tailscale

Der wichtigste Kontrollpunkt: Vor jedem oc-Befehl musst du wissen, auf welchen API-Server der aktuelle Kontext zeigt. CRC und SNO können dieselben Namespaces und Objektnamen enthalten, ohne denselben Zustand zu teilen.

2 Die Sicherheitsgrenze dieses Labs

Die folgenden Prüfungen starten keinen Cluster, erzeugen keinen Hetzner-Server und führen keinen Deploy aus.

nur lesenändert Zustand oder Kosten
.\scripts\sno.ps1 status, crc status, tailscale statussno.ps1 up, sno.ps1 install, crc start
oc get, oc describe, hcloud server describeoc apply, helm upgrade, hcloud server create
podman machine list, podman ps, podman portpodman machine start, podman run, Pipeline-Start

Nicht ersetzen: Wenn eine Komponente gestoppt ist, notiere den Befund. Starte sie nicht nebenbei. Der ausgeschaltete SNO ist der gewünschte kostensparende Zustand und ein gestartetes CRC reserviert viel Laptop-RAM.

3 Verfügbare Werkzeuge inventarisieren

Laptop · PowerShell · nur lesen
$names = 'oc','crc','hcloud','tailscale','podman','git','wsl'
$names | ForEach-Object {
  $command = Get-Command $_ -ErrorAction SilentlyContinue
  [pscustomobject]@{
    Werkzeug = $_
    Gefunden = [bool]$command
    Pfad = if ($command) { $command.Source } else { '-' }
  }
} | Format-Table -AutoSize

Ein fehlender Befehl bedeutet nur, dass dieser Teil auf dem aktuellen Laptop nicht geprüft werden kann. Es sagt nichts über den Zustand des entfernten Clusters aus.

Repository-Wurzel · PowerShell · Skriptstatus ohne Start
.\scripts\sno.ps1 status
crc status
podman machine list
tailscale status

scripts/sno.ps1 ist der sichere Einstieg für den Hetzner-SNO. Die Aktion status liest Server-, Snapshot- und Erreichbarkeitszustand, ohne den Server anzulegen.

4 Den aktiven OpenShift-Cluster eindeutig erkennen

Kontext bedeutet die Kombination aus Clusteradresse, Benutzer und Standard-Namespace in der lokalen Kubeconfig.

Laptop · PowerShell oder Bash · nur lesen
oc config current-context
oc whoami
oc whoami --show-server
oc get clusterversion version -o custom-columns=VERSION:.status.desired.version,CHANNEL:.spec.channel
oc get infrastructure cluster -o custom-columns=PLATFORM:.status.platformStatus.type,CONTROL-PLANE:.status.controlPlaneTopology,INFRA:.status.infrastructureTopology
oc get ingress.config.openshift.io cluster -o jsonpath='{.spec.domain}{"\n"}'
oc get nodes -o custom-columns=NAME:.metadata.name,ROLES:.metadata.labels,EFFECTIVE-OS:.status.nodeInfo.osImage,KERNEL:.status.nodeInfo.kernelVersion

Berechtigung: Die Infrastruktur-, Ingress- und ClusterOperator-Abfragen brauchen clusterweite Leserechte. Ein Forbidden bei einem Entwicklerkonto bedeutet fehlende Sichtbarkeit und nicht automatisch einen defekten Cluster.

BeobachtungEinordnung
API unter api.crc.testing und App-Domain apps-crc.testingCRC auf diesem Laptop
API-Name mit sno und nip.ioder Hetzner-SNO dieses Repositorys
genau ein Node mit Control-Plane- und Worker-RolleSingle-Node-Topologie, aber noch kein Beweis für CRC oder Hetzner
mehrere Nodes und getrennte RollenMulti-Node-Cluster, weder die lokale CRC noch diese SNO

Wenn mehrere Kontexte vorhanden sind, verwende für Vergleiche oc --context <name> get …. Das ist sicherer als den globalen aktuellen Kontext umzuschalten.

5 Den SNO-Aufbau aus Skript und Ist-Zustand ableiten

Single-Node OpenShift, kurz SNO, vereint Steuerungsebene und Anwendungs-Workloads auf einem Node. Der Hetzner-Weg dieses Repositorys nutzt das Rescue-System als Sprungbrett zu SCOS.

Repository-Wurzel · PowerShell · lokale Dateien nur lesen
Select-String -LiteralPath .\scripts\sno.ps1 -Pattern 'Rescue|ReservedIP|TailscaleHost|Invoke-Install|wait-for'
Select-String -LiteralPath .\scripts\sno-wsl.sh -Pattern 'bootstrap-in-place|wait-for|install-config'
Select-String -LiteralPath .\scripts\sno-kexec.sh -Pattern 'kexec|config.ign|initramfs'
.\scripts\sno.ps1 status
RescueHetzner bootet ein temporäres Linux. Es ist nur Träger für Kernel, Netzwerk und den nächsten Sprung.
kexecDer laufende Kernel startet die SCOS-Live-Umgebung ohne normalen Firmware-Neustart.
IgnitionDie maschinenlesbare Erstkonfiguration beschreibt Platte, Dateien und Systemzustand für den ersten Boot.
BootstrapEine temporäre Steuerungsebene erzeugt die dauerhafte Clusterkonfiguration direkt auf diesem Node.
KonvergenzCluster Version Operator und Cluster Operators bringen API, Netzwerk, Registry und weitere Komponenten in ihren Sollzustand.

SCOS bedeutet CentOS Stream CoreOS und ist das unveränderliche Node-Betriebssystem von OKD. Bei OpenShift Container Platform übernimmt RHCOS, Red Hat Enterprise Linux CoreOS, diese Rolle. „Unveränderlich“ bedeutet hier, dass Node-Konfiguration über deklarierte Clustermechanismen statt durch manuelles Paketinstallieren gepflegt wird.

Laufenden SNO zusätzlich im Cluster prüfen
Laptop · richtiger SNO-Kontext · nur lesen
oc whoami --show-server
oc get nodes -o custom-columns=NAME:.metadata.name,ROLES:.metadata.labels,OS:.status.nodeInfo.osImage
oc get clusterversion version
oc get clusteroperator
oc get machineconfigpool

6 CRC als lokalen Cluster vermessen

CRC ist das Upstream-Werkzeug hinter Red Hat OpenShift Local. Es stellt einen vollständigen OpenShift-Single-Node in einer lokalen VM für Entwicklung und Lernen bereit.

Laptop · PowerShell · nur lesen
crc status
crc config view
crc ip
oc config get-contexts

$crcContexts = @(oc config get-contexts -o name | Where-Object { $_ -match 'crc' })
$crcContext = $crcContexts | Where-Object { $_ -match 'admin' } | Select-Object -First 1
if (-not $crcContext) { $crcContext = $crcContexts | Select-Object -First 1 }
if (-not $crcContext) { throw 'Kein CRC-Kontext in der Kubeconfig gefunden.' }

oc --context $crcContext whoami --show-server
oc --context $crcContext get nodes -o wide
oc --context $crcContext get clusteroperator
Bash-Variante anzeigen
Laptop · Bash · nur lesen
crc status
crc config view
crc ip
oc config get-contexts

crc_context=$(oc config get-contexts -o name | grep 'crc' | grep 'admin' | head -1)
test -n "$crc_context" || crc_context=$(oc config get-contexts -o name | grep 'crc' | head -1)
test -n "$crc_context" || { printf 'Kein CRC-Kontext gefunden.\n' >&2; exit 1; }

oc --context "$crc_context" whoami --show-server
oc --context "$crc_context" get nodes -o wide
oc --context "$crc_context" get clusteroperator

crc status unterscheidet VM, OpenShift und Disk-Nutzung. crc config view zeigt die lokal gewählten CPU-, RAM- und Disk-Werte. Wenn CRC gestoppt ist, bleibt diese Konfiguration lesbar, Clusterabfragen schlagen aber erwartbar fehl.

7 Ein-Node-Grenzen am Cluster beweisen

CRC- oder SNO-Kontext · nur lesen
oc get nodes -L node-role.kubernetes.io/master,node-role.kubernetes.io/worker
oc get storageclass
oc get volumesnapshotclass
oc get machineconfigpool
oc get clusteroperator monitoring
oc get pods -A -o wide

Wenn oc get volumesnapshotclass meldet, dass dieser Ressourcentyp unbekannt ist, ist die Snapshot-API nicht installiert. Eine leere Liste bedeutet dagegen, dass die API existiert, aber keine Klasse angeboten wird.

BefundFolgerungNicht daraus folgern
ein Node trägt Steuerungsebene und Workloadskein Schutz vor Ausfall dieses NodesOpenShift-Funktionen seien nur simuliert
alle Pods landen auf demselben NodeAnti-Affinity kann keine Hardwareausfälle trennenScheduler-Regeln seien grundsätzlich falsch
lokaler oder HostPath-StorageVolume bleibt an diese Maschine gebundenjedes OpenShift habe nur lokalen Storage
kein Verkehr zwischen Nodeskein realer Geneve-Hop messbarOVN-Kubernetes oder NetworkPolicy fehle

CRC gegen SNO: Beide zeigen die OpenShift-API und Operatoren echt. CRC ergänzt die besondere Grenze eines vorgebauten lokalen Bundles. Die Hetzner-SNO ergänzt echte externe Netze, Kosten, Remote-Zugriff und einen persistenten Server-Lebenszyklus.

8 Den Tailscale-Pfad zur SNO prüfen

Tailscale bildet ein privates Overlay-Netz, Tailnet genannt. MagicDNS ordnet seinen Geräten stabile Namen zu. Die OpenShift-API behält trotzdem ihren Zertifikatsnamen.

Laptop · PowerShell · nur lesen
tailscale status
$apiUri = [Uri](oc whoami --show-server)
$apiHost = $apiUri.Host
"API-Name: $apiHost"
Resolve-DnsName $apiHost
Test-NetConnection $apiHost -Port 6443
Get-Content -LiteralPath "$env:WINDIR\System32\drivers\etc\hosts" |
  Select-String -SimpleMatch $apiHost

Der Eintrag in C:\Windows\System32\drivers\etc\hosts ist wichtig, wenn der öffentliche nip.io-Name lokal auf die private Tailscale-IP zeigen soll. Der Name bleibt gleich, damit die Subject Alternative Names, kurz SANs, im API-Zertifikat passen.

Zwei unabhängige Prüfungen: Ein erreichbares Tailscale-Gerät beweist noch nicht, dass Port 6443 lauscht. Ein auflösbarer API-Name beweist noch nicht, dass er auf die gewünschte Tailnet-IP zeigt. Deshalb werden Status, DNS und TCP-Port getrennt geprüft.

9 Den lokalen Jenkins und seine Engine finden

Jenkins läuft hier als Container in der Podman-Maschine. Die Maschine stellt Linux auf Windows bereit, der Jenkins-Container orchestriert die Pipeline und die Host-Engine baut die Images.

Laptop · PowerShell · nur lesen
podman machine list
podman system connection list
podman ps --filter name=shared-jenkins --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
podman port shared-jenkins
podman stats shared-jenkins --no-stream

Wenn die Podman-Maschine gestoppt ist, kann podman ps keine Container liefern. Das ist ein klarer Schichtfehler vor Jenkins und kein OpenShift-Problem.

Keine Geheimnisse inventarisieren: Verwende dafür weder vollständiges podman inspect noch die Ausgabe aller Jenkins-Umgebungsvariablen. Dort können Zugangsdaten, Tokens und Registry-Passwörter stehen.

10 Das Ergebnis eines Deploys im Cluster verfolgen

Die Pipeline ist erst bewiesen, wenn Commit, Image und laufender Pod zusammenpassen. Diese Abfragen starten keinen Build.

Im Anwendungs-Repository

Projekt-Repository · PowerShell oder Bash · nur lesen
git remote get-url origin
git branch --show-current
git rev-parse --short HEAD
git status --short

Im Zielcluster

Laptop · SNO-Kontext · nur lesen
oc whoami --show-server
oc get namespace library
oc -n library get deployment -o custom-columns=NAME:.metadata.name,READY:.status.readyReplicas,IMAGE:.spec.template.spec.containers[*].image
oc -n library get replicaset --sort-by=.metadata.creationTimestamp
oc -n library get pod -o wide
oc -n library get route
oc -n library get serviceaccount pipeline
oc get route default-route -n openshift-image-registry
GitDer Commit ist die nachvollziehbare Quelle für die Pipeline.
JenkinsDie Pipeline testet, baut Images und stößt die deklarative Auslieferung an.
RegistryDie integrierte Registry hält die gebauten Image-Inhalte hinter Tags und Digests.
HelmDas Release rendert und aktualisiert die Kubernetes-Objekte im Namespace library.
DeploymentDas Deployment erzeugt ReplicaSets und die laufenden Pods aus der neuen Pod-Vorlage.

Ein laufender Pod beweist nur den letzten Abschnitt. Die Zuordnung zum Commit gelingt über den verwendeten Image-Tag oder besser über Digest und Build-Metadaten. Fehlt diese Verbindung, ist der Rollout technisch erfolgreich, aber nicht vollständig nachvollziehbar.

11 Für jede Frage die kleinste passende Umgebung wählen

Frage oder Übungpassende UmgebungGrund
Web-Konsole, Projects, RBAC, SCC, Routes und OLM lernenCRClokal, schnell wiederholbar und vollständige OpenShift-Oberfläche
Remote-Zugriff, öffentliche Routes, Registry und Kostenbetrieb verstehenHetzner-SNOechtes externes Netz und echter Server-Lebenszyklus
Node-Ausfall, Anti-Affinity und verteilten Storage testenMulti-Node-Clustereine SNO und CRC besitzen keine zweite Ausfallzone
Nur Kubernetes-API und Multi-Node-Scheduling übenkind oder k3dkleiner als OpenShift, aber ohne Routes, SCC und Cluster Operators
Den vollständigen Bibliothek-Deploy demonstrierenSNO mit lokalem Jenkinszeigt reale Build-, Registry-, Tunnel- und Rollout-Grenzen gemeinsam

12 Dateien und Herkunft sauber trennen

Datei oder ZustandKategorieUmgang
scripts/sno.ps1, scripts/sno-wsl.sh, scripts/sno-kexec.shwichtigversionierte Automatisierung für Server, SCOS-Sprung und Installation
install-config.yaml und Ignition-Konfigurationwird generiertInstallationsartefakte mit sensiblen Daten, nicht veröffentlichen
~/.kube/okd-sno-hetzner.yamlwird generiertKubeconfig mit Zugangsdaten, nur geschützt lokal aufbewahren
C:\Windows\System32\drivers\etc\hostsdu legst anlokale Namensauflösung für den API-Zertifikatsnamen
CRC-VM, Bundle und lokale Kubeconfig-Kontextewird generiertdurch CRC verwalten, nicht in dessen VM manuell ändern
Jenkins-Compose, Jenkinsfile und Helm-Chartwichtigversionierter Sollzustand in den jeweiligen Projekt-Repositories
Build-Container, Images, ReplicaSets und Podswird generiertüber Pipeline, Registry und Deployment zurückverfolgen

13 Fehler zuerst der richtigen Schicht zuordnen

Fehlerbilderste PrüfungSchicht
oc zeigt unerwartete Namespacesoc whoami --show-serverfalscher Kubeconfig-Kontext
API-Name löst falsch aufResolve-DnsName und hostsDNS oder lokaler Override
Tailscale sieht den Node, Port 6443 bleibt zuTest-NetConnectionAPI-Prozess, Zielhost oder Filterregel
Jenkins-Webseite fehltPodman-Maschine, Container und Portlokale Container-Laufzeit
Build grün, alter Pod läuft weiterImage-Referenz und ReplicaSet-AlterRegistry-, Helm- oder Rollout-Übergabe
CRC ist langsam oder Workloads bleiben pendingcrc config view und Node-RessourcenLaptop-Kapazität oder Ein-Node-Grenze

Die Reihenfolge verhindert, dass ein Tunnelproblem im Deployment gesucht oder ein falscher Kontext als fehlgeschlagener Rollout interpretiert wird.

14 Lernkontrolle

  • Ich kann CRC und Hetzner-SNO anhand von API-Adresse, Domain und lokalem Status unterscheiden.
  • Ich kann erklären, warum Rescue, kexec, SCOS, Ignition und Bootstrap nacheinander nötig sind.
  • Ich kann Ein-Node-Grenzen von fehlenden OpenShift-Funktionen unterscheiden.
  • Ich kann DNS-Auflösung, Tailscale-Verbindung und API-Port getrennt prüfen.
  • Ich kann lokalen Jenkins, Podman-Engine und Zielcluster als drei getrennte Schichten diagnostizieren.
  • Ich kann einen laufenden Pod über Image, Deployment und Pipeline bis zu einem Git-Commit zurückverfolgen.

Nichts aufzuräumen: Dieses Labor hat nur lokale Dateien und entfernte Zustände gelesen. Wenn du keine der ausdrücklich abgegrenzten Start- oder Änderungsaktionen ausgeführt hast, wurde nichts erzeugt.