Questa pagina mostra come modificare le risorse utilizzando
Policy Controller. Questo è utile per eseguire operazioni come l'impostazione di valori predefiniti. Ad esempio, potresti voler iniettare
un'etichetta per tutte le risorse in uno spazio dei nomi specifico o impostare per impostazione predefinita il valore imagePullPolicy
di un pod su Always
se non è già impostato.
Attivare la mutazione
Console
Per attivare la mutazione, completa i seguenti passaggi:
- Nella console Google Cloud , vai alla pagina Criteri di GKE Enterprise nella sezione Gestione della postura.
- Nella scheda Impostazioni, nella tabella del cluster, seleziona Modifica edit nella colonna Modifica configurazione.
- Espandi il menu Modifica la configurazione di Policy Controller.
- Seleziona la casella di controllo Attiva webhook di modifica.
- Seleziona Salva modifiche.
gcloud Policy Controller
Per abilitare la mutazione, esegui il seguente comando:
gcloud container fleet policycontroller update \
--memberships=MEMBERSHIP_NAME \
--mutation
Sostituisci MEMBERSHIP_NAME
con il nome dell'appartenenza
del cluster registrato per attivare la mutazione. Puoi specificare più iscrizioni separate da una virgola.
gcloud ConfigManagement
La mutazione deve essere attivata impostando spec.policyController.mutation.enabled
su
true
nella risorsa config-management
:
apiVersion: configmanagement.gke.io/v1
kind: ConfigManagement
metadata:
name: config-management
spec:
policyController:
enabled: true
mutation:
enabled: true
Se utilizzi il comando gcloud CLI, devi utilizzare la versione alpha per attivare la mutazione, come mostrato nell'esempio seguente:
# apply-spec.yaml
applySpecVersion: 1
spec:
policyController:
enabled: true
mutationEnabled: true
Dopo aver creato il file apply-spec.yaml
, esegui il seguente comando per
applicare la configurazione:
gcloud alpha container fleet config-management apply \
--membership=MEMBERSHIP_NAME \
--config=CONFIG_YAML_PATH \
--project=PROJECT_ID
Sostituisci quanto segue:
MEMBERSHIP_NAME
: il nome dell'appartenenza al cluster registrato con le impostazioni del controller dei criteri che vuoi utilizzareCONFIG_YAML_PATH
: il percorso del fileapply-spec.yaml
PROJECT_ID
: il tuo ID progetto
Definizioni
- mutator: una risorsa Kubernetes che consente di configurare il comportamento della mutazione di Policy Controller.
- system: un'organizzazione di più mutator
Esempio di mutazione
L'esempio seguente mostra un mutatore che imposta imagePullPolicy
su Always
per tutti i container di tutti i pod:
# 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 in spec
è configurato il comportamento del modificatore.
spec.applyTo
lega 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 applicato
a una risorsa Namespace
. Per questo motivo, questo campo è obbligatorio affinché
Policy Controller sappia per quali schemi è pertinente questo mutatore.
GroupVersionKinds
mancanti in questo elenco non vengono sottoposti a mutazione.
spec.location
ci indica quale campo modificare. In questo caso, utilizziamo un glob (*
) per indicare che vogliamo modificare tutte le voci nell'elenco del contenitore. Tieni presente che gli unici tipi di elenchi che possono essere attraversati
dal campo location
sono gli elenchi di tipo mappa e che il campo chiave per la mappa deve essere
specificato. Gli elenchi di tipo mappa sono un costrutto Kubernetes. Puoi trovare maggiori dettagli nella documentazione di Kubernetes.
spec.parameters.assign.value
è il valore da assegnare a location
.
Questo campo non è tipizzato e può assumere qualsiasi valore, ma tieni presente che Kubernetes convalida comunque la richiesta dopo la mutazione, pertanto l'inserimento di valori con uno schema errato per l'oggetto modificato comporta il rifiuto della richiesta.
Utilizzare i mutatori per i job
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 i job, 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 modifica.
Flusso di esecuzione
Forse il concetto più importante da comprendere sui webhook di mutazione Kubernetes è il loro regolamento di richiamo, perché l'output di un mutator potrebbe cambiare il comportamento di un altro mutator. Ad esempio, se aggiungi un nuovo container sidecar, un mutatore che imposta il criterio di estrazione delle immagini per tutti i container ora ha un nuovo container da modificare.
In pratica, ciò significa che per qualsiasi richiesta, il webhook di mutazione di Policy Controller potrebbe essere chiamato più volte.
Per ridurre la latenza, Policy Controller si richiama di nuovo per evitare richieste HTTP aggiuntive. Ciò significa che il criterio di inserimento di sidecar e di estrazione delle immagini ha il risultato previsto.
La routine di mutazione di Policy Controller continuerà a riavviarsi fino a quando la risorsa non "converge", il che significa che le iterazioni aggiuntive non hanno alcun ulteriore effetto.
Sintassi della località
La sintassi della posizione utilizza l'accessore punto (.
) per attraversare i campi. Nel caso degli elenchi con chiave, 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 inseriti con un carattere di escape anteponendoli a \
. "Use \" to escape and \\\" to escape"
diventa 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 contenitorefoo
.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 non esiste attualmente in una risorsa, questa viene creata per impostazione predefinita. Questo comportamento può essere configurato tramite il testing dei percorsi.
Test del percorso
Come possiamo eseguire l'impostazione predefinita, evitando di modificare un valore già esistente? Ad esempio, potremmo voler impostare /secure-mount
su di sola lettura per tutti i contenitori, ma non vogliamo creare un /secure-mount
se non esiste già. Possiamo eseguire entrambe queste operazioni tramite i test di percorso.
Ecco un esempio che evita la mutazione di 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 di 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 mutator: 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
specifici.
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 dei metadati. Non può modificare il valore delle etichette dei metadati esistenti. In caso contrario, sarebbe possibile scrivere un sistema di mutatori che si rechi in modo ricorsivo a un numero infinito di volte, 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
Limitazioni di Kubernetes
La documentazione di Kubernetes elenca alcune considerazioni importanti sull'utilizzo degli webhook di mutazione. Poiché Policy Controller funziona come webhook di ammissione Kubernetes, questo consiglio si applica qui.
La sintassi delle mutazioni di Policy Controller è progettata per semplificare la conformità ai problemi operativi relativi ai webhook di mutazione, inclusa l'idempotenza.
Scrivi i mutatori
Atomicità
È buona prassi rendere ogni mutator il più autonomo possibile. Poiché Kubernetes è eventualmente coerente, un mutator non deve fare affidamento sul riconoscimento di un secondo mutator per svolgere correttamente il proprio compito. Ad esempio, quando aggiungi un sidecar, aggiungi l'intero sidecar, non costruiscilo a pezzi utilizzando più mutator.
Convalida
Se vuoi applicare una condizione, è buona norma che il mutatore abbia una limitazione di corrispondenza. In questo modo, le richieste in violazione vengono rifiutate e le violazioni preesistenti vengono rilevate durante il controllo.
Ripristino di emergenza
La mutazione è implementata come webhook di modifica Kubernetes. Può essere interrotto nello stesso modo del webhook di convalida, ma la risorsa pertinente è un MutatingWebhookConfiguration
chiamato gatekeeper-mutating-webhook-configuration
.
Passaggi successivi
- Per spiegazioni ed esempi di mutazioni Gatekeeper, consulta la documentazione open source