Questa pagina mostra come modificare le risorse utilizzando
Policy Controller. È utile per
impostare valori predefiniti. Ad esempio, potresti voler inserire
un'etichetta per tutte le risorse in uno spazio dei nomi specifico o impostare come predefinito il valore di imagePullPolicy
di un pod su Always
se non è già impostato.
Abilita mutazione
Console
Per abilitare la mutazione, completa i seguenti passaggi:
- Nella console Google Cloud , vai alla pagina Policy nella sezione Posture Management.
- Nella scheda Impostazioni, seleziona Modifica edit nella colonna Modifica configurazione della tabella dei cluster.
- Espandi il menu Modifica la configurazione di Policy Controller.
- Seleziona la casella di controllo Abilita webhook di modifica.
- Seleziona Salva modifiche.
gcloud
Per abilitare la mutazione, esegui questo comando:
gcloud container fleet policycontroller update \
--memberships=MEMBERSHIP_NAME \
--mutation
Sostituisci MEMBERSHIP_NAME
con il nome dell'appartenenza del cluster registrato per abilitare la mutazione. Puoi specificare più abbonamenti separati da una virgola.
Definizioni
- mutator:una risorsa Kubernetes che consente di configurare il comportamento di mutazione di Policy Controller.
- system: Una disposizione di più mutatori
Esempio di mutazione
L'esempio seguente mostra un mutatore che
imposta imagePullPolicy
per tutti i container in tutti i pod su Always
:
# 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 questo esempio, sono presenti i campi dei metadati Kubernetes standard
(apiVersion
, kind
, metadata.name
), ma spec
è dove viene configurato il comportamento
del mutatore.
spec.applyTo
associa il mutatore alle risorse specificate. Poiché stiamo modificando campi specifici in un oggetto, stiamo definendo implicitamente lo schema dell'oggetto. Ad esempio, il mutatore attuale non avrebbe senso se venisse applicato
a una risorsa Namespace
. Per questo motivo, questo campo è obbligatorio
in modo che Policy Controller sappia per quali schemi è pertinente questo mutatore.
GroupVersionKinds
mancanti in questo elenco non vengono modificati.
spec.location
indica il campo da modificare. In questo caso, utilizziamo
un glob (*
) per indicare che vogliamo modificare tutte le voci nell'elenco
contenitore. Tieni presente che gli unici tipi di elenchi che possono essere attraversati
dal campo location
sono gli elenchi di tipo mappa e deve essere specificato
il campo chiave per la mappa. Gli elenchi di tipo mappa sono una struttura Kubernetes. Per ulteriori dettagli, consulta la documentazione di Kubernetes.
spec.parameters.assign.value
è il valore da assegnare a location
.
Questo campo non è tipizzato e può accettare qualsiasi valore, anche se Kubernetes
convalida comunque la richiesta dopo la mutazione, quindi l'inserimento di valori con uno
schema errato per l'oggetto modificato comporta il rifiuto della richiesta.
Utilizzare i mutatori per le offerte di lavoro
Se stai configurando un Job o un CronJob, devi specificare la versione e il gruppo separatamente, come mostrato nell'esempio seguente:
applyTo:
- groups: ["batch"]
kind: ["Job"]
versions: ["v1"]
Quando utilizzi un mutatore per Jobs, i job esistenti non vengono modificati a meno che non vengano modificati. La modifica di un job attiva una richiesta al webhook di modifica e ne causa la mutazione.
Flusso di esecuzione
Forse il concetto più importante da comprendere sugli webhook di mutazione di Kubernetes è la loro norma di reinvocazione, perché l'output di un mutatore potrebbe modificare il comportamento di un altro mutatore. Ad esempio, se aggiungi un nuovo container sidecar, un mutatore che imposta il criterio di pull dell'immagine per tutti i container ora ha un nuovo container da mutare.
In pratica, ciò significa che per una determinata richiesta, il webhook di mutazione di Policy Controller potrebbe essere chiamato più di una volta.
Per ridurre la latenza, Policy Controller si richiama automaticamente per evitare richieste HTTP aggiuntive. Ciò significa che l'inserimento di sidecar e il pull delle immagini hanno il risultato previsto.
La routine di mutazione di Policy Controller continuerà a richiamarsi finché la risorsa non "converge", il che significa che ulteriori iterazioni non hanno alcun effetto.
Sintassi della località
La sintassi della posizione utilizza l'accesso con il punto (.
) per attraversare i campi. Nel caso di elenchi con chiavi, gli utenti possono fare riferimento a singoli oggetti in un elenco utilizzando la sintassi [<key>: <value>]
o a tutti gli oggetti nell'elenco utilizzando [<key>: *]
.
I valori e i campi possono essere racchiusi tra virgolette singole ('
) o doppie ("
). Questo è
necessario quando contengono caratteri speciali, come punti o spazi.
Nei valori tra virgolette, i caratteri speciali possono essere sottoposti a escape anteponendo
\
. "Use \" to escape and \\\" to escape"
si trasforma in Use " to escape and \" to escape
.
Alcuni esempi per la risorsa v1/Pod
:
spec.priority
riferimentispec.priority
spec.containers[name: "foo"].volumeMounts[mountPath: "/my/mount"].readOnly
fa riferimento al camporeadOnly
del montaggio/my/mount
del containerfoo
.spec.containers[name: *].volumeMounts[mountPath: "/my/mount"].readOnly
fa riferimento al camporeadOnly
del montaggio/my/mount
di tutti i container.
Se fai riferimento a una località che al momento non esiste in una risorsa, questa viene creata per impostazione predefinita. Questo comportamento può essere configurato tramite il test dei percorsi.
Test del percorso
Come possiamo eseguire l'impostazione predefinita, evitando di modificare un valore già
esistente? Forse vogliamo impostare /secure-mount
come di sola lettura per tutti i contenitori,
ma non vogliamo creare un /secure-mount
se non ne esiste già uno. Possiamo
eseguire una di queste operazioni tramite il test del percorso.
Ecco un esempio che evita di modificare imagePullPolicy
se è già
impostato:
# 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"
Ecco un altro esempio che evita di creare un contenitore sidecar
vuoto
se non esiste già:
# 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"
Se necessario, è possibile specificare più test del percorso.
subPath
deve essere un prefisso di (o uguale a) location
.
Gli unici valori validi per condition
sono MustExist
e MustNotExist
.
Corrispondenza
I mutatori consentono anche la corrispondenza, utilizzando gli stessi criteri dei vincoli.
Mutatori
Al momento esistono due tipi di mutatori: Assign
e AssignMetadata
.
Assegna
Assign
può modificare qualsiasi valore al di fuori del campo metadata
di una risorsa.
Poiché tutti i GroupVersionKinds
hanno uno schema univoco, devono essere associati a un insieme
di GroupVersionKinds
particolari.
Ha lo schema seguente:
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
AssignMetadata
può aggiungere nuove etichette di metadati. Non può modificare il valore delle etichette dei metadati esistenti. In caso contrario, sarebbe possibile scrivere un sistema di mutatori che ricorsivamente si ripeterebbero all'infinito, causando il timeout delle richieste.
Poiché tutte le risorse condividono lo stesso schema metadata
, non è necessario specificare a quale risorsa si applica un AssignMetadata
.
Inoltre, poiché AssignMetadata
non può fare molto, il suo schema è un po' più
semplice.
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 practice
Avvertenze di Kubernetes
La documentazione di Kubernetes elenca alcune considerazioni importanti sull'utilizzo dei webhook di mutazione. Poiché Policy Controller funziona come webhook di ammissione Kubernetes, questo consiglio è valido anche in questo caso.
La sintassi di mutazione di Policy Controller è progettata per semplificare la conformità ai problemi operativi relativi agli webhook di mutazione, inclusa l'idempotenza.
Scrivere mutatori
Atomicità
La best practice consiste nel rendere ogni mutatore il più autosufficiente possibile. Poiché Kubernetes è coerente alla fine, un mutatore non deve fare affidamento sul riconoscimento di un secondo mutatore per svolgere correttamente il proprio lavoro. Ad esempio, quando aggiungi un sidecar, aggiungi l'intero sidecar, non costruirlo pezzo per pezzo utilizzando più mutatori.
Convalida
Se esiste una condizione che vuoi applicare, è consigliabile che il mutatore abbia un vincolo corrispondente. In questo modo, le richieste che violano le norme vengono rifiutate e le violazioni preesistenti vengono rilevate durante il controllo.
Recupero di emergenza
La mutazione viene implementata come webhook di mutazione Kubernetes. Può essere arrestato
allo stesso modo dell'webhook di convalida,
ma la risorsa pertinente è un MutatingWebhookConfiguration
chiamato
gatekeeper-mutating-webhook-configuration
.
Passaggi successivi
- Per spiegazioni ed esempi di mutazione di Gatekeeper, consulta la documentazione open source.