TL;DR
- In Polycrate bedeutet Multi-Cluster automatisch Multi-Workspace: Ein Workspace verwaltet genau einen Kubernetes-Cluster. Das hält Zuständigkeiten, Kubeconfigs und Zugriffsrechte klar getrennt.
- Gemeinsame Logik wandert in wiederverwendbare Blöcke in einer OCI-Registry. Staging und Production nutzen denselben Block-Typ, aber unterschiedliche, explizit gepinnte Versionen – das ist der Promotionsmechanismus.
- Deploy-Workflow: Neue Block-Version in den Staging-Workspace ziehen, mit
polycrate runtesten, dann dieselbe Block-Version in Production pinnen und erneut ausführen. Rollback bedeutet: Version im jeweiligen Workspace zurückdrehen und Action noch einmal laufen lassen. - Jeder Block deployed in einen eigenen Namespace – das schafft technische Isolation, reduziert „shared state“-Effekte und macht Audits pro Workspace und pro Block deutlich einfacher.
- ayedo unterstützt Sie mit Polycrate, Best Practices und passenden Services, um Multi-Cluster-Setups als Multi-Workspace-Architektur sauber aufzubauen – von der ersten Demo bis zur produktiven Umgebung.
Warum ein Workspace = ein Kubernetes-Cluster
Polycrate folgt einer klaren Konvention: Ein Workspace repräsentiert eine in sich geschlossene Automatisierungsdomäne. Für Kubernetes-Lösungen heißt das: Ein Workspace = Ein Cluster.
Das hat mehrere sehr praktische Gründe:
-
Klare Verantwortlichkeiten
Ein Production-Cluster hat andere Anforderungen (SLAs, Compliance, Change-Prozesse) als ein Staging-Cluster. Wenn beide im selben Workspace leben würden, wären Policies, Secrets und Audit-Trails vermischt. -
Kein Kubeconfig-Chaos
Polycrate erwartet genau einekubeconfigpro Workspace – und zwar unter:Damit ist technisch ausgeschlossen, dass ein Playbook „aus Versehen“ im falschen Cluster landet, weil der Kubectl-Context falsch gesetzt ist. Multi-Cluster wird nicht über mehrere Kubeconfigs im selben Workspace gelöst, sondern über mehrere Workspaces.artifacts/secrets/kubeconfig.yml -
Containerisierte Ausführung ohne lokale Abhängigkeiten
Polycrate führt Ansible immer in einem Container aus. Die komplette Toolchain (Python,kubectl,helm, Ansible-Collections) ist darin gekapselt. Keine lokalen Abhängigkeiten, kein Python-Version-Chaos, geringere Supply-Chain-Risiken – das löst das klassische Dependency-Problem, das viele Teams mit plain Ansible kennen. -
Workspace-verschlüsselung und Compliance pro Cluster
Jeder Workspace kann separat verschlüsselt werden, inklusivekubeconfigund Secrets. Das macht es deutlich einfacher, Audit-Anforderungen pro Cluster zu erfüllen. Details finden Sie in der Dokumentation zur Workspace-Verschlüsselung.
Wenn Sie mehr zu empfohlenen Strukturen lesen möchten: Die Polycrate-Best Practices führen genau dieses „Ein Workspace = Ein Cluster“-Muster ausführlich aus.
Beispiel-Setup: acme-staging-1 und acme-production-1
Nehmen wir ein fiktives, aber realistisches Setup bei „Acme Corp“:
acme-staging-1: Staging-Cluster für interne Testsacme-production-1: Production-Cluster für Kunden-Traffic
Jeder Cluster hat einen eigenen Workspace:
acme-staging-1/
workspace.poly
inventory.yml
artifacts/
secrets/
kubeconfig.yml
blocks/
registry.acme-corp.com/acme/apps/app-deploy/
block.poly
deploy.yml
rollback.yml
acme-production-1/
workspace.poly
inventory.yml
artifacts/
secrets/
kubeconfig.yml
blocks/
registry.acme-corp.com/acme/apps/app-deploy/
# gleicher Block-Pfad nach polycrate blocks pull / erstem run
Wichtig:
- Jeder Workspace hat seine eigene
kubeconfig– es gibt nie mehrere Kubeconfigs in einem Workspace. - Blöcke kommen per
from:aus einer OCI-Registry; lokal liegen sie unterblocks/<registry-pfad>/(hier fiktiv:registry.acme-corp.com/...). Öffentliche oder gehostete Registrys: z. B.cargo.ayedo.cloudoder PolyHub.
Ein gemeinsamer Block für beide Cluster
Die gemeinsame Logik – z. B. Deployment eines Webservices – lebt in einem Polycrate-Block. Diesen Block können Sie lokal entwickeln und dann über eine Registry mit anderen Workspaces teilen.
Ein einfaches Beispiel für einen app-deploy-Block (nach Push in eure Registry; name = vollständiger Registry-Pfad ohne Tag, wie in anderen Beiträgen):
# blocks/registry.acme-corp.com/acme/apps/app-deploy/block.poly
name: registry.acme-corp.com/acme/apps/app-deploy
version: 1.2.0
kind: generic
config:
namespace: ""
image: ""
actions:
- name: deploy
description: "Deploy der Anwendung in den Cluster"
playbook: deploy.yml
- name: rollback
description: "Rollback auf eine vorherige Version"
playbook: rollback.yml
In workspace.poly und block.poly gibt es kein Jinja2 – namespace und image tragen Sie pro Workspace-Instanz als literale Werte in der config der Block-Referenz ein (siehe nächster Abschnitt).
Wesentliche Punkte:
- Namespace-Isolation: Pro Umgebung setzen Sie z. B.
acme-app-acme-staging-1bzw.acme-app-acme-production-1in derconfigdes Blocks – damit gibt es keine Überschneidung zwischen Clustern. - Kein
kubeconfig-Pfad im Block: Polycrate setzt im Action-ContainerKUBECONFIGundK8S_AUTH_KUBECONFIGauf diekubeconfigausartifacts/secrets/kubeconfig.yml.kubernetes.core.k8snutzt das automatisch – Sie müssen keinkubeconfig:in den Tasks angeben und keinenkubeconfig_pathin derblock.poly. - Versionierung im Block:
version: 1.2.0ist die Block-Version, die in der Registry landet. Staging kann z. B.1.2.0testen, Production bleibt noch auf1.1.0(gepinnt überfrom: …:1.1.0).
Wenn der Block fertig ist, wird er in eine OCI-Registry gepusht (Details in der Registry-Dokumentation). Von dort können beliebig viele Workspaces denselben Block-Typ nutzen – aber jeweils mit eigener, explizit gepinnter Version.
Workspaces konfigurieren: Staging vs. Production
Jetzt binden wir diesen Block in zwei Workspaces ein: acme-staging-1 und acme-production-1. Beide verwenden denselben Block-Namen und dieselbe Registry-URL, aber unterschiedliche Versionen.
workspace.poly für Staging
# acme-staging-1/workspace.poly
name: acme-staging-1
organization: acme
blocks:
- name: app
from: registry.acme-corp.com/acme/apps/app-deploy:1.2.0
config:
namespace: "acme-app-acme-staging-1"
image: "ghcr.io/acme/myapp:1.2.0"
workspace.poly für Production
# acme-production-1/workspace.poly
name: acme-production-1
organization: acme
blocks:
- name: app
from: registry.acme-corp.com/acme/apps/app-deploy:1.1.0
config:
namespace: "acme-app-acme-production-1"
image: "ghcr.io/acme/myapp:1.1.0"
Wichtig:
- Die Version wird immer in der
from:-URL gepinnt (:1.2.0,:1.1.0). Nie:latestverwenden. - Konfigurationen wie
namespaceundimagekönnen zwischen Staging und Production variieren – auch wenn sie denselben Block-Typ verwenden. - Jeder Workspace hat einen eigenständigen State: Logs, Secrets,
kubeconfigund ggf. weitere Artifacts sind sauber getrennt.
Im Vergleich zu plain Ansible müssten Sie diese Trennung selbst erzwingen – etwa mit getrennten Projektverzeichnissen, unterschiedlichen ansible.cfg-Dateien, eigenem Tooling für Kubeconfigs etc. Polycrate bringt diese Guardrails über das Block- und Workspace-Modell von Haus aus mit.
Deploy-Workflow: Von Staging nach Production
Wie sieht der konkrete Deploy-Workflow mit Polycrate aus?
Schritt 1: Neue Version in Staging deployen
Im Staging-Workspace ist bereits 1.2.0 gepinnt. Wir führen die Deploy-Action aus:
cd acme-staging-1
polycrate run app deploy
Das Playbook deploy.yml wird in einem Polycrate-Container ausgeführt, nicht auf Ihrer lokalen Maschine. Die Ansible-Tasks sprechen den Kubernetes-API-Server über kubernetes.core.k8s an. Die Cluster-Anmeldung übernimmt Polycrate: KUBECONFIG zeigt auf die kubeconfig des Workspaces – Sie setzen kein kubeconfig-Feld in den Modulen.
Ein vollständiges Beispiel-Playbook:
# …/app-deploy/deploy.yml
- name: Deploy application to Kubernetes
hosts: localhost
connection: local
gather_facts: false
vars:
namespace: "{{ block.config.namespace }}"
image: "{{ block.config.image }}"
tasks:
- name: Sicherstellen, dass Namespace existiert
kubernetes.core.k8s:
api_version: v1
kind: Namespace
name: "{{ namespace }}"
state: present
- name: Deployment anwenden
kubernetes.core.k8s:
state: present
definition:
apiVersion: apps/v1
kind: Deployment
metadata:
name: acme-app
namespace: "{{ namespace }}"
spec:
replicas: 3
selector:
matchLabels:
app: acme-app
template:
metadata:
labels:
app: acme-app
spec:
containers:
- name: acme-app
image: "{{ image }}"
ports:
- containerPort: 8080
- name: Service anwenden
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: Service
metadata:
name: acme-app
namespace: "{{ namespace }}"
spec:
selector:
app: acme-app
ports:
- port: 80
targetPort: 8080
Hinweis: hosts: localhost und connection: local sind hier korrekt, weil wir im Polycrate-Container gegen die Kubernetes-API arbeiten, nicht gegen einen Remote-Host per SSH.
Sie testen die neue Version im Staging-Cluster. Läuft alles stabil, geht es weiter.
Schritt 2: Promotionsschritt nach Production
Jetzt promoten Sie dieselbe Block-Version in den Production-Workspace. Der Promotionsschritt ist bewusst simpel:
- Im Production-Workspace die Block-Version anpassen:
# acme-production-1/workspace.poly (nach Freigabe) name: acme-production-1 organization: acme blocks: - name: app from: registry.acme-corp.com/acme/apps/app-deploy:1.2.0 config: namespace: "acme-app-acme-production-1" image: "ghcr.io/acme/myapp:1.2.0" - Deploy-Action im Production-Workspace ausführen:
cd acme-production-1 polycrate run app deploy
Damit haben Sie ein sauberes Promotionsmodell:
- Staging testet neue Block-Versionen zuerst.
- Production folgt erst, wenn die Version freigegeben ist.
- Der technische Standort der Business-Logik (der Block) ist derselbe – nur die Version ändert sich.
Mit plain Ansible würden Sie für diesen Prozess typischerweise separate Git-Branches, manuelle Playbook-Kopien oder eigene Promotions-Skripte pflegen. Polycrate nutzt dafür das eingebaute Block-Versioning und die Registry.
Rollback: Version zurückdrehen, Action neu ausführen
Rollbacks sind mit diesem Modell ebenso geradlinig wie Promotions:
- Problem identifiziert? Sie möchten von 1.2.0 zurück auf 1.1.0 in Production.
- Sie passen die Block-Referenz in
acme-production-1/workspace.polyan:blocks: - name: app from: registry.acme-corp.com/acme/apps/app-deploy:1.1.0 config: namespace: "acme-app-acme-production-1" image: "ghcr.io/acme/myapp:1.1.0" - Sie führen erneut die Deploy-Action aus:
cd acme-production-1 polycrate run app deploy
Durch die Idempotenz von Ansible wird der Cluster in den Zustand gebracht, der in Version 1.1.0 beschrieben ist. Kein manuelles Zurückrollen, keine „Rollback-Playbooks“, die extra gepflegt werden müssen – die Rollback-Logik kann bei Bedarf selbst wieder als Action in denselben Block integriert werden (z. B. mit einem rollback.yml).
Namespace-Isolation pro Block
Ein wichtiger Baustein für Multi-Cluster- und Multi-Workspace-Szenarien ist die saubere Isolation auf Namespace-Ebene.
In den workspace.poly-Beispielen oben haben wir:
config:
namespace: "acme-app-acme-staging-1" # bzw. …-production-1
Das führt zu:
- Namespace
acme-app-acme-staging-1im Staging-Cluster - Namespace
acme-app-acme-production-1im Production-Cluster
Vorteile:
- Keine versehentliche Überschneidung von Ressourcen, wenn z. B. mehrere Teams mit denselben Blöcken arbeiten.
- Klare Zuordnung im Audit: Aus Logs und Cluster-States ist sofort ersichtlich, aus welchem Workspace (und damit aus welchem Cluster-Kontext) ein Deployment stammt.
- Guardrails gegen Playbook-Wildwuchs: Der Namespace steht im Block, nicht in zig einzelnen Playbooks oder ad-hoc
kubectl apply-Skripten.
Die Polycrate-Best Practices empfehlen Namespace-Isolation pro Block explizit als Standard, insbesondere in regulierten Umgebungen.
Compliance, Verschlüsselung und Auditierbarkeit pro Workspace
Mit Multi-Workspace-Architekturen lässt sich Compliance pragmatisch anpacken:
-
Workspace-Verschlüsselung:
Secrets wiekubeconfig.ymlkönnen pro Workspace mitageverschlüsselt werden. Sie brauchen keinen separaten Vault, wenn es „nur“ um Workspace-Secrets geht. Mehr dazu in der Dokumentation zur Workspace-Verschlüsselung. -
Auditpfade pro Cluster:
Deployments, Promotions und Rollbacks sind als Polycrate-Actions nachvollziehbar. In Kombination mit Git-Historie derworkspace.poly-Dateien haben Sie eine lückenlose Pipeline: „Wer hat wann welche Block-Version in welchem Workspace ausgerollt?“. -
Saubere Trennung von Verantwortlichkeiten:
Das Team für den Staging-Cluster braucht keinen Zugriff auf Production-Secrets – und umgekehrt. Zugriffsrechte werden auf Workspace-Ebene vergeben.
Polycrate hilft hier nicht nur technikseitig: Das Block-Modell und das Container-Execution-Model verhindern viele typische Fehlerquellen, die man bei plain Ansible immer wieder manuell einhegen muss.
Häufige Fragen
Kann ich nicht doch mehrere Kubernetes-Cluster in einem Workspace verwalten?
Technisch ließen sich mehrere Kubeconfigs in einem Container nutzen, aber Polycrate ist bewusst anders designt. Ein Workspace hat genau eine kubeconfig unter artifacts/secrets/kubeconfig.yml. Multi-Cluster wird über mehrere Workspaces abgebildet.
Das macht Dinge wie Promotions, Zugriffssteuerung, Verschlüsselung und Audits wesentlich einfacher. Gemeinsame Logik steckt in geteilten Blöcken aus der Registry, nicht in geteiltem Workspace-State.
Wie gehe ich mit Unterschieden zwischen Staging und Production um?
Dafür gibt es die config-Sektion pro Block in der workspace.poly. Sie können z. B.:
- unterschiedliche Replikazahlen konfigurieren,
- verschiedene Images (z. B. mit Debug-Flags in Staging),
- andere Ressourcen-Limits oder Feature-Flags setzen.
Der Block selbst bleibt identisch, nur die Konfiguration pro Workspace ändert sich. So behalten Sie einheitliche Automatisierungslogik, ohne dass Staging und Production denselben Stand erzwingen müssen.
Wie werden Kubeconfigs und Secrets geschützt?
Alle Workspace-Secrets (z. B. kubeconfig.yml, Tokens, Zertifikate) liegen unter artifacts/secrets/. Über die eingebaute Workspace-Verschlüsselung können Sie diesen Bereich mit age verschlüsseln. Damit bleiben sensible Daten auch in Git-Repositories geschützt.
Die Dokumentation zur Workspace-Verschlüsselung beschreibt Varianten und Integrationsmöglichkeiten im Detail.
Weitere Fragen? Siehe unsere FAQ
Von der Theorie zur Umsetzung
Was bleibt, ist ein klares Bild:
- Ein Workspace = Ein Cluster
- Gemeinsame Logik = Geteilte Blöcke in der Registry
- Promotions und Rollbacks = Versionswechsel in
workspace.poly - Isolation = Eigene Namespaces pro Block und eigene Secrets pro Workspace
Polycrate nimmt Ihnen dabei viel von dem ab, was mit plain Ansible sonst in eigene Skripte, Konventionen und Tools auslagert wird: Containerisierte, einheitliche Toolchains, ein strukturiertes Block-Modell statt Playbook-Wildwuchs, eingebaute Registry-Integration und Workspace-Verschlüsselung.
Bei ayedo haben wir diesen Ansatz in vielen Projekten erprobt – von kleinen Setups mit einem Staging- und einem Production-Cluster bis hin zu komplexen Multi-Cluster-Landschaften mit mehreren Teams und Compliance-Anforderungen. Ob Sie erst mit einem Staging-Cluster beginnen oder bereits eine gewachsene Flotte an Clustern besitzen: Der Schritt hin zu Multi-Workspace-Strukturen ist überschaubar, wenn man systematisch vorgeht.
Wenn Sie sehen möchten, wie das in Ihrer Umgebung aussehen könnte – inklusive konkreter workspace.poly-Struktur, Block-Design und Registry-Strategie – dann lohnt sich eine gemeinsame, praxisnahe Demo.
Mehr zu Formaten mit ayedo: Workshops.