|
Dieses Dokument wurde mithilfe automatisierter maschineller Übersetzungstechnologie übersetzt. Wir bemühen uns um korrekte Übersetzungen, übernehmen jedoch keine Gewähr für die Vollständigkeit, Richtigkeit oder Zuverlässigkeit der übersetzten Inhalte. Im Falle von Abweichungen ist die englische Originalversion maßgebend und stellt den verbindlichen Text dar. |
Entwicklung für Kubernetes
Rancher Desktop – SUSE Application Collection – Tilt
Von der Entwicklungsumgebung bis zur Bereitstellung – Innere Schleife, Einblick, GitOps
1. Überblick: Warum dieser Leitfaden?
Dieser Leitfaden behandelt die komplette Wertschöpfungskette der Kubernetes-Entwicklung, von der anfänglichen Einrichtung der Umgebung bis zur kontinuierlichen Bereitstellung. Das Ziel: einen Entwickler schnell produktiv zu machen, indem beliebte Werkzeuge, ein lokaler Cluster (Rancher Desktop) und vertrauenswürdige Images (SUSE Application Collection) verwendet werden.
Er ist in zwei Teile gegliedert: zuerst eine praktische Demo, die Sie in wenigen Minuten zum Laufen bringt. Dann ein Weiterführender Abschnitt, der das breitere Ökosystem (Dev-Container, Testcontainers, mirrord, Helm, Sicherheit, GitOps) abdeckt, wenn Sie bereit sind, Ihren Workflow zu vertiefen.
1.1 Die beiden Schleifen der cloudnativen Entwicklung
| Innere Schleife | Äußere Schleife | |
|---|---|---|
Was |
Der schnelle tägliche Zyklus des Entwicklers: Code schreiben, bauen, lokal bereitstellen, testen, debuggen, iterieren |
Der automatisierte Post-Commit-Zyklus: CI/CD, Integrationstests, Sicherheitsprüfungen, Staging/Produktion-Bereitstellung |
Zielwert |
Feedback in Sekunden |
Qualität und Reproduzierbarkeit |
Werkzeuge |
Tilt, mirrord |
Argo CD, GitHub Actions, Tekton |
Bereich |
Entwicklerarbeitsplatz + lokaler Cluster |
CI/CD-Pipeline + Remote-Cluster |
Schlüsselprinzip – Die innere Schleife muss so schnell wie möglich sein. Jede Sekunde, die im Code-Bau-Bereitstellungs-Testzyklus eingespart wird, multipliziert sich mit der Anzahl der täglichen Änderungen. Eine gute innere Schleife bedeutet, von 5-10 Minuten auf 5-10 Sekunden pro Iteration zu kommen.
2. Gesamtarchitektur
2.1 Diagramm
2.2 Stapelschichten
| ebene | Werkzeug | Rolle |
|---|---|---|
IDE |
VS Code + Erweiterungen |
Editor, Debuggen, integrierte Terminals |
Lokaler Cluster |
Rancher Desktop (k3s) |
Lokales Kubernetes + Container-Laufzeit |
Images |
SUSE Anwendungssammlung |
Basisbilder, Sprachen, Middleware, Werkzeuge |
Innere Schleife |
Tilt |
Automatisches Bauen, automatisches Bereitstellen, Hot Reload |
Authentifizierung |
Keycloak |
OAuth2 / OpenID Connect Identitätsanbieter |
Einblick |
Prometheus + Grafana |
Anwendungsmetriken, Echtzeit-Dashboards |
Paketerstellung |
Helm / Kustomize |
K8s-Manifestvorlagen |
Sicherheit |
Trivy / Cosign |
Schwachstellenscanning, Bildsignierung |
GitOps |
Argo CD |
Deklarative Bereitstellung aus Git |
3. Einrichten von Rancher Desktop
3.1 Was ist Rancher Desktop?
Rancher Desktop ist eine Open-Source-Desktopanwendung, die einen lokalen Kubernetes-Cluster (k3s) und eine Container-Laufzeit (dockerd oder containerd) bereitstellt, alles innerhalb einer automatisch verwalteten VM. Es ist nicht erforderlich, Docker Desktop zu installieren.
3.2 Installation und Konfiguration
-
Herunterladen von rancherdesktop.io.
-
Wählen Sie die Laufzeit: wählen Sie dockerd (moby) (nicht containerd). Dies ist entscheidend für das Folgende.
-
Kubernetes aktivieren (standardmäßig aktiviert).
-
Überprüfen:
docker info # shows "Server Version: ..." kubectl get nodes # shows "Ready" -
PATH – unter macOS überprüfen Sie, ob
~/.rd/bin/in Ihrem$PATHist (automatisch vom Installer hinzugefügt):which docker kubectl helm # should point to ~/.rd/bin/
Rancher Desktop ist nicht Docker Desktop. Sie benötigen Docker Desktop nicht. Rancher Desktop bietet seinen eigenen Docker-Daemon (moby/dockerd) an. Wenn beide installiert sind, kann es zu Konflikten bei den Sockets kommen. Deaktivieren Sie Docker Desktop, wenn Sie es haben.
3.3 Warum dockerd (moby), wenn die Produktion containerd verwendet?
In der Produktion verwendet Kubernetes containerd als Laufzeit. Hier ist die entscheidende Erkenntnis: das tut auch Rancher Desktop, selbst im Moby-Modus. Der k3s-Cluster läuft immer auf containerd, unabhängig von der Einstellung. Die Wahl von “dockerd (moby)” ersetzt containerd nicht – es fügt den Daemon von Docker hinzu, und beide teilen sich denselben Image-Speicher.
Das ist es, was uns das Beste aus beiden Welten gibt: dieselbe Laufzeit wie in der Produktion, plus die entwicklerfreundlichen Werkzeuge von Docker.
Rancher Desktop VM (moby mode): +---------------------------------------------+ | | | dockerd (moby) k3s (containerd) | | +-- image store <----> image store --+ | | (shared) (same!) | | | | | docker build -> image appears in both | | NO PUSH NEEDED! | +---------------------------------------------+ Rancher Desktop VM (containerd mode): +---------------------------------------------+ | | | nerdctl (containerd) k3s (containerd) | | +-- image store image store --+ | | (separate!) (separate!) | | | | | nerdctl build -> push -> pull -> k3s | | 3 steps instead of 1 = slower | +---------------------------------------------+
Von Docker erstellte Images sind sofort sichtbar für k3s, da sie denselben Speicher teilen. Kein Registry, kein Push, kein Pull. Das ist es, was die innere Schleife so schnell macht.
Kein Kompromiss bei der Parität. Ihre App läuft in beiden Fällen auf containerd. Der einzige Unterschied ist die Kommandozeilenschnittstelle, die zum Erstellen von Images verwendet wird:
docker(Moby-Modus) vsnerdctl(containerd-Modus). Zur Laufzeit verhält sich k3s identisch.
Das ist auch der Grund, warum die Demo-K8s-Deployments imagePullPolicy: IfNotPresent (oder Never) verwenden: Wir sagen k3s “use the local image, do not look in a registry”.
4. SUSE Anwendungssammlung
4.1 Was ist die SUSE Application Collection?
SUSE Application Collection ist eine Sammlung von Anwendungen in Form von Container-Images und Helm-Charts, die von SUSE erstellt, verpackt, gehärtet und gewartet werden – mit SLSA L3-Builds und allen Metadaten, die benötigt werden, um den Betrieb ruhig zu halten. Es ist die vertrauenswürdige Quelle zum Erstellen von Anwendungen auf Kubernetes.
Die Registry ist dp.apps.rancher.io. Hier finden Sie:
-
Basisbilder (BCI) – SUSE Linux Enterprise Basis-Containerbilder: minimale, sichere Grundlagen.
-
Language images – Node.js, Go, Rust, Java, Ruby, Clojure… mit vollständigen Toolchains.
-
Middleware – PostgreSQL, Redis, Kafka, MariaDB, Nats, NGINX, Apache ActiveMQ, Apache Apisix, Apache Tomcat…
-
Werkzeuge – Helm, Trivy, Cosign, kubectl, ArgoCD, Prometheus, Grafana…
Verfügbar in Form von einzelnen Containern oder, wenn relevant, vollwertigen Anwendungen mit Helm-Charts für die Bereitstellung.
Die SUSE Application Collection-Erweiterung in Rancher Desktop fügt eine dedizierte Registerkarte in der Benutzeroberfläche hinzu. Sie durchsuchen den Katalog, konfigurieren Werte und installieren mit einem Klick – die Helm-Komplexität ist verborgen.
4.2 Warum Application Collection über öffentliche Registries?
| Öffentliche Registries | SUSE Anwendungssammlung | |
|---|---|---|
Wartung |
Gemeinschaft, variabel |
SUSE, Unternehmens-SLA |
Basis-OS |
Alpine, Debian, Ubuntu… |
SLE BCI (SUSE Linux Enterprise) |
Sicherheitspatches |
Wenn der Maintainer es möchte |
Kontinuierliches CVE-Tracking durch SUSE |
Signieren |
Optional |
Cosign integriert |
Lieferkette |
Variable |
SBOM, Provenance, Attestierungen, SLSA L3 |
4.3 Authentifizierung
Die Authentifizierung für die SUSE Application Collection Registry wird automatisch über die SUSE Application Collection-Erweiterung in Rancher Desktop konfiguriert.
Überprüfen Sie, ob es funktioniert:
docker pull dp.apps.rancher.io/containers/bci-base:latest
Wenn die Authentifizierung nicht konfiguriert ist, fügen Sie sie manuell hinzu:
# Log in to the registry (SUSE Customer Center credentials)
docker login dp.apps.rancher.io
# Verify
docker pull dp.apps.rancher.io/containers/bci-base:latest
Für Kubernetes (helm install, Pods) – ein Pull-Secret ist erforderlich, wenn die Images nicht bereits heruntergeladen wurden. Rancher Desktop erledigt dies automatisch über die Erweiterung. Wenn es ein Problem gibt:
kubectl create secret docker-registry application-collection \
--docker-server=dp.apps.rancher.io \
--docker-username=<USERNAME> \
--docker-password=<PASSWORD>
Fügen Sie dann imagePullSecrets: [{name: application-collection}] in Ihre Helm-Werte ein.
5. Tilt installieren
Tilt ist ein Open-Source-Tool, das jeden Schritt der inneren Schleife automatisiert, von der Codeänderung bis zur erneuten Bereitstellung. Es überwacht Ihre Dateien, baut Images neu, aktualisiert den Cluster und zeigt alles in einem Echtzeit-Dashboard an. Siehe tilt.dev.
5.2 Linux (SUSE und andere)
curl -fsSL https://raw.githubusercontent.com/tilt-dev/tilt/master/scripts/install.sh | bash
Das Skript erkennt Ihre Architektur und platziert die Binärdatei in Ihrem $PATH (~/.local/bin, /usr/local/bin oder ~/bin). Überprüfen:
tilt version
5.3 Windows
In PowerShell:
iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/tilt-dev/tilt/master/scripts/install.ps1'))
Wenn Sie Scoop installiert haben, wird das Skript es automatisch verwenden. Andernfalls müssen Sie möglicherweise das Installationsverzeichnis zu Ihrem $PATH hinzufügen. Überprüfen:
tilt version
5.4 Tilt + Rancher Desktop
Tilt läuft auf dem Host (nicht in einem Container) und verwendet direkt die von Rancher Desktop installierten Kommandozeilenschnittstellen: docker, kubectl, helm. Es erkennt automatisch Rancher Desktop (seit Tilt v0.25.1+), wenn die Laufzeit dockerd ist. Es weiß dann, dass lokal erstellte Images direkt im Cluster verfügbar sind, und überspringt den Push.
Wenn Tilt Ihr Cluster nicht automatisch erkennt, fügen Sie diese Zeile oben in die Tiltfile ein:
allow_k8s_contexts('rancher-desktop')
6. Die Demo: Nachrichtenwand mit Einblick
Dieser Abschnitt führt durch die vollständige Demo. Es zeigt den inneren Loop-Workflow: eine Node.js “message wall”-Anwendung, die mit PostgreSQL verbunden ist, mit Keycloak zur Authentifizierung, instrumentiert mit Prometheus und in Grafana visualisiert. Alles wird aus der SUSE Application Collection installiert.
Der vollständige Quellcode ist auf GitHub verfügbar: fxHouard/Rancher-Developer-Access-Demo.
6.1 Projektstruktur
Rancher-Developer-Access-Demo/ +-- src/ | +-- server.js Application (API + UI + Prometheus metrics) +-- k8s/ | +-- appco/ | | +-- deployment.yaml Pod spec with Prometheus annotations | | +-- service.yaml ClusterIP service | | +-- keycloak.yaml Keycloak Deployment + Service (Application Collection image) | +-- shared/ | +-- grafana-dashboard.yaml 8-panel dashboard (auto-provisioned via sidecar) | +-- keycloak-realm.json Realm config (demo user + OAuth client) +-- scripts/ | +-- setup-keycloak-realm.sh Keycloak realm import via Admin REST API +-- values_yaml/ | +-- postgresql.yaml Helm values for PostgreSQL | +-- prometheus.yaml Helm values for Prometheus | +-- grafana.yaml Helm values for Grafana +-- Dockerfile Container image (Application Collection base) +-- Tiltfile Inner loop config (build, deploy, sync, monitoring) +-- package.json
6.2 Die package.json
{
"name": "message-wall",
"version": "1.0.0",
"description": "SUSE Rancher Developer Access + Tilt: Demo",
"main": "src/server.js",
"scripts": {
"start": "node src/server.js"
},
"dependencies": {
"pg": "^8.13.0",
"prom-client": "^15.1.0"
}
}
Nur zwei Abhängigkeiten: pg für PostgreSQL und prom-client, um Prometheus-Metriken bereitzustellen.
6.3 Die Anwendung (src/server.js)
Die Anwendung ist eine interaktive Nachrichtenwand mit einer integrierten Web-UI. Sie stellt Prometheus-Metriken für den Einblick bereit. Hier sind die wichtigsten Teile – die vollständige Datei befindet sich im Repo.
Konfiguration und Prometheus-Metriken:
const http = require('http');
const { Client } = require('pg');
const promClient = require('prom-client');
const PORT = 3000;
// Change this color, save, see it update!
const ACCENT_COLOR = "#747dcd";
// --- Prometheus metrics ---
// collectDefaultMetrics() automatically exposes Node.js
// metrics: CPU, heap memory, event loop lag, GC...
promClient.collectDefaultMetrics();
// Custom metrics -- prefixed "app_" for easy discovery
const httpDuration = new promClient.Histogram({
name: 'app_http_request_duration_seconds',
help: 'Duration of HTTP requests in seconds',
labelNames: ['method', 'path', 'status'],
buckets: [0.005, 0.01, 0.05, 0.1, 0.5, 1],
});
const messagesPosted = new promClient.Counter({
name: 'app_messages_posted_total',
help: 'Total number of messages posted',
});
const messagesDeleted = new promClient.Counter({
name: 'app_messages_deleted_total',
help: 'Total number of bulk deletes',
});
const messagesCurrent = new promClient.Gauge({
name: 'app_messages_count',
help: 'Current number of messages in the database',
});
Warum das
app_Präfix? – Prometheus sammelt Hunderte von Metriken (Node.js, k8s, System…). Dasapp_-Präfix ermöglicht es Ihnen, Ihre Anwendungsmetriken sofort zu finden: Geben Sieapp_in Grafana ein und die Autovervollständigung erledigt den Rest.
Prometheus Metriktypen:
| Typ | Verwendung | Demobeispiel |
|---|---|---|
+++Counter |
Wert, der nur steigt |
|
Messwert |
Wert, der steigt und fällt |
|
Histogramm |
Verteilung der Werte (Latenz) |
|
API-Routen:
Die Anwendung stellt 6 Routen zur Verfügung: GET / dient der HTML-Seite, GET /api/messages listet die 50 neuesten Nachrichten auf, POST /api/messages erstellt eine Nachricht (280 Zeichen Limit), DELETE /api/messages löscht alle Nachrichten, GET /health dient als K8s-Prüfung (Liveness + Readiness) und GET /metrics stellt Prometheus-Metriken im Textformat zur Verfügung.
Der /metrics Endpunkt:
if (req.method === 'GET' && req.url === '/metrics') {
const metrics = await promClient.register.metrics();
res.writeHead(200, { 'Content-Type': promClient.register.contentType });
res.end(metrics);
// Do not record /metrics in the histogram (noise)
return;
}
Dies ist der Endpunkt, den Prometheus regelmäßig abruft. Er gibt alle Metriken im OpenMetrics-Textformat zurück. Beachten Sie, dass /metrics selbst nicht vom Histogramm gemessen wird – das wäre Rauschen.
The measurement middleware:
Die Mess-Middleware:
Jede HTTP-Anfrage wird automatisch zeitlich erfasst:
const end = httpDuration.startTimer();
// ... request processing ...
end({ method: req.method, path: routePath, status: statusCode });
Das Histogramm zeichnet die Dauer, Methode, den Pfad und den Rückgabecode auf. Grafana kann dann Perzentile (p50, p95, p99) pro Route berechnen.
Die HTML-Seite:
Die Anwendung dient einer interaktiven Nachrichtenwand, die direkt von Node.js (Inline-HTML in server.js) bereitgestellt wird. Die Benutzeroberfläche umfasst ein Eingabefeld, eine Informationsleiste, die den Pod-Namen und die Betriebszeit anzeigt, sowie eine automatische Abfrage alle 3 Sekunden mit intelligentem Diffing (nur Zeitstempel werden aktualisiert, wenn sich die Nachrichten nicht geändert haben, kein Flackern).
live_update-Demo – Ändern Sie die Konstante
ACCENT_COLORin Zeile 9 und speichern Sie. In ~2 Sekunden ändert sich die Wandfarbe, ohne dass Nachrichten verloren gehen. Das ist Tilt’s live_update in Aktion.
6.4 Das Dockerfile
FROM dp.apps.rancher.io/containers/nodejs:24-dev
WORKDIR /app
COPY package.json ./
RUN npm install --no-package-lock
COPY . .
EXPOSE 3000
CMD ["node", "src/server.js"]
In der Produktion würden Sie einen Multi-Stage-Build verwenden, um den
npm install-Schritt (Entwicklungsimage mit npm) vom finalen Image (minimalesnodejs:24-Image, ohne npm oder Build-Tools) zu trennen. Hier behalten wir ein einfaches Dockerfile für die Demo. Siehe Weiterführend: minimale Images.
6.5 Die Kubernetes-Manifeste
k8s/deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: message-wall
spec:
replicas: 1
selector:
matchLabels:
app: message-wall
template:
metadata:
labels:
app: message-wall
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "3000"
prometheus.io/path: "/metrics"
spec:
containers:
- name: message-wall
image: message-wall # Tilt replaces with local image
ports:
- containerPort: 3000
env:
- name: DB_HOST
value: "demo-db-postgresql"
- name: DB_PORT
value: "5432"
- name: DB_USER
value: "demo"
- name: DB_PASSWORD
value: "demo"
- name: DB_NAME
value: "demo"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
Prometheus-Anmerkungen – Die drei Anmerkungen unter
template.metadata.annotationssagen Prometheus: “scrape diesen Pod, auf Port 3000, unter dem Pfad/metrics”. Der Prometheus-Server, der standardmäßig für die Kubernetes-Autoentdeckung konfiguriert ist, erkennt automatisch annotierte Pods. Keine zusätzliche Prometheus-Konfiguration erforderlich.
Beobachten Sie die Einrückung – Anmerkungen müssen unter
template.metadata(der Pod-Vorlage) stehen, nicht unter demmetadatades Deployments oder auf derspec-Ebene. Dies ist ein häufiger Fehler: Wenn Anmerkungen auf der falschen Ebene sind, findet Prometheus Ihre Pods nicht.
k8s/service.yaml:
apiVersion: v1
kind: Service
metadata:
name: message-wall
spec:
selector:
app: message-wall
ports:
- port: 3000
targetPort: 3000
6.6 Installation von PostgreSQL, Prometheus und Grafana
Alle drei sind Infrastruktur-Dienste – installieren Sie sie einmal über Rancher Desktop, nicht bei jedem tilt up. Sie bleiben zwischen den Entwicklungssitzungen bestehen.
Das Repository enthält Helm-Werte-Dateien in values_yaml/ für jeden Dienst. Im Rancher Desktop-Anwendungsbereich "Sammlung" suchen Sie nach jedem Chart, wechseln Sie in den YAML-Modus und fügen Sie die entsprechende Datei ein.
values_yaml/postgresql.yaml:
auth:
database: demo
postgresPassword: demo
postgresUsername: demo
username: demo
global:
imagePullSecrets:
- application-collection
values_yaml/prometheus.yaml:
alertmanager:
service:
type: NodePort
global:
imagePullSecrets:
- application-collection
values_yaml/grafana.yaml:
adminPassword: admin
global:
imagePullSecrets:
- application-collection
sidecar:
dashboards:
enabled: true
datasources:
enabled: true
imagePullSecrets– Jede Werte-Datei verweist auf dasapplication-collectionGeheimnis, damit Pods Images vondp.apps.rancher.ioabrufen können. Dieses Geheimnis wird automatisch von der Rancher Desktop-Erweiterung erstellt.
Grafana-Sidecars – Die
sidecar.dashboards.enabledundsidecar.datasources.enabledEinstellungen sind entscheidend. Sie starten kleine Container neben Grafana, die nach Kubernetes ConfigMaps mit bestimmten Labels suchen und deren Inhalte automatisch in Grafana laden. Es ist nicht erforderlich, Datenquellen manuell zu konfigurieren oder Dashboards zu importieren.
| Sidecar | Überwachtes Label | Auswirkung |
|---|---|---|
|
|
Lädt automatisch Dashboard-JSON-Dateien |
|
|
Konfiguriert automatisch Datenquellen |
Überprüfen Sie, ob die Sidecars aktiv sind:
kubectl get pods -l app.kubernetes.io/name=grafana \
-o jsonpath='{.items[0].spec.containers[*].name}'
# Expected: grafana grafana-sc-dashboard grafana-sc-datasources
Wenn Sie nur grafana sehen, gehen Sie zurück zur Rancher Desktop-Benutzeroberfläche und überprüfen Sie, ob sowohl sidecar.dashboards.enabled als auch sidecar.datasources.enabled true sind, dann Aktualisieren Sie das Chart.
Das Helm-Chart für PostgreSQL erstellt automatisch den Benutzer, die Datenbank und einen Dienst mit dem Namen
<release-name>-postgresql. Die Tiltfile erkennt diesen Dienst automatisch über dasapp.kubernetes.io/name=postgresqlLabel – es ist nicht erforderlich, sich den Release-Namen zu merken.
6.7 Keycloak: Authentifizierung ohne ein Helm-Chart
Keycloak bietet OAuth2 / OpenID Connect-Authentifizierung für die Message Wall. Benutzer melden sich an, und die App überprüft ihr Identitätstoken, bevor sie Nachrichten posten oder löschen dürfen.
Warum keine Helm-Installation? – Im Gegensatz zu PostgreSQL, Prometheus und Grafana gibt es kein Helm-Chart für Keycloak in der SUSE Application Collection. Es ist nur als Container-Image verfügbar (dp.apps.rancher.io/containers/keycloak). Dies ist ein realistisches Szenario: Nicht jede Anwendung liefert ein Helm-Chart, und Entwickler müssen wissen, wie man rohe Kubernetes-Manifeste bereitstellt.
k8s/appco/keycloak.yaml (simplified):
apiVersion: apps/v1
kind: Deployment
metadata:
name: keycloak-appco
spec:
replicas: 1
selector:
matchLabels:
app: keycloak
template:
metadata:
labels:
app: keycloak
spec:
volumes:
- name: realm-config
configMap:
name: keycloak-realm
containers:
- name: keycloak
image: dp.apps.rancher.io/containers/keycloak:26.5.4
args: ["start-dev", "--health-enabled=true", "--import-realm"]
volumeMounts:
- name: realm-config
mountPath: /opt/keycloak/data/import
env:
- name: KC_DB
value: postgres
- name: KC_DB_URL
value: jdbc:postgresql://PLACEHOLDER_PG_SVC:5432/keycloak
# ... KC_DB_USERNAME, KC_DB_PASSWORD, KEYCLOAK_ADMIN, etc.
readinessProbe:
httpGet:
path: /health/ready
port: 9000
initialDelaySeconds: 30
imagePullSecrets:
- name: application-collection
Wichtigste Punkte:
start-dev+--import-realm– Keycloak startet im Entwicklungsmodus (HTTP, kein Zertifikat) und importiert automatisch alle JSON-Realm-Dateien, die in/opt/keycloak/data/importgefunden werden.Realm ConfigMap – Eine ConfigMap (
keycloak-realm), die das Realm-JSON enthält, wird als Volume eingebunden. Diese ConfigMap wird von der Tiltfile ausk8s/shared/keycloak-realm.jsonerstellt.
PLACEHOLDER_PG_SVC– Die Tiltfile ersetzt dies zur Deploy-Zeit durch den tatsächlichen PostgreSQL-Dienstnamen, der über Label-Selectoren entdeckt wird.Getrennte Datenbank – Keycloak verwendet eine dedizierte
keycloakDatenbank in derselben PostgreSQL-Instanz. Die Tiltfile erstellt sie automatisch, wenn sie nicht existiert.
Realm-setup-Skript (scripts/setup-keycloak-realm.sh):
Die Tiltfile führt auch ein setup-Skript über die Admin REST API als Fallback aus. Das Skript ist idempotent: Es überprüft, ob das Realm bereits existiert, erhält ein Admin-Token und erstellt das Realm, falls erforderlich. Dies behandelt den Fall, in dem der Import der ConfigMap nicht erfasst wird (z. B. wenn Keycloak bereits lief, bevor die ConfigMap erstellt wurde).
6.8 Das Grafana-Dashboard (automatisch bereitgestellte ConfigMap)
Das Grafana-Dashboard ist in einer Kubernetes ConfigMap definiert. Dank des Sidecars, das im vorherigen Schritt aktiviert wurde, wird es automatisch geladen – kein manueller Import erforderlich.
k8s/grafana-dashboard.yaml (Struktur – die vollständige Datei befindet sich im Repository):
apiVersion: v1
kind: ConfigMap
metadata:
name: message-wall-dashboard
labels:
grafana_dashboard: "1" # the sidecar detects this label
data:
message-wall.json: |
{
"uid": "message-wall",
"title": "Message Wall",
"panels": [ ... ]
}
uid: "prometheus"– Jedes Panel verweist auf die Datenquelle über"uid": "prometheus". Diese UID muss genau übereinstimmen mit der, die in der von der Tiltfile generierten Datenquellen-ConfigMap deklariert ist (siehe nächster Abschnitt). Wenn das JSON${DS_PROMETHEUS}verwendet (Grafana UI-Importsyntax), wird das Sidecar diese Variable nicht auflösen – Sie müssen die hardcodierte UID verwenden.
Das Dashboard enthält 8 Panels:
| des Assistenten | Typ | Metrik | Was es zeigt |
|---|---|---|---|
Nachrichten in der Datenbank |
Stat |
|
Messgerät mit Schwellenwerten grün < 50 < gelb < 100 < rot |
Veröffentlichte Nachrichten |
Stat |
|
Zähler für insgesamt veröffentlichte Nachrichten |
Massenlöschungen |
Stat |
|
Zähler für insgesamt Massenlöschungen |
Anfragen / Sekunde |
Zeitreihe |
|
Durchsatz pro HTTP-Route |
Beiträge / Minute |
Zeitreihe |
|
Veröffentlichungsrate |
Antwortzeit (p95) |
Zeitreihe |
|
Latenz des 95. Perzentils pro Route |
Speichernutzung |
Zeitreihe |
|
RSS + Node.js-Heap |
Verzögerung der Ereignisschleife (p99) |
Zeitreihe |
|
Gesundheit der Ereignisschleife |
Warum
rate(…[5m])und nicht[1m]? – Dierate()Funktion benötigt mindestens 2 Datenpunkte innerhalb des Fensters. Wenn Prometheus alle 60 Sekunden abfragt, hat ein 1-Minuten-Fenster nur einen Punkt und gibt nichts zurück. Die Faustregel: Setzen Sie dasrate()Fenster auf mindestens 2x des Abfrageintervalls. 5 Minuten sind ein sicherer Standardwert.
Deklarative Bereitstellung – Das Dashboard befindet sich in Git, versioniert mit dem Code. Wenn Sie es in Grafana ändern (Panels hinzufügen, Abfragen ändern), exportieren Sie es und aktualisieren Sie die ConfigMap, damit Änderungen bei der nächsten erneuten Implementierung nicht verloren gehen. Dies ist der Infrastruktur als Code-Ansatz, der auf Einblick angewendet wird.
6.9 Die vollständige Tiltfile
# Demo Tiltfile
load('ext://restart_process', 'docker_build_with_restart')
allow_k8s_contexts('rancher-desktop')
# --- Helpers ---------------------------------------------------------
def find_service(label_selector, required=False, name='Service'):
# Discover a Kubernetes service by label selector.
#
# Helm charts installed via Rancher Desktop get random release
# names (e.g. postgresql-1772033328). Searching by label is
# robust regardless of the release name.
svc = str(local(
"kubectl get svc -l " + label_selector +
" -o jsonpath='{.items[0].metadata.name}'",
quiet=True,
)).strip()
if required and svc == '':
fail(name + ' not found. Install it via Rancher Desktop ' +
'(Application Collection).')
return svc
# --- Service discovery -----------------------------------------------
pg_svc = find_service(
'app.kubernetes.io/name=postgresql',
required=True,
name='PostgreSQL',
)
grafana_svc = find_service('app.kubernetes.io/name=grafana')
prometheus_svc = find_service(
'app.kubernetes.io/name=prometheus,app.kubernetes.io/component=server',
)
# --- Application -----------------------------------------------------
docker_build_with_restart(
'message-wall',
'.',
entrypoint=['node', 'src/server.js'],
only=['src/', 'package.json'],
live_update=[
sync('./src', '/app/src'),
run('cd /app && npm install --no-package-lock',
trigger=['package.json']),
],
)
deployment = str(read_file('k8s/appco/deployment.yaml')).replace(
'PLACEHOLDER_PG_SVC', pg_svc)
service = str(read_file('k8s/appco/service.yaml'))
k8s_yaml([blob(deployment), blob(service), 'k8s/shared/grafana-dashboard.yaml'])
k8s_resource(
'message-wall-appco',
port_forwards='3000:3000',
labels=['app'],
)
# --- Keycloak (no Helm chart — deployed as raw K8s manifest) ---------
# Ensure keycloak DB exists in PostgreSQL
pg_pod = str(local(
"kubectl get pods -l app.kubernetes.io/name=postgresql "
"-o jsonpath='{.items[0].metadata.name}'", quiet=True)).strip()
local("kubectl exec " + pg_pod +
" -- env PGPASSWORD=demo psql -U demo -tc "
"\"SELECT 1 FROM pg_database WHERE datname='keycloak'\""
" | grep -q 1 || kubectl exec " + pg_pod +
" -- env PGPASSWORD=demo psql -U demo -c 'CREATE DATABASE keycloak'",
quiet=True)
# Realm ConfigMap (auto-imports realm with demo user + OAuth client)
local('kubectl create configmap keycloak-realm '
'--from-file=message-wall.json=k8s/shared/keycloak-realm.json '
'--dry-run=client -o yaml | kubectl apply -f -', quiet=True)
# Deploy Keycloak using the Application Collection container image
keycloak_yaml = str(read_file('k8s/appco/keycloak.yaml')).replace(
'PLACEHOLDER_PG_SVC', pg_svc)
k8s_yaml(blob(keycloak_yaml))
k8s_resource('keycloak-appco', port_forwards='8080:8080', labels=['app'])
# Realm setup via Admin REST API (idempotent fallback)
local_resource(
'keycloak-realm-setup',
cmd='bash scripts/setup-keycloak-realm.sh http://localhost:8080 '
'k8s/shared/keycloak-realm.json',
labels=['app'],
resource_deps=['keycloak-appco'],
)
# --- Monitoring (optional) -------------------------------------------
if grafana_svc:
local_resource(
'grafana',
serve_cmd='kubectl port-forward svc/' + grafana_svc + ' 3001:80',
labels=['monitoring'],
allow_parallel=True,
links=['http://localhost:3001',
'http://localhost:3001/d/message-wall/'],
)
if prometheus_svc:
local_resource(
'prometheus',
serve_cmd='kubectl port-forward svc/' + prometheus_svc
+ ' 9090:80',
labels=['monitoring'],
allow_parallel=True,
links=['http://localhost:9090'],
)
datasource_cm = """apiVersion: v1
kind: ConfigMap
metadata:
name: grafana-datasource-prometheus
labels:
grafana_datasource: "1"
data:
prometheus.yaml: |
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
uid: prometheus
url: http://{svc}:80
access: proxy
isDefault: true
editable: false
""".format(svc=prometheus_svc)
k8s_yaml(blob(datasource_cm))
k8s_resource(
objects=['message-wall-dashboard:configmap',
'grafana-datasource-prometheus:configmap'],
new_name='grafana-config',
labels=['monitoring'],
links=['http://localhost:3001/d/message-wall/'],
)
Wichtige Punkte der Tiltfile:
find_service() Helfer – Dienste, die über die Rancher Desktop UI installiert wurden, haben zufällige Versionsnamen (z. B. grafana-1772033328). Anstatt diese Namen fest einzugeben, entdeckt der Helfer sie über Kubernetes-Labels, die von den Helm-Charts gesetzt werden. Dies ist ein robustes Muster: Die Tiltfile funktioniert unabhängig vom Versionsnamen.
docker_build_with_restart – Die restart_process Erweiterung löst ein Problem, das spezifisch für interpretierte Sprachen ist. Wenn live_update eine Datei in den Container synchronisiert, sieht Node.js sie nicht – der Code ist bereits im Speicher geladen. docker_build_with_restart umschließt den Einstiegspunkt, um den Prozess nach jeder Synchronisierung automatisch neu zu starten. Für kompilierte Sprachen (Go, Rust) ist ein Standard docker_build mit einem Kompilierungsschritt in run() der übliche Ansatz.
Prometheus-Datenquelle als ConfigMap – Anstatt Prometheus in der Grafana UI zu konfigurieren (manuelle Konfiguration geht beim Redeployment verloren), generiert die Tiltfile eine ConfigMap mit dem grafana_datasource: "1"-Label. Der Grafana Sidecar erkennt es und stellt die Verbindung automatisch bereit. Die Prometheus-URL wird dynamisch injiziert: http://<detected-service-name>:80.
links – Jede local_resource und k8s_resource kann klickbare Links im Tilt-Dashboard deklarieren. Sie sehen die URLs für Grafana, Prometheus und das spezifische Dashboard direkt in der Tilt UI.
objects + new_name – ConfigMaps sind keine Workloads (Deployment, StatefulSet…), daher ordnet Tilt sie standardmäßig unter “uncategorized” ein. Die objects Direktive gruppiert sie unter einem expliziten Namen (grafana-config) mit dem monitoring Label.
Keycloak-Implementierung – Da es kein Helm-Chart für Keycloak in der SUSE Application Collection gibt, stellt das Tiltfile es als rohes K8s-Manifest bereit. Zuerst wird sichergestellt, dass eine keycloak Datenbank in PostgreSQL existiert, eine ConfigMap mit dem Realm-JSON erstellt, die Keycloak-Implementierung (wobei PLACEHOLDER_PG_SVC durch den entdeckten Dienstnamen ersetzt wird) bereitgestellt und ein setup-Skript über die Admin-REST-API als idempotente Rückfalloption ausgeführt.
Bedingtheit – Der Überwachungsblock ist bedingt (if grafana_svc / if prometheus_svc). Wenn Prometheus und Grafana nicht installiert sind, funktioniert das Tiltfile trotzdem – nur die App und PostgreSQL sind erforderlich. Einblick ist ein optionales Bonusangebot.
6.10 Die Demo ausführen
# 1. Clone the repo
git clone https://github.com/fxHouard/Rancher-Developer-Access-Demo.git
cd Rancher-Developer-Access-Demo
# 2. Install services via Rancher Desktop (one time only):
#
# PostgreSQL:
# Application Collection tab -> search PostgreSQL -> Install
# Switch to YAML mode, paste values_yaml/postgresql.yaml, Install
#
# Prometheus:
# Application Collection tab -> search Prometheus -> Install
# Switch to YAML mode, paste values_yaml/prometheus.yaml, Install
#
# Grafana:
# Application Collection tab -> search Grafana -> Install
# Switch to YAML mode, paste values_yaml/grafana.yaml, Install
# 3. Start the inner loop:
tilt up
# 4. Press Space to open the Tilt dashboard in your browser
# 5. From the Tilt dashboard, click the links to:
# -> http://localhost:3000 -- The Message Wall app
# -> http://localhost:8080 -- Keycloak (admin / admin)
# -> http://localhost:9090 -- Prometheus (check targets)
# -> http://localhost:3001 -- Grafana (admin / admin)
# 6. In Grafana: go to Dashboards -> "Message Wall" is already there
# (or click the direct link in Tilt)
# 7. Post messages on localhost:3000 and watch the metrics
# update in real time in Grafana
# 8. Change ACCENT_COLOR in src/server.js (line 9)
# -> save -> ~2 sec -> the color changes
6.11 Was im Hintergrund passiert
1. `tilt up` on the host: +-- Auto-detects PostgreSQL (label app.kubernetes.io/name=postgresql) +-- Auto-detects Prometheus and Grafana (labels app.kubernetes.io/name=...) +-- Creates keycloak DB in PostgreSQL if needed +-- docker build message-wall -> image in dockerd local store | +-- k3s sees the image because same store -> imagePullPolicy: IfNotPresent +-- kubectl apply deployment + service -> k3s creates the app pod | +-- Pod connects to detected PG service (K8s internal DNS) | +-- Prometheus scrapes the pod (prometheus.io/* annotations) +-- Deploys Keycloak (Application Collection image, raw K8s manifest) | +-- Imports realm via ConfigMap volume mount | +-- Runs setup script via Admin REST API (idempotent fallback) +-- kubectl apply ConfigMaps (datasource + dashboard) | +-- Grafana sidecars detect and load them +-- Port-forward 3000 -> localhost:3000 (app) +-- Port-forward 8080 -> Keycloak +-- Port-forward 3001 -> Grafana +-- Port-forward 9090 -> Prometheus 2. Dev modifies src/server.js: +-- Tilt (on host) detects the change (file watcher) +-- live_update syncs ./src -> /app/src in the pod (kubectl cp) +-- restart_process relaunches `node src/server.js` in the container +-- ~2 seconds later: change visible on localhost:3000 3. Observability loop (continuous): +-- Prometheus scrapes localhost:3000/metrics every 15-60s +-- Grafana queries Prometheus to display dashboards +-- Dev sees the impact of their changes in real time
6.12 Portweiterleitung erklärt
Tilt verwaltet die Portweiterleitung automatisch über port_forwards in k8s_resource(). Es ist das Äquivalent von kubectl port-forward, aber in den Lebenszyklus von Tilt integriert (automatisch neu gestartet, wenn das Pod neu erstellt wird).
Vollständige Portweiterleitungskette:
Browser (localhost:3000)
-> Tilt port-forward
-> K8s Service (ClusterIP)
-> Your app pod (:3000)
-> Connects to PostgreSQL Service (:5432)
-> PostgreSQL pod
Ihre App im Pod verwendet den internen Kubernetes-DNS, um PostgreSQL zu erreichen:
postgresql://user:pass@demo-db-postgresql.default.svc.cluster.local:5432/mydb
Von Ihrem lokalen Rechner (zum Beispiel für einen SQL-Client): kubectl port-forward svc/demo-db-postgresql 5432:5432.
7. Der vollständige Workflow
| # | Schritt | Werkzeuge | Details |
|---|---|---|---|
1 |
Code schreiben |
VS Code + Erweiterungen |
Editor, Autovervollständigung, Lint, Git |
2 |
Iterieren (innerer Loop) |
Tilt |
Automatisches Erstellen + Live-Synchronisierung + Dashboard |
3 |
Authentifizieren |
Keycloak |
OAuth2-Login, Bereich automatisch von Tilt bereitgestellt |
4 |
Beobachten |
Prometheus + Grafana |
Echtzeit-Metriken, automatisch bereitgestellte Dashboards |
5 |
Commit + Push |
Git |
Quelle der Wahrheit für GitOps |
6 |
Build + Scan (äußere Schleife) |
CI-Pipeline + Trivy + Cosign |
Schwachstellen + Bildsignierung |
7 |
Bereitstellen |
Argo CD |
Automatische Synchronisierung Git → Cluster |
8 |
Progressive Bereitstellung |
Argo Rollouts |
Canary / Blue-Green mit Analyse |
8. Weiter gehen
Die obige Demo behandelt die wesentlichen Aspekte der inneren Schleife. Dieser Abschnitt stellt zusätzliche Werkzeuge und Praktiken vor, die den Workflow ergänzen, während Ihr Projekt wächst.
8.1 Dev-Container: die reproduzierbare Umgebung
Das Prinzip: Ihre Entwicklungsumgebung ist im Code definiert (.devcontainer/). Jeder Entwickler, der das Projekt öffnet, erhält genau die gleiche Umgebung, mit den gleichen Werkzeugen, den gleichen Versionen und den gleichen VS Code-Erweiterungen.
Der Dev Container ist ein Entwicklungscontainer – er dient nur zum Programmieren. Er benötigt kein Docker, kubectl oder Helm. Tilt läuft auf dem Host.
.devcontainer/Dockerfile:
FROM dp.apps.rancher.io/containers/nodejs:24-dev
# System tools (available in the SLE_BCI repo)
# gawk: required by VS Code Server (check-requirements.sh)
RUN zypper --non-interactive install -y git openssh make gawk \
&& zypper clean -a
.devcontainer/devcontainer.json:
{
"name": "Message Wall - Node.js",
"build": {
"dockerfile": "Dockerfile"
},
"customizations": {
"vscode": {
"extensions": [
"ms-kubernetes-tools.vscode-kubernetes-tools"
],
"settings": {
"vs-kubernetes.disable-linters": true
}
}
},
"postCreateCommand": "if [ -f package.json ]; then npm install --no-package-lock; fi"
}
Kein
docker,kubectl,helmodertiltim Container. Tilt läuft auf dem Host. Die Kubernetes-Erweiterung bietet IntelliSense für die Bearbeitung von K8s-Manifesten. Diekubeconfig not foundWarnung ist zu erwarten und harmlos – der Cluster-Explorer funktioniert nicht im Container, aber die Autovervollständigung funktioniert.
Wenn VS Code mit einem Container verbunden ist, öffnen sich alle integrierten Terminals im Container. Aber Tilt muss auf dem Host (wo Docker, kubectl und Helm vorhanden sind) ausgeführt werden. Verwenden Sie ein separates Terminal (Terminal.app, iTerm2, Warp, Windows Terminal…) oder ein zweites VS Code-Fenster, das im selben Ordner ohne “Reopen in Container” geöffnet ist.
8.2 Ressourcenanforderungen und -grenzen
In der Demo hat die Implementierung keinen resources-Block aus Gründen der Einfachheit. In der Produktion (oder in gemeinsamen Clustern) sollten Sie sie immer definieren:
resources:
requests:
cpu: 100m # 0.1 vCPU -- scheduler reserves this
memory: 128Mi # 128 MB -- guaranteed minimum
limits:
cpu: 500m # 0.5 vCPU -- ceiling, throttled beyond
memory: 256Mi # 256 MB -- OOMKill beyond
Ohne requests oder limits kann ein Pod alle Ressourcen des Knotens verbrauchen und andere Workloads beeinträchtigen – das “noisy neighbor” Problem. requests sind für den Scheduler (intelligente Platzierung), limits schützen den Knoten (CPU-Drosselung, OOMKill, wenn der Speicher überschritten wird).
8.3 Testcontainers: Integrationstests
Das Konzept: Testcontainers ist eine Bibliothek, die flüchtige Docker-Container in Ihren Integrationstests hochfährt. Brauchen Sie eine PostgreSQL, um Ihre SQL-Abfragen zu testen? Testcontainers startet eine, führt Ihre Tests aus und zerstört sie, wenn sie abgeschlossen sind.
Warum es wichtig ist:
-
Reproduzierbarkeit: Jeder Test startet eine frische Datenbank – keine Verschmutzung zwischen den Tests.
-
Keine Mocks: Sie testen gegen die echte Datenbank, nicht gegen einen Mock, der abweichen kann.
-
CI-freundlich: funktioniert in GitHub Actions, GitLab CI usw. (benötigt nur Docker).
Testcontainers verwendet den Docker-Daemon des Hosts. Mit Rancher Desktop (dockerd) funktioniert es direkt – keine spezielle Konfiguration erforderlich.
Konfiguration:
# macOS / Linux -- already configured if ~/.rd/bin is in PATH
export DOCKER_HOST=unix://$HOME/.rd/run/docker.sock
Beispiel (Node.js):
const { GenericContainer } = require('testcontainers');
const { Client } = require('pg');
describe('Database integration', () => {
let container, client;
beforeAll(async () => {
container = await new GenericContainer('dp.apps.rancher.io/containers/postgresql:17')
.withExposedPorts(5432)
.withEnvironment({ POSTGRES_USER: 'test', POSTGRES_PASSWORD: 'test', POSTGRES_DB: 'test' })
.start();
client = new Client({
host: container.getHost(),
port: container.getMappedPort(5432),
user: 'test', password: 'test', database: 'test',
});
await client.connect();
});
afterAll(async () => {
await client.end();
await container.stop();
});
test('should insert and retrieve data', async () => {
await client.query('CREATE TABLE test (id SERIAL, name TEXT)');
await client.query("INSERT INTO test (name) VALUES ('hello')");
const result = await client.query('SELECT * FROM test');
expect(result.rows).toHaveLength(1);
});
});
Testcontainers vs Tilt+Helm:
| Testcontainers | Tilt + Helm | |
|---|---|---|
Lebenszyklus |
Ephemeral (1 Testlauf) |
Persistent (Dauer der Entwicklungs-Sitzung) |
Daten |
Frisch bei jedem Lauf |
Persistent (es sei denn, es wird gelöscht) |
Verwendung |
Integrationstests in CI |
Tägliche lokale Entwicklung |
8.4 mirrord: lokales Debuggen in einem Remote-Cluster
mirrord ermöglicht es Ihnen, einen lokalen Prozess auszuführen, während Sie ihn mit dem Netzwerk und dem Dateisystem eines Pods in einem Remote-Kubernetes-Cluster verbinden. Der Code läuft lokal, aber “sees” die Cluster-Umgebung.
Kein Bedarf für mirrord, wenn Sie einen lokalen Cluster mit allen Abhängigkeiten haben und Ihre App 1 bis 5 Mikrodienste hat.
mirrord wird interessant, wenn die App 20+ Mikrodienste hat (unmöglich, alles lokal auszuführen), Sie verwaltete Dienste benötigen, die lokal nicht verfügbar sind, oder Sie lokales Debuggen (Haltepunkte in VS Code) im Kontext eines echten Clusters wünschen.
Die gewinnende Kombination – Tilt für die tägliche innere Schleife (lokaler Cluster), mirrord für gelegentliches Debugging in der Staging-Umgebung. Die beiden Tools sind komplementär.
8.5 Helm und Kustomize
Helm ermöglicht es Ihnen, Ihre Kubernetes-Manifeste zu templatisieren und sie als “charts” zu verteilen. Es ist das Äquivalent eines Paketmanagers (npm, zypper…) für Kubernetes. values.yaml passt Implementierungen pro Umgebung (dev, staging, prod) an. Helm verfolgt die bereitgestellten Versionen und ermöglicht Rollback.
Kustomize funktioniert, indem es Patches auf Basis-YAML-Manifeste anwendet. Keine Template-Sprache: Sie wenden deklarative Transformationen an. Nativ in kubectl integriert (kubectl apply -k).
Helm oder Kustomize? – Die beiden schließen sich nicht gegenseitig aus. Ein gängiger Ansatz: Verwenden Sie Helm für externe Charts (Datenbanken, Monitoring) und Kustomize, um Ihre eigenen Manifeste pro Umgebung anzupassen.
8.6 Sicherheit: Trivy und Cosign
Trivy (verfügbar in der Anwendungsammlung) scannt Ihre Container-Images, Kubernetes-Dateien, Abhängigkeiten und IaC-Code, um bekannte Schwachstellen (CVEs), Fehlkonfigurationen und exponierte Geheimnisse zu erkennen.
trivy image dp.apps.rancher.io/containers/nodejs:24
trivy k8s --report summary cluster
Cosign (verfügbar in der Anwendungsammlung) ermöglicht es Ihnen, Ihre Container-Images kryptografisch zu signieren. Es ist ein Pfeiler der Lieferkettensicherheit.
cosign sign --key cosign.key myregistry/myapp:v1.0
cosign verify --key cosign.pub myregistry/myapp:v1.0
8.7 GitOps: Argo CD und Argo Rollouts
GitOps ist das Prinzip, dass Git die einzige Quelle der Wahrheit für den gewünschten Zustand Ihrer Infrastruktur und Anwendungen ist. Ein Implementierungstool überwacht das Git-Repository und gleicht automatisch den Clusterzustand mit dem in Git deklarierten Zustand ab.
Argo CD (verfügbar in der Anwendungsammlung) ist ein deklaratives kontinuierliches Implementierungstool für Kubernetes: deklarativer Zustand in Git, automatische Synchronisierung mit Drift-Erkennung, Multi-Cluster-Unterstützung und eine Web-UI zur Visualisierung.
Argo Rollouts (auch in der Anwendungsammlung) fügt Blue-Green und Canary Implementierungsstrategien zu Kubernetes hinzu, mit automatischer Metrikanalyse, um zu entscheiden, ob eine Implementierung gefördert oder zurückgerollt werden soll.
8.8 Die “12 Factor App” für Kubernetes
-
Konfiguration über die Umgebung: verwenden Sie ConfigMaps und Secrets, codieren Sie niemals Konfiguration fest im Image.
-
Zustandslose Prozesse: Jede Instanz Ihrer Anwendung muss identisch und austauschbar sein.
-
Portbindung: Ihre Anwendung stellt einen Port zur Verfügung, Kubernetes verwaltet das Routing über Services.
-
Protokolle an stdout: Schreiben Sie niemals in Protokolldateien. Lassen Sie Kubernetes / Fluent Bit stdout sammeln.
-
Gesundheitsprüfungen: Implementieren Sie immer Liveness- und Readiness-Probes.
-
Metriken: Stellen Sie einen
/metricsPrometheus-Endpunkt zur Verfügung. Observability ist kein Luxus, sondern ein Standard.
8.9 Minimale Images
-
BCI Micro: für statische Binärdateien (Go, Rust). Kein Paketmanager, minimale Angriffsfläche.
-
BCI BusyBox: für Fälle, die eine minimale Shell erfordern.
-
BCI Base: für Fälle, die zypper/RPM erfordern.
-
Multi-Stage-Builds: Mit dem Entwicklungs-Image bauen und das Ergebnis in BCI Micro kopieren.
8.10 Infrastruktur als Code
-
Alles ist in Git: Dockerfiles, Helm-Charts, Kustomize-Overlays, Tiltfiles, devcontainer.json, Grafana-Dashboards.
-
Kein manuelles
kubectl applyin Staging/Produktion. Alles läuft über GitOps (Argo CD). -
Ephemere Umgebungen (Vorschau-Umgebungen) werden automatisch bei jedem PR erstellt.
9. Glossar
| Begriff | Definition |
|---|---|
Inner Loop |
Schneller lokaler Entwicklungszyklus: Code, erstellen, bereitstellen, testen |
Outer Loop |
Automatisierter Post-Commit-Zyklus: CI/CD, Tests, Implementierung |
Tilt |
Inner Loop-Tool mit live_update und Web-Dashboard |
Tiltfile |
Tilt-Konfigurationsdatei in Starlark (Python-ähnliche DSL) |
live_update |
Tilt-Funktion: Dateisynchronisierung in einen Container ohne Neubau |
restart_process |
Tilt-Erweiterung: startet den Anwendungsprozess nach einem live_update neu |
Entwicklungscontainer |
Offene Spezifikation zur Definition einer Entwicklungsumgebung in einem Container |
mirrord |
Verbindet einen lokalen Prozess mit einem Remote-K8s-Cluster-Kontext |
Testcontainers |
Bibliothek für containerisierte Abhängigkeiten in Tests |
Helm |
Paketmanager für Kubernetes (Charts) |
Kustomize |
K8s-Manifestanpassung über Patches/Overlays |
Trivy |
Schwachstellenscanner für Bilder, Code, IaC |
Cosign |
Werkzeug zum Signieren/Überprüfen von Container-Images |
Argo CD |
GitOps-Tool für kontinuierliche Implementierung in Kubernetes |
Argo Rollouts |
Canary- und Blue-Green-Implementierungen für Kubernetes |
GitOps |
Paradigm: Git = Quelle der Wahrheit für den Clusterzustand |
Keycloak |
Open-Source-Identitäts- und Zugriffsmanagement (OAuth2 / OpenID Connect) |
Prometheus |
Überwachungssystem, das Metriken über HTTP-Scraping sammelt |
Grafana |
Plattform zur Visualisierung von Metriken (Dashboards) |
prom-client |
Node.js-Bibliothek zum Bereitstellen von Prometheus-Metriken |
Sidecar |
Hilfscontainer in einem Pod, der eine ergänzende Aufgabe ausführt |
ConfigMap |
K8s-Ressource zum Speichern der Konfiguration (hier: Dashboards, Datenquellen) |
k3s |
Leichtgewichtige Kubernetes-Distribution, die von Rancher Desktop verwendet wird |
BCI |
Basis-Container-Images von SUSE, Grundlage der Application Collection Images |
OCI |
Open Container Initiative: Standard für Container-Images |
imagePullPolicy |
K8s-Richtlinie: |
10. Weiterführende Informationen
-
Rancher Desktop: rancherdesktop.io
-
SUSE Application Collection: apps.rancher.io/
-
Demo-Quellcode: github.com/fxHouard/Rancher-Developer-Access-Demo
-
Tilt: tilt.dev – und der Blogbeitrag Tilt + Rancher Desktop
-
mirrord: mirrord.dev
-
Testcontainers: testcontainers.com
-
Dev Containers Spezifikation: containers.dev
-
Argo CD: argoproj.github.io/cd
-
Helm: helm.sh
-
Trivy: aquasecurity.github.io/trivy
-
Cosign: docs.sigstore.dev/cosign
-
Keycloak: keycloak.org
-
Prometheus: prometheus.io
-
Grafana: grafana.com
-
prom-client (Node.js): github.com/siimon/prom-client
Viel Spaß bei der Kubernetes-Entwicklung!