Modifica risorse

Questa pagina mostra come modificare le risorse utilizzando Policy Controller. Questo è utile per 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:

  1. Nella console Google Cloud, vai alla pagina Criteri di GKE Enterprise nella sezione Gestione della postura.

    Vai al criterio

  2. Nella tabella dei cluster della scheda Impostazioni, seleziona Modifica. nella colonna Modifica configurazione.
  3. Espandi il menu Modifica configurazione di Policy Controller.
  4. Seleziona la casella di controllo Abilita webhook di mutazione.
  5. 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ù separate da una virgola.

gcloud ConfigManagement

La mutazione deve essere abilitata 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 abilitare la mutazione, come illustrato nell'esempio seguente:

  # apply-spec.yaml

  applySpecVersion: 1
  spec:
    policyController:
      enabled: true
      mutationEnabled: true

Dopo aver creato il file apply-spec.yaml, esegui questo comando per applica 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'utente registrato con le impostazioni di Policy Controller che vuoi utilizzare
  • CONFIG_YAML_PATH: il percorso del file apply-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: una disposizione composta da più mutatori

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 superati in base al campo location sono elenchi di tipi di mappa, mentre il campo chiave per la mappa deve che l'utente può specificare. Gli elenchi di tipo mappa sono un costrutto Kubernetes. Ulteriori dettagli su puoi trovare queste risorse documentazione.

spec.parameters.assign.value è il valore da assegnare a location. Questo campo non è digitato e può avere qualsiasi valore, ma tieni presente che Kubernetes convalida comunque la post-mutazione della richiesta, quindi inserire valori con un lo schema dell'oggetto da modificare fa sì che la richiesta venga rifiutata.

Utilizzare i mutatori per i job

Se stai configurando un job o un CronJob, devi specificare la versione e il gruppo separatamente, come illustrato nell'esempio seguente:

applyTo:
- groups: ["batch"]
  kind: ["Job"]
  versions: ["v1"]

Quando usi un mutatore per i job, i job esistenti non vengono mutati, a meno che vengono modificati. La modifica di un job attiva una richiesta al webhook di mutazione e ne fa sì che vengano mutate.

Flusso di esecuzione

Forse il concetto più importante della mutazione di Kubernetes webhook è il criterio di reinvocazione, perché l'output di un mutatore potrebbe cambiare come si comporta un altro mutatore. 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 ogni 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 i criteri di inserimento di sidecar e di estrazione delle immagini hanno il risultato previsto.

La routine di mutazione di Policy Controller continuerà a richiamarsi fino a quando la risorsa "converge", il che significa che ulteriori iterazioni non hanno 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 preceduti dal carattere di escape \. "Use \" to escape and \\\" to escape" diventa Use " to escape and \" to escape.

Alcuni esempi per la risorsa v1/Pod:

  • spec.priority fa riferimento a spec.priority
  • spec.containers[name: "foo"].volumeMounts[mountPath: "/my/mount"].readOnly fa riferimento al campo readOnly del montaggio /my/mount dell'elemento foo containerizzato.
  • spec.containers[name: *].volumeMounts[mountPath: "/my/mount"].readOnly fa riferimento al campo readOnly del montaggio /my/mount di tutti i container.

Se fai riferimento a una località che attualmente non esiste su una risorsa, viene creata per impostazione predefinita. Questo comportamento può essere configurato tramite il percorso test.

Test del percorso

Come possiamo eseguire l'impostazione predefinita, evitando di modificare un valore già esistente? Supponiamo che vogliamo impostare /secure-mount come di sola lettura per tutti i container, ma non vogliamo creare un /secure-mount se non ne esiste già uno. Me puoi eseguire una di queste operazioni tramite il test del percorso.

Ecco un esempio che evita la modifica di imagePullPolicy, se è già imposta:

# 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 inoltre la corrispondenza, utilizzando gli stessi criteri vincoli.

Mutatori

Attualmente 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 gli elementi GroupVersionKinds hanno uno schema univoco, devono essere associati a un insieme di particolare GroupVersionKinds.

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 le etichette dei metadati esistenti. Altrimenti, sarebbe possibile scrivere un modello di mutatori che si ripeterebbero all'infinito, con conseguente timeout delle richieste.

Poiché tutte le risorse condividono lo stesso schema metadata, non è necessario specificare a quale risorsa si applica un AssignMetadata.

Inoltre, dato che AssignMetadata non può fare così tanto, 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 relative a Kubernetes

La documentazione di Kubernetes elenca alcune considerazioni importanti relative tramite webhook di mutazione. Poiché Policy Controller funziona come un cluster Kubernetes webhook di ammissione, i consigli si applicano qui.

La sintassi delle mutazioni di Policy Controller è progettata per semplificare la conformità ai problemi operativi relativi ai webhook di mutazione, inclusa l'idempotenza.

Scrittura dei mutatori

Atomicità

È buona prassi rendere ogni mutator il più autonomo possibile. Poiché Kubernetes è sempre coerente, un mutatore non dovrebbe basarsi su un secondo mutatore sia stato riconosciuto per poter svolgere il suo lavoro correttamente. Ad esempio: quando aggiungi un file collaterale, aggiungi l'intero file collaterale, non costruirlo in modo frammentario utilizzando più mutatori.

Convalida

Se vuoi applicare una condizione, è una buona idea che mutatore in modo che abbia un vincolo corrispondente. In questo modo, possiamo evitare le richieste vengono rifiutate e nel controllo vengono rilevate violazioni preesistenti.

Ripristino di emergenza

La mutazione è implementata come webhook di modifica Kubernetes. Può essere interrotto esattamente come del webhook di convalida, ma la risorsa pertinente è un MutatingWebhookConfiguration chiamato gatekeeper-mutating-webhook-configuration.

Passaggi successivi