Auf dieser Seite wird gezeigt, wie Sie Ressourcen mithilfe des Policy Controller mutieren. Durch Mutieren lassen sich z. B. Standardwerte festlegen. Beispielsweise können Sie ein Label für alle Ressourcen in einem bestimmten Namespace einfügen oder für die imagePullPolicy
eines Pods standardmäßig den Wert Always
festlegen, wenn dieser nicht bereits angegeben ist.
Mutation aktivieren
Console
Führen Sie die folgenden Schritte aus, um die Mutation zu aktivieren:
- Rufen Sie in der Google Cloud Console im Abschnitt Statusverwaltung die Seite GKE Enterprise-Richtlinie auf.
- Wählen Sie auf dem Tab Einstellungen in der Clustertabelle in der Spalte Konfiguration bearbeiten die Option Bearbeiten edit aus.
- Maximieren Sie das Menü Policy Controller-Konfiguration bearbeiten.
- Klicken Sie auf das Kästchen Mutations-Webhook aktivieren.
- Wählen Sie Änderungen speichern aus.
gcloud Policy Controller
Führen Sie den folgenden Befehl aus, um die Mutation zu aktivieren:
gcloud container fleet policycontroller update \
--memberships=MEMBERSHIP_NAME \
--mutation
Ersetzen Sie MEMBERSHIP_NAME
durch den Mitgliedschaftsnamen des registrierten Clusters, für den die Mutation aktiviert werden soll. Sie können mehrere Mitgliedschaften durch Kommas getrennt angeben.
gcloud-ConfigManagement
Eine Mutation muss durch Festlegen des Werts true
für spec.policyController.mutation.enabled
in der Ressource config-management
aktiviert werden:
apiVersion: configmanagement.gke.io/v1
kind: ConfigManagement
metadata:
name: config-management
spec:
policyController:
enabled: true
mutation:
enabled: true
Wenn Sie den gcloud CLI-Befehl verwenden, müssen Sie zur Aktivierung der Mutation die Alphaversion verwenden, wie im folgenden Beispiel gezeigt:
# apply-spec.yaml
applySpecVersion: 1
spec:
policyController:
enabled: true
mutationEnabled: true
Nachdem Sie die Datei apply-spec.yaml
erstellt haben, führen Sie den folgenden Befehl aus, um die Konfiguration anzuwenden:
gcloud alpha container fleet config-management apply \
--membership=MEMBERSHIP_NAME \
--config=CONFIG_YAML_PATH \
--project=PROJECT_ID
Dabei gilt:
MEMBERSHIP_NAME
: Name der Mitgliedschaft des registrierten Clusters mit den Policy Controller-Einstellungen, die Sie verwenden möchtenCONFIG_YAML_PATH
: Pfad zur Dateiapply-spec.yaml
PROJECT_ID
: Ihre Projekt-ID
Definitionen
- mutator: Eine Kubernetes-Ressource für die Konfiguration des Mutationsverhaltens des Policy Controller.
- system: Eine Anordnung mehrerer Mutatoren.
Mutationsbeispiel
Im folgenden Beispiel wird ein Mutator gezeigt, mit dem imagePullPolicy
für alle Container in allen Pods auf Always
gesetzt wird:
# set-image-pull-policy.yaml
apiVersion: mutations.gatekeeper.sh/v1alpha1
kind: Assign
metadata:
name: always-pull-image
spec:
applyTo:
- groups: [""]
kinds: ["Pod"]
versions: ["v1"]
location: "spec.containers[name: *].imagePullPolicy"
parameters:
assign:
value: "Always"
In diesem Beispiel gibt es die standardmäßigen Kubernetes-Metadatenfelder (apiVersion
, kind
, metadata.name
), aber in spec
ist das Verhalten des Mutators konfiguriert.
spec.applyTo
bindet den Mutator an die angegebenen Ressourcen. Wenn wir bestimmte Felder in einem Objekt ändern, definieren wir implizit auch das Schema dieses Objekts. Beispielsweise ist die Anwendung des aktuellen Mutators auf die Namespace
-Ressource nicht sinnvoll. Deshalb ist dieses Feld erforderlich, um für Policy Controller anzugeben, für welche Schemas dieser Mutator relevant sein soll.
GroupVersionKinds
, die in dieser Liste fehlen, werden nicht mutiert.
Mit spec.location
wird festgelegt, welches Feld geändert werden soll. In diesem Fall wird ein Glob (*
) verwendet, um anzugeben, dass alle Einträge in der Containerliste geändert werden. Die einzige Art von Listen, die vom Feld location
geprüft werden können, sind Kartenlisten. Dabei muss das Schlüsselfeld für die Karte angegeben werden. Listen vom Typ "Karte" sind ein Kubernetes-Konstrukt. Weitere Informationen dazu finden Sie in der Kubernetes-Dokumentation.
spec.parameters.assign.value
ist der Wert, der location
zugewiesen werden soll.
Dieses Feld hat keinen bestimmten Typ und kann beliebige Werte annehmen. Beachten Sie aber, dass Kubernetes die Anfrage nach der Mutation weiterhin prüft. Wenn Werte mit einem falschen Schema für das Objekt eingefügt werden, das geändert wird, wird die Anfrage abgelehnt.
Mutatoren für Jobs verwenden
Wenn Sie einen Job oder CronJob konfigurieren, müssen Sie die Version und Gruppe separat angeben, wie im folgenden Beispiel gezeigt:
applyTo:
- groups: ["batch"]
kind: ["Job"]
versions: ["v1"]
Wenn Sie einen Mutator für Jobs verwenden, werden die vorhandenen Jobs nur mutiert, wenn sie geändert werden. Durch die Änderung eines Jobs wird eine Anfrage an den Mutations-Webhook ausgelöst und dieser wird mutiert.
Ablauf der Ausführung
Der wahrscheinlich wichtigste Aspekt von Kubernetes-Mutations-Webhooks ist die Verwendung der zugehörigen Richtlinie für den nochmaligen Aufruf, da die Ausgabe eines Mutators das Verhalten eines anderen Mutators ändern kann. Wenn Sie beispielsweise einen neuen Sidecar-Container hinzufügen, muss ein Mutator, der die Image-Pull-Richtlinie für alle Container festlegt, einen neuen Container mutieren.
In der Praxis bedeutet dies, dass für eine beliebige Anfrage der Mutations-Webhook eines Policy Controller mehr als einmal aufgerufen werden kann.
Zur Verringerung der Latenz wird der Policy Controller automatisch aufgerufen, um zusätzliche HTTP-Anfragen zu vermeiden. Dies bedeutet, dass die Sidecar-Einfügung und die Image-Pull-Richtlinie das erwartete Ergebnis haben.
Die Mutationsroutine des Policy Controller wird so lange aufgerufen, bis die Ressource "konvergiert", d. h. bis zusätzliche Iterationen keine Auswirkung mehr haben.
Syntax des Standorts
Für die Syntax des Standorts wird der Punktzugriff (.
) zum Prüfen von Feldern verwendet. Bei zugeordneten Listen können Nutzer mithilfe der Syntax [<key>: <value>]
auf einzelne Objekte in einer Liste oder mit [<key>: *]
auf alle Objekte in der Liste verweisen.
Werte und Felder können entweder in einfache ('
) oder in doppelte ("
) Anführungszeichen gesetzt werden. Das ist erforderlich, wenn dafür Sonderzeichen wie Punkte oder Leerzeichen verwendet werden.
In Werten in Anführungszeichen können Sonderzeichen mit Escapezeichen in Form des Präfix \
versehen werden. "Use \" to escape and \\\" to escape"
wird zu Use " to escape and \" to escape
.
Im Folgenden finden Sie einige Beispiele für die Ressource v1/Pod
:
spec.priority
verweist aufspec.priority
spec.containers[name: "foo"].volumeMounts[mountPath: "/my/mount"].readOnly
verweist auf das FeldreadOnly
der/my/mount
-Bereitstellung desfoo
-Containers.spec.containers[name: *].volumeMounts[mountPath: "/my/mount"].readOnly
verweist auf das FeldreadOnly
der/my/mount
-Bereitstellung aller Container.
Wenn Sie auf einen Standort verweisen, der derzeit für eine Ressource nicht vorhanden ist, wird dieser Standort standardmäßig erstellt. Dieses Verhalten kann über Pfadtests konfiguriert werden.
Pfadtests
Wie können Standardeinstellungen festgelegt werden, mit denen vermieden wird, dass ein bereits vorhandener Wert geändert wird? Beispielsweise kann /secure-mount
für alle Container als schreibgeschützt festgelegt werden. Es soll aber kein /secure-mount
erstellt werden, wenn er noch nicht vorhanden ist. Dies lässt sich jeweils über Pfadtests ausführen.
Im folgenden Beispiel wird eine Mutation von imagePullPolicy
vermieden, wenn dieser Pfad bereits festgelegt ist:
# set-image-pull-policy.yaml
apiVersion: mutations.gatekeeper.sh/v1alpha1
kind: Assign
metadata:
name: always-pull-image
spec:
applyTo:
- groups: [""]
kinds: ["Pod"]
versions: ["v1"]
location: "spec.containers[name: *].imagePullPolicy"
parameters:
assign:
value: "Always"
pathTests:
- subPath: "spec.containers[name: *].imagePullPolicy"
condition: "MustNotExist"
Mit dem nächsten Beispiel wird das Erstellen eines leeren sidecar
-Containers unterbunden, wenn er noch nicht vorhanden ist:
# set-image-pull-policy.yaml
apiVersion: mutations.gatekeeper.sh/v1alpha1
kind: Assign
metadata:
name: always-pull-image
spec:
applyTo:
- groups: [""]
kinds: ["Pod"]
versions: ["v1"]
location: 'spec.containers[name: "sidecar"].imagePullPolicy'
parameters:
assign:
value: "Always"
pathTests:
- subPath: 'spec.containers[name: "sidecar"]'
condition: "MustExist"
Bei Bedarf können mehrere Pfadtests angegeben werden.
subPath
muss ein Präfix von oder gleich location
sein.
Für condition
sind nur die Werte MustExist
und MustNotExist
gültig.
Abgleich
Mutatoren ermöglichen auch einen Abgleich, wobei die gleichen Kriterien wie bei Einschränkungen verwendet werden.
Mutatoren
Derzeit gibt es zwei Arten von Mutatoren: Assign
und AssignMetadata
.
Assign
Assign
kann jeden Wert außerhalb des Felds metadata
einer Ressource ändern.
Da alle GroupVersionKinds
ein eindeutiges Schema haben, muss der Mutator an eine Reihe von bestimmten GroupVersionKinds
gebunden sein.
Er hat das folgende Schema:
apiVersion: mutations.gatekeeper.sh/v1alpha1
kind: Assign
metadata:
name: always-pull-image
spec:
applyTo:
- groups: [""]
kinds: ["Pod"]
versions: ["v1"]
match:
kinds: # redundant because of `applyTo`, but left in for consistency
- apiGroups: ["*"]
kinds: ["*"]
namespaces: ["my-namespace"]
scope: "Namespaced" # or "Cluster"
excludedNamespaces: ["some-other-ns"]
labelSelector:
matchLabels:
mutate: "yes"
matchExpressions:
- key: "my-label"
operator: "In" # or, "NotIn", "Exists", or "DoesNotExist"
values: ["my-value"]
namespaceSelector:
matchLabels:
mutate: "yes"
matchExpressions:
- key: "my-label"
operator: "In" # or, "NotIn", "Exists", or "DoesNotExist"
values: ["my-value"]
location: "spec.containers[name: *].imagePullPolicy"
parameters:
pathTests:
- subPath: 'spec.containers[name: "sidecar"]' # must be a prefix of `location`
condition: "MustExist" # or "MustNotExist"
- subPath: "spec.containers[name: *].imagePullPolicy"
condition: "MustNotExist"
assign:
value: "Always" # any type can go here, not just a string
AssignMetadata
Mit AssignMetadata
können neue Metadatenlabels hinzugefügt werden. Der Wert vorhandener Metadatenlabels lässt sich damit aber nicht ändern. Andernfalls wäre es möglich, ein System von Mutatoren zu schreiben, die unbegrenzt rekursiv sind und zu einer Zeitüberschreitung bei Anfragen führen.
Da alle Ressourcen das gleiche metadata
-Schema haben, muss nicht angegeben werden, auf welche Ressource AssignMetadata
angewendet wird.
Da mit AssignMetadata
keine umfangreichen Mutationen möglich sind, ist auch sein Schema etwas einfacher.
apiVersion: mutations.gatekeeper.sh/v1alpha1
kind: AssignMetadata
metadata:
name: set-team-name
spec:
match:
kinds:
- apiGroups: ["*"]
kinds: ["*"]
namespaces: ["my-namespace"]
scope: "Namespaced" # or "Cluster"
excludedNamespaces: ["some-other-ns"]
labelSelector:
matchLabels:
mutate: "yes"
matchExpressions:
- key: "my-label"
operator: "In" # or, "NotIn", "Exists", or "DoesNotExist"
values: ["my-value"]
namespaceSelector:
matchLabels:
mutate: "yes"
matchExpressions:
- key: "my-label"
operator: "In" # or, "NotIn", "Exists", or "DoesNotExist"
values: ["my-value"]
location: "metadata.labels.team" # must start with `metadata.labels`
parameters:
assign:
value: "Always" # any type can go here, not just a string
Best Practices
Kubernetes-Vorsichtsmaßnahmen
In der Kubernetes-Dokumentation sind wichtige Überlegungen zur Verwendung von Mutations-Webhooks aufgeführt. Da der Policy Controller als Kubernetes-Zulassungs-Webhook dient, gelten hier die entsprechenden Empfehlungen.
Die Mutationssyntax des Policy Controller ist so konzipiert, dass die Berücksichtigung der Anforderungen für die Ausführung bei Mutations-Webhooks, einschließlich Idempotenz, vereinfacht wird.
Schreibmutatoren
Atomarität
Es wird empfohlen, jeden Mutator so eigenständig wie möglich anzuwenden. Da für Kubernetes das Modell Eventual Consistency gilt, sollte ein Mutator nicht davon abhängig sein, dass ein zweiter Mutator erkannt wurde, um seinen Job ordnungsgemäß ausführen zu können. Wenn Sie beispielsweise einen Sidecar hinzufügen, fügen Sie ihn insgesamt hinzu und erstellen ihn nicht stückweise über mehrere Mutatoren.
Validierung
Wenn es eine Bedingung gibt, die erzwungen werden soll, ist zu empfehlen, dass der Mutator eine entsprechende Einschränkung hat. Diese sorgt dafür, dass Anfragen, die gegen Richtlinien verstoßen, abgelehnt werden, und bereits vorhandene Verstöße bei der Prüfung erkannt werden.
Notfallwiederherstellung
Die Mutation wird als mutierender Kubernetes-Webhook implementiert. Dieser kann auf die gleiche Weise wie der validierende Webhook beendet werden. Die relevante Ressource ist jedoch eine MutatingWebhookConfiguration
namens gatekeeper-mutating-webhook-configuration
.
Nächste Schritte
- Erläuterungen und Beispiele für die Gatekeeper-Mutation finden Sie in der Open-Source-Dokumentation.