Modifica risorse

Questa pagina mostra come modificare le risorse utilizzando Policy Controller. È utile per operazioni come l'impostazione dei valori predefiniti. Ad esempio, potresti voler inserire un'etichetta per tutte le risorse in uno spazio dei nomi specifico o impostare come valore predefinito imagePullPolicy per un pod su Always, se non è già impostato.

Abilita mutazione

Console

Per attivare la mutazione, completa i seguenti passaggi:

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

    Vai alle norme

  2. Nella scheda Impostazioni, nella tabella del cluster, 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.

Policy Controller 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 modifica. Puoi specificare più abbonamenti separati da una virgola.

ConfigManagement gcloud

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 mostrato 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 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 del cluster 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 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 di metadati standard di Kubernetes (apiVersion, kind, metadata.name), ma in spec è configurato il comportamento del mutatore.

spec.applyTo associa il mutatore alle risorse specificate. Poiché modifichiamo campi specifici in un oggetto, definiamo in modo implicito lo schema di quell'oggetto. Ad esempio, l'attuale mutatore non avrebbe senso se fosse applicato a una risorsa Namespace. Per questo motivo, questo campo è obbligatorio affinché Policy Controller sappia a quali schemi è pertinente questo mutatore. GroupVersionKinds mancanti in questo elenco non hanno subito modifiche.

spec.location ci indica il campo da modificare. In questo caso, stiamo usando un glob (*) per indicare che vogliamo modificare tutte le voci nell'elenco di container. Tieni presente che gli unici tipi di elenchi che possono essere attraversati dal campo location sono elenchi di tipi di mappa, perciò è necessario specificare il campo chiave per la mappa. Gli elenchi di tipi di mappa sono un costrutto di Kubernetes. Per ulteriori dettagli, consulta la documentazione di Kubernetes.

spec.parameters.assign.value è il valore da assegnare a location. Questo campo non è digitato e può contenere qualsiasi valore. Tuttavia, tieni presente che Kubernetes continua a convalidare la richiesta dopo la modifica, quindi se inserisci valori con uno schema errato per l'oggetto in fase di modifica, la richiesta viene rifiutata.

Utilizzare i mutatori per le offerte di lavoro

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

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

Quando utilizzi un mutatore per i job, i job esistenti non subiscono modifiche, a meno che non vengano modificati. La modifica di un job attiva una richiesta al webhook di mutazione e ne causa la mutazione.

Flusso di esecuzione

Forse il concetto più importante da comprendere sui webhook di mutazione di Kubernetes è il criterio di richiamo, perché l'output di un mutatore potrebbe cambiare il comportamento di un altro mutatore. Ad esempio, se aggiungi un nuovo container collaterale, un mutatore che imposta il criterio di pull dell'immagine per tutti i container ora avrà un nuovo container da modificare.

In pratica, questo significa che il webhook di mutazione di Policy Controller di una determinata richiesta potrebbe essere chiamato più di una volta.

Per ridurre la latenza, Policy Controller esegue nuovamente la chiamata per evitare richieste HTTP aggiuntive. Ciò significa che i criteri di inserimento collaterale e pull dell'immagine hanno il risultato previsto.

La routine di mutazione di Policy Controller continuerà a richiamarsi finché la risorsa non "converge", il che significa che le iterazioni aggiuntive non avranno alcun ulteriore effetto.

Sintassi delle località

La sintassi relativa alla posizione utilizza la funzione di accesso del punto (.) per attraversare i campi. Nel caso di elenchi con chiavi, gli utenti possono fare riferimento a singoli oggetti di 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 ("). Questa operazione è necessaria quando contengono caratteri speciali, come punti o spazi.

Nei valori tra virgolette, è possibile eseguire l'escape dei caratteri speciali facendoli precedere da \. "Use \" to escape and \\\" to escape" diventa Use " to escape and \" to escape.

Alcuni esempi per la risorsa v1/Pod:

  • spec.priority riferimento a spec.priority
  • spec.containers[name: "foo"].volumeMounts[mountPath: "/my/mount"].readOnly fa riferimento al campo readOnly del montaggio /my/mount del container foo.
  • 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 non esiste attualmente su una risorsa, questa viene creata per impostazione predefinita. Questo comportamento può essere configurato tramite il test del percorso.

Test del percorso

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

Ecco un esempio che evita la modifica 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 del percorso.

subPath deve essere un prefisso di (o uguale a) location.

Gli unici valori validi per condition sono MustExist e MustNotExist.

Corrispondenza in corso...

I mutatori consentono anche la corrispondenza, utilizzando gli stessi criteri dei 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 GroupVersionKinds specifico.

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. Altrimenti sarebbe possibile scrivere un sistema di mutatori con una ripetizione indefinita, 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 Kubernetes

La documentazione di Kubernetes elenca alcune importanti considerazioni sull'uso dei webhook di mutazione. Poiché Policy Controller funziona come un webhook di ammissione Kubernetes, è il caso di farlo.

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

Scrivere mutatori

Atomicità

È buona norma rendere ogni mutatore il più autosufficiente possibile. Poiché Kubernetes è alla fine coerente, un mutatore non deve fare affidamento su un secondo mutatore per essere riconosciuto per svolgere correttamente il suo lavoro. 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, è consigliabile che il mutatore abbia un vincolo corrispondente. Ciò aiuta a garantire che le richieste in violazione vengano rifiutate e che le violazioni preesistenti vengano rilevate nell'audit.

Recupero di emergenza

La mutazione è implementata come un webhook mutabile di Kubernetes. Può essere arrestato nello stesso modo del webhook di convalida, ma la risorsa pertinente è un MutatingWebhookConfiguration chiamato gatekeeper-mutating-webhook-configuration.

Passaggi successivi