Einführung
Der Betrieb von Kubernetes-Clustern bei mehreren Cloud-Anbietern bringt eine Herausforderung für die Governance mit sich: Wie lässt sich sicherstellen, dass jeder Cluster denselben Sicherheits- und Betriebsrichtlinien folgt? Ohne eine zentralisierte Durchsetzung kommt es zu uneinheitlichen Konfigurationen – ein Cluster erlaubt privilegierte Container, ein anderer hat keine Ressourcenbeschränkungen und bei einem dritten fehlen in den Namespaces erforderliche Labels. Diese Lücken bergen Sicherheitsrisiken und erschweren Audits erheblich.
„Policy-as-Code“ löst dieses Problem, indem es Regeln definiert, die Kubernetes bei der Zulassung automatisch durchsetzt. OPA Gatekeeper ist das Standardwerkzeug hierfür im Kubernetes-Ökosystem. Es nutzt einen Webhook-basierten Zulassungscontroller, der jede API-Anfrage anhand Ihrer Richtlinien überprüft, bevor die Anfrage gespeichert wird. In Kombination mit der Kubermatic Kubernetes Platform (KKP) können Sie die Durchsetzung von Richtlinien über alle Ihre Cluster hinweg von einer einzigen Steuerungsebene aus verwalten.
In diesem Tutorial aktivieren Sie die OPA-Gatekeeper-Integration auf einem KKP Community Edition-Seed-Cluster, stellen Gatekeeper auf einem Benutzer-Cluster bereit und erstellen zwei Richtlinien: eine, die bestimmte Labels in Namespaces vorschreibt, und eine weitere, die privilegierte Container blockiert. Am Ende verfügen Sie über eine funktionsfähige Governance-Konfiguration, die Sie mit zusätzlichen Richtlinien an Ihre eigenen Anforderungen anpassen können.
Hinweis: Die hier beschriebene OPA-Gatekeeper-Integration ist in der KKP Community Edition verfügbar. Sie wird über die Seed-Ressource konfiguriert, auf die in der KKP CE uneingeschränkter Zugriff besteht. Es ist keine Unternehmenslizenz erforderlich.
Was Sie lernen werden:
- So aktivieren Sie die OPA-Integration auf einem KKP CE-Seed-Cluster
- So erstellen Sie ConstraintTemplates und Constraints für Gatekeeper
- So testen Sie die Durchsetzung von Richtlinien und überprüfen vorhandene Ressourcen
- So erstellen Sie eine Bibliothek mit Governance-Richtlinien für Multi-Cloud-Umgebungen
Voraussetzungen
Bevor Sie beginnen, stellen Sie sicher, dass Sie Folgendes zur Hand haben:
- KKP Community Edition — Eine laufende KKP-CE-Installation mit mindestens einem konfigurierten Seed-Cluster
- Ein Benutzercluster — Mindestens ein über KKP bereitgestellter Benutzercluster (beliebiger Cloud-Anbieter)
- kubectl — Version 1.27 oder höher, konfiguriert mit Zugriff sowohl auf den Seed-Cluster als auch auf den Benutzer-Cluster
- Zugriff für Cluster-Administratoren — Sie benötigen die Berechtigung, Seed-Ressourcen zu bearbeiten und CRDs im Benutzercluster anzulegen
- Helm — Version 3.12 oder höher (für die Installation von Gatekeeper)
Geschätzte Dauer: 25 Minuten
In diesem Tutorial verwendete Umgebung:
- KKP Community Edition: v2.25+
- Kubernetes (Benutzercluster): 1.28+
- OPA Gatekeeper: v3.15+
- Helm: 3.12+
Schritt 1: Überprüfen Sie Ihre KKP-CE-Installation und den Seed-Cluster
Bevor Sie die OPA-Integration aktivieren, vergewissern Sie sich, dass Ihr KKP CE-Seed-Cluster läuft und erreichbar ist. Sie benötigen den Namen Ihres Seeds, um dessen Konfiguration im nächsten Schritt zu aktualisieren.
Wechseln Sie Ihren kubectl-Kontext zum Seed-Cluster:
# Verfügbare Kontexte auflisten
kubectl config get-contexts
# Zum Seed-Cluster-Kontext wechseln
kubectl config use-context seed-cluster
Überprüfen Sie, ob die Seed-Ressource vorhanden ist:
kubectl get seeds -n kubermatic
Erwartetes Ergebnis:
NAME ALTER
Europa-West 45d
Notieren Sie sich den Seed-Namen – Sie werden ihn im nächsten Schritt benötigen. Wenn Sie mehrere Seeds haben, können Sie die OPA-Integration für jeden einzelnen separat aktivieren.
Tipp: Wenn keine Seed-Ressourcen angezeigt werden, überprüfen Sie, ob Sie mit dem richtigen Cluster verbunden sind. Seed-Ressourcen befinden sich auf dem Master-/Seed-Cluster, nicht auf Benutzer-Clustern.
Schritt 2: Aktivieren Sie die OPA-Integration in der Seed-Ressource
KKP CE ermöglicht die Integration von OPA Gatekeeper über die Konfiguration der Seed-Ressource. Durch die Aktivierung dieser Funktion wird KKP angewiesen, die Verwaltung von Gatekeeper-Richtlinien für alle von diesem Seed verwalteten Benutzercluster zu unterstützen.
Bearbeiten Sie die Seed-Ressource, um die OPA-Integration zu aktivieren:
kubectl edit seed europe-west -n kubermatic
Füge das opaIntegration Abschnitt unter Spezifikation:
apiVersion: kubermatic.k8c.io/v1
Art: Seed
Metadaten:
Name: europe-west
Namespace: kubermatic
spec:
opaIntegration:
aktiviert: true
Webhook-Zeitlimit: 10
# ... Rest Ihrer bestehenden Seed-Konfiguration
Die webhookTimeout Das Feld legt die maximale Anzahl von Sekunden fest, innerhalb derer der Gatekeeper-Zulassungs-Webhook reagieren muss, bevor die Anfrage zugelassen wird. Ein Wert von 10 Sekunden bietet ein ausgewogenes Verhältnis zwischen der Zeit für die Richtlinienauswertung und der Benutzerfreundlichkeit.
Überprüfen Sie, ob die Seed-Ressource erfolgreich aktualisiert wurde:
kubectl get seed europe-west -n kubermatic -o jsonpath='{.spec.opaIntegration}' | python3 -m json.tool
Erwartetes Ergebnis:
{
"enabled": true,
"webhookTimeout": 10
}
Schritt 3: Installieren Sie Gatekeeper auf dem Benutzercluster
Nachdem die OPA-Integration auf Seed-Ebene aktiviert wurde, installieren Sie Gatekeeper nun auf dem Benutzercluster, auf dem Sie Richtlinien durchsetzen möchten. Wechseln Sie in Ihrem kubectl-Kontext zum Ziel-Benutzercluster.
kubectl config use-context user-cluster-01
Füge das Gatekeeper Helm hinzu und installiere es:
# Das Gatekeeper Helm hinzufügen
helm add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts
# Repo-Index aktualisieren
helm update
# Gatekeeper im Namespace „gatekeeper-system“ installieren
helm gatekeeper gatekeeper/gatekeeper \
--namespace gatekeeper-system \
--create-namespace \
--setauditInterval=60 \
--setconstraintViolationsLimit=50
Die Prüfintervall Diese Einstellung weist Gatekeeper an, vorhandene Ressourcen alle 60 Sekunden auf Verstöße gegen Richtlinien zu überprüfen. Die Grenzwert für Verstöße gegen Einschränkungen legt fest, wie viele Verstöße pro Einschränkung gespeichert werden.
Warten Sie, bis die Gatekeeper-Pods bereit sind:
kubectl -n gatekeeper-system wait--for=condition=readypod -l control-plane=controller-manager--timeout=120s
Überprüfen Sie die Installation:
kubectl get pods -n gatekeeper-system
Erwartetes Ergebnis:
NAME BEREIT STATUS NEUSTARTE ALTER
gatekeeper-audit-6b7d4b5f9c-xk2mn 1/1 Läuft 0 45s
gatekeeper-controller-manager-7c9f8d6b4d-2hj7p 1/1 Läuft 0 45s
gatekeeper-controller-manager-7c9f8d6b4d-9xt4k 1/1 Läuft 0 45s
gatekeeper-controller-manager-7c9f8d6b4d-rn3vw 1/1 Läuft 0 45s
Es sollten ein Audit-Pod und drei Controller-Manager-Pods laufen.
Warnung: Überspringen Sie den Warteschritt nicht. Wenn Sie ConstraintTemplates anwenden, bevor der Gatekeeper-Webhook bereit ist, werden diese möglicherweise nicht korrekt registriert.
Schritt 4: Erstellen Sie eine ConstraintTemplate, um Namespace-Labels vorzuschreiben
Nun erstellen Sie Ihre erste Richtlinie. Ein ConstraintTemplate definiert die Logik der Richtlinie mithilfe von Rego (der OPA-Richtliniensprache), und ein Constraint wendet diese Logik auf bestimmte Ressourcen an.
Diese Vorlage setzt voraus, dass bestimmte Bezeichnungen in den Namensräumen vorhanden sind. Dies ist eine gängige Anforderung im Rahmen der Governance – Teams benötigen häufig Namensräume, die mit einem Verantwortlichen, einer Kostenstelle oder einer Umgebungskennung gekennzeichnet sind.
Erstellen Sie eine Datei mit dem Namen require-labels-template.yaml:
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8srequiredlabels
annotations:
description: "Requires specified labels on resources"
spec:
crd:
spec:
names:
kind: K8sRequiredLabels
validation:
openAPIV3Schema:
type: object
properties:
labels:
type: array
description: "List of required label keys"
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredlabels
violation[{"msg": msg, "details": {"missing_labels": missing}}] {
provided := {label | input.review.object.metadata.labels[label]}
required := {label | label := input.parameters.labels[_]}
missing := required - provided
count(missing) > 0
msg := sprintf("Resource is missing required labels: %v", [missing])
}
Wende die ConstraintTemplate an:
kubectl apply -f require-labels-template.yaml
Überprüfen Sie, ob die Vorlage erstellt wurde und die entsprechende CRD verfügbar ist:
kubectl get constrainttemplates
Erwartetes Ergebnis:
NAME ALTER
k8srequiredlabels 10s
# Überprüfen Sie, ob die CRD generiert wurde
kubectl get crd | grep requiredlabels
Erwartetes Ergebnis:
k8srequiredlabels.constraints.gatekeeper.sh 17.03.2026 10:00:00Z
Tipp: Das ConstraintTemplate generiert dynamisch eine CRD. Sollte die CRD nicht innerhalb von 30 Sekunden erscheinen, überprüfen Sie die Protokolle des Gatekeeper-Controllers mit
kubectl logs -n gatekeeper-system -l control-plane=controller-manager.
Schritt 5: Erstellen Sie eine Einschränkung, um die Vorlage durchzusetzen
Nachdem die Vorlage eingerichtet ist, erstellen Sie eine Einschränkung, die diese durchsetzt. Diese Einschränkung erfordert die Team und Umwelt Labels für alle Namespaces im Cluster.
Erstellen Sie zunächst eine Produktion Namensraum, den Sie zum Testen verwenden werden:
kubectl create namespace production
Erstellen Sie nun eine Datei mit dem Namen require-ns-labels-constraint.yaml:
apiVersion: constraints.gatekeeper.sh/v1beta1
Art: K8sRequiredLabels
Metadaten:
name: require-namespace-labels
Spezifikation:
Durchsetzungsmaßnahme: verweigern
Übereinstimmung:
Arten:
- apiGroups: [""]
Arten: ["Namespace"]
ausgeschlosseneNamensräume:
- kube-system
- kube-public
- kube-node-lease
- default
- gatekeeper-system
- kubermatic
Parameter:
Labels:
- „team“
- „Umgebung“
Die ausgeschlossene Namensräume Diese Liste stellt sicher, dass System-Namespaces von dieser Richtlinie nicht blockiert werden. Ohne diese Ausnahmen könnten Sie versehentlich verhindern, dass Kubernetes die für den Betrieb erforderlichen Namespaces erstellt.
Die Einschränkung anwenden:
kubectl apply -f require-ns-labels-constraint.yaml
Überprüfen Sie, ob die Einschränkung aktiv ist:
kubectl get k8srequiredlabels
Erwartetes Ergebnis:
NAME DURCHSETZUNGSMASSNAHME GESAMTZAHL DER VERSTÖSSE
require-namespace-labels verweigern 1
Die GESAMTZAHL DER VERSTÖSSE Die Zählung zeigt möglicherweise bereits vorhandene Namensräume an (wie den Produktion (in dem soeben erstellten Namespace), die nicht über die erforderlichen Labels verfügen.
Schritt 6: Durchsetzung der Richtlinie testen
Prüfen Sie nun, ob die Richtlinie funktioniert. Versuchen Sie, einen Namespace ohne die erforderlichen Labels zu erstellen. Gatekeeper sollte dies ablehnen.
kubectl create namespace test-no-labels
Erwartetes Ergebnis:
Error from server (Forbidden): admission webhook "validation.gatekeeper.sh" denied the request: [require-namespace-labels] Resource is missing required labels: {"environment", "team"}
Die Anfrage wurde abgelehnt, da im Namensraum das Team und Umwelt Etiketten.
Erstellen Sie nun einen Namespace mit den erforderlichen Labels:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
name: test-with-labels
labels:
team: "platform"
environment: "staging"
EOF
Erwartetes Ergebnis:
Namespace „test-with-labels“ erstellt
Der Namensraum wurde erfolgreich erstellt, da er beide erforderlichen Bezeichnungen enthält.
Behebe das Produktion Namensraum, der zuvor ohne Bezeichnungen erstellt wurde:
kubectl label namespace production team=backend environment=production
Überprüfen Sie, ob die Anzahl der Verstöße zurückgegangen ist:
kubectl get k8srequiredlabels require-namespace-labels -o jsonpath='{.status.totalViolations}'
Erwartetes Ergebnis:
0
Den Test-Namespace bereinigen:
kubectl delete namespace test-with-labels
Schritt 7: Fügen Sie eine zweite Richtlinie hinzu, um privilegierte Container zu blockieren
Eine einzige Richtlinie ist ein guter Anfang, doch für eine wirksame Governance sind mehrere Ebenen erforderlich. Fügen Sie eine zweite Richtlinie hinzu, die verhindert, dass Container im privilegierten Modus ausgeführt werden. Privilegierte Container haben uneingeschränkten Zugriff auf den Host, was in jeder Multi-Tenant- oder Produktionsumgebung ein erhebliches Sicherheitsrisiko darstellt.
Erstellen Sie die ConstraintTemplate in einer Datei namens block-privileged-template.yaml:
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8sblockprivilegedcontainer
annotations:
description: "Blocks containers from running in privileged mode"
spec:
crd:
spec:
names:
kind: K8sBlockPrivilegedContainer
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8sblockprivilegedcontainer
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
container.securityContext.privileged == true
msg := sprintf("Container <%v> is not allowed to run as privileged", [container.name])
}
violation[{"msg": msg}] {
container := input.review.object.spec.initContainers[_]
container.securityContext.privileged == true
msg := sprintf("Init container <%v> is not allowed to run as privileged", [container.name])
}
Diese Vorlage überprüft sowohl reguläre Container als auch Init-Container. Wenden Sie sie an:
kubectl apply -f block-privileged-template.yaml
Erstellen Sie nun die Einschränkung in einer Datei namens block-privileged-constraint.yaml:
apiVersion: constraints.gatekeeper.sh/v1beta1
Art: K8sBlockPrivilegedContainer
Metadaten:
name: block-privileged-containers
Spezifikation:
Durchsetzungsmaßnahme: verweigern
Übereinstimmung:
Arten:
- apiGroups: [""]
Arten: ["Pod"]
Namensräume:
- production
ausgeschlosseneNamensräume:
- kube-system
Diese Einschränkung gilt für Pods in der Produktion speziell diesen Namespace. Wenden Sie ihn an:
kubectl apply -f block-privileged-constraint.yaml
Testen Sie dies, indem Sie versuchen, einen privilegierten Pod zu erstellen:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: privileged-test
namespace: production
spec:
containers:
- name: nginx
image: nginx:latest
securityContext:
privileged: true
EOF
Erwartetes Ergebnis:
Error from server (Forbidden): error when creating "STDIN": admission webhook "validation.gatekeeper.sh" denied the request: [block-privileged-containers] Container <nginx> is not allowed to run as privileged
Versuchen Sie nun, einen nicht privilegierten Pod zu starten, um zu überprüfen, ob legitime Workloads weiterhin bereitgestellt werden:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: safe-test
namespace: production
spec:
containers:
- name: nginx
image: nginx:latest
securityContext:
privileged: false
EOF
Erwartetes Ergebnis:
pod/safe-test erstellt
Den Testcontainer aufräumen:
kubectl delete pod safe-test -n production
Schritt 8: Überprüfung bestehender Ressourcen auf Verstöße gegen Richtlinien
Gatekeeper wendet Richtlinien nicht nur auf neue Ressourcen an, sondern überprüft auch regelmäßig bestehende Ressourcen (konfiguriert durch Prüfintervall (während der Installation). Dies ist hilfreich, um einen Überblick über den aktuellen Stand der Compliance im gesamten Cluster zu erhalten.
Überprüfen Sie alle Einschränkungen auf Verstöße:
kubectl get k8srequiredlabels require-namespace-labels -o yaml | grep -A 50 'violations:'
Sie können auch alle Einschränkungen und die Anzahl ihrer Verstöße mit einem einzigen Befehl auflisten:
kubectl get constraints
Erwartetes Ergebnis:
NAME DURCHSETZUNGSMASSNAHME GESAMTZAHL DER VERSTÖSSE
block-privileged-containers verweigern 0
namespace-labels-erfordern verweigern 0
Um einen detaillierten Überblick darüber zu erhalten, welche Ressourcen gegen eine bestimmte Einschränkung verstoßen:
kubectl describe k8srequiredlabels require-namespace-labels
Achten Sie auf das Status.Verstöße Abschnitt in der Ausgabe. Jeder Eintrag enthält die betreffende Ressource, ihren Namensraum und die spezifische Richtlinienmeldung.
Tipp: Um einen clusterweiten Compliance-Bericht zu erhalten, können Sie Folgendes festlegen:
Durchsetzungsmaßnahme: Verwarnungstattablehnenbei neuen Einschränkungen. Dadurch werden Verstöße protokolliert, ohne dass Anfragen blockiert werden. Dies ist während einer Einführungsphase nützlich, in der Sie zunächst die Auswirkungen einschätzen möchten, bevor Sie die Regeln durchsetzen.
So schalten Sie eine bestehende Einschränkung zu Prüfzwecken in den reinen Warnmodus um:
kubectl patch k8srequiredlabels require-namespace-labels \
--type='merge' \
-p '{"spec":{"enforcementAction":"warn"}}'
Denk daran, es wieder auf ablehnen sobald Sie die Verstöße behoben haben:
kubectl patch k8srequiredlabels require-namespace-labels \
--type='merge' \
-p '{"spec":{"enforcementAction":"deny"}}'
Fehlerbehebung
Der Gatekeeper-Webhook fängt keine Anfragen ab
Ursache: Die Webhook-Konfiguration ist möglicherweise nicht registriert, oder die Gatekeeper-Pods sind noch nicht bereit.
Lösung:
# Überprüfen Sie, ob der Webhook vorhanden ist
kubectl get validatingwebhookconfigurations | grep gatekeeper
# Überprüfen Sie, ob die Pods laufen
kubectl get pods -n gatekeeper-system
# Controller-Protokolle auf Fehler überprüfen
kubectl logs -n gatekeeper-system -l control-plane=controller-manager--tail=50
Die CRD „ConstraintTemplate“ wurde nicht erstellt
Ursache: Der Rego-Code in der Vorlage enthält möglicherweise Syntaxfehler, wodurch die Erstellung des CRD verhindert wird.
Lösung:
# Überprüfe den Status von ConstraintTemplate auf Fehler
kubectl get constrainttemplate k8srequiredlabels -o jsonpath='{.status}'
# Nach Fehlerereignissen suchen
kubectl describe constrainttemplate k8srequiredlabels
Überprüfen Sie den Rego-Code auf Tippfehler oder falsche Paketnamen. Der Paketname im Rego-Block muss mit dem Namen des ConstraintTemplate (in Kleinbuchstaben) übereinstimmen.
Die Einschränkung zeigt Verstöße an, blockiert jedoch keine Anfragen
Grund: Die Durchsetzungsmaßnahme kann auf warnen oder Probedurchlauf statt ablehnen.
Lösung:
# Überprüfen Sie die Durchsetzungsmaßnahme
kubectl get k8srequiredlabels require-namespace-labels -o jsonpath='{.spec.enforcementAction}'
Wenn die Ausgabe lautet warnen oder Probedurchlauf, aktualisieren Sie es auf ablehnen:
kubectl patch k8srequiredlabels require-namespace-labels \
--type='merge' \
-p '{"spec":{"enforcementAction":"deny"}}'
Verstöße gegen die Prüfungsvorschriften werden nicht aktualisiert
Grund: Der Audit-Controller läuft nach einem Zeitplan, der durch Prüfintervall. Möglicherweise gibt es auch Ressourcenbeschränkungen, die den Audit-Pod daran hindern, seinen Scan abzuschließen.
Lösung:
# Die Protokolle des Audit-Pods überprüfen
kubectl logs -n gatekeeper-system -l control-plane=audit-controller--tail=50
# Starten Sie den Audit-Pod neu, um einen sofortigen Scan auszulösen
kubectl delete pod -n gatekeeper-system -l control-plane=audit-controller
Nächste Schritte
Nachdem Sie nun über eine funktionierende Governance-Struktur verfügen, sollten Sie folgende Punkte berücksichtigen:
- Gatekeeper-Richtlinienbibliothek – Durchsuchen Sie vorgefertigte Richtlinien für gängige Anforderungen wie Image-Registerst, Eingangsbeschränkungen und Ressourcenkontingente
- KKP-Benutzercluster-Verwaltung — Erfahren Sie mehr über die Verwaltung von Benutzerclustern über mehrere Clouds hinweg mit KKP
- Erweitern Sie Ihre Richtlinienbibliothek – Fügen Sie Richtlinien für Zulassungslisten für Container-Images, Einschränkungen für Ingress-Hostnamen und erforderliche Annotationen für die Kostenverfolgung hinzu
- In CI/CD integrieren — Verwendung
Gator-Test(die Gatekeeper-Befehlszeilenschnittstelle), um Richtlinien in Ihrer Pipeline zu überprüfen, bevor sie den Cluster erreichen
Zusammenfassung
Sie haben die OPA-Gatekeeper-Integration auf einem KKP Community Edition-Seed-Cluster aktiviert und Gatekeeper auf einem Benutzer-Cluster installiert. Sie haben zwei Richtlinien erstellt: eine, die Team und Umwelt Labels für Namespaces und eine weitere, die privilegierte Container im Produktions-Namespace blockiert. Sie haben die Durchsetzung getestet, indem Sie überprüft haben, ob nicht konforme Ressourcen abgelehnt und konforme Ressourcen akzeptiert werden, und Sie haben die Audit-Funktion von Gatekeeper genutzt, um vorhandene Ressourcen anhand Ihrer Richtlinien zu überprüfen. Dieses Muster lässt sich auf eine beliebige Anzahl von Clustern anwenden, die von KKP verwaltet werden – definieren Sie Ihre Richtlinien einmalig und stellen Sie sie in Ihrer gesamten Multi-Cloud-Flotte bereit.
