Utilizzare la libreria di modelli di vincolo

Questa pagina mostra come definire i vincoli Policy Controller utilizzando i modelli di vincolo preesistenti di Google.

Policy Controller consente di applicare i criteri per un cluster Kubernetes mediante la definizione di uno o più oggetti vincolo. Dopo aver installato un vincolo, le richieste al server API vengono confrontate con il vincolo e vengono rifiutate se non sono conformi. Le risorse non conformi preesistenti vengono riportate al tempo di controllo.

Ogni vincolo è supportato da un modello di vincolo che definisce lo schema e la logica del vincolo. I modelli di vincolo possono essere forniti da Google e da terze parti; in alternativa, puoi scrivere autonomamente. Per ulteriori informazioni sulla creazione di nuovi modelli, consulta la sezione Scrivere un modello di vincolo.

Prima di iniziare

Esaminare la libreria di modelli di vincolo

Quando definisci un vincolo, devi specificare il modello di vincolo che estende. Per impostazione predefinita, viene installata una libreria di modelli di vincolo comuni sviluppati da Google e molte organizzazioni non hanno bisogno di creare modelli di vincoli personalizzati direttamente in Rego. I modelli di vincolo forniti da Google hanno l'etichetta configmanagement.gke.io/configmanagement.

Per elencare i vincoli, utilizza il comando seguente:

kubectl get constrainttemplates \
    -l="configmanagement.gke.io/configmanagement=config-management"

Per descrivere un modello di vincolo e controllare i relativi parametri richiesti, utilizza il seguente comando:

kubectl describe constrainttemplate CONSTRAINT_TEMPLATE_NAME

Puoi anche visualizzare tutti i modelli di vincolo nella libreria.

Definisci un vincolo

Per definire un vincolo devi utilizzare YAML e non sarà necessario comprendere o scrivere Rego. Al contrario, un vincolo richiama un modello di vincolo e fornisce parametri specifici al vincolo.

Se utilizzi un repository strutturato, ti consigliamo di creare i vincoli nella directory cluster/.

I vincoli hanno i seguenti campi:

  • La kind minuscola contiene il nome di un modello di vincolo.
  • metadata.name è il nome del vincolo.
  • Il campo match definisce gli oggetti a cui si applica il vincolo. Tutte le condizioni specificate devono essere soddisfatte prima che un oggetto rientri nell'ambito di un vincolo. Le condizioni match sono definite dai seguenti sottocampi:
    • kinds sono i tipi di risorse a cui si applica il vincolo, determinato da due campi: apiGroups è un elenco di gruppi di API Kubernetes che corrisponderà e kinds è un elenco di tipi che corrisponderanno. "*" corrisponde a tutto. Se almeno una voce apiGroup e una voce kind corrispondono, la condizione kinds è soddisfatta.
    • scope accetta *, Cluster o Namepaced, che determina se sono selezionate le risorse con ambito cluster e/o con spazio dei nomi (il valore predefinito è *).
    • namespaces è un elenco di nomi degli spazi dei nomi a cui può appartenere l'oggetto. L'oggetto deve appartenere ad almeno uno di questi spazi dei nomi. le risorse dello spazio dei nomi vengono trattate come se fossero di loro proprietà.
    • excludedNamespaces è un elenco di spazi dei nomi a cui l'oggetto non può appartenere.
    • labelSelector è un selettore di etichette Kubernetes che l'oggetto deve soddisfare.
    • namespaceSelector è un selettore di etichette nello spazio dei nomi a cui appartiene l'oggetto. Se lo spazio dei nomi non soddisfa l'oggetto, non corrisponderà. Le risorse dello spazio dei nomi vengono trattate come se fossero di loro proprietà.
  • Il campo parameters definisce gli argomenti per il vincolo, in base a quanto previsto dal modello di vincolo.

Il seguente vincolo, chiamato ns-must-have-geo, richiama un modello di vincolo denominato K8sRequiredLabels, che è incluso nella libreria dei modelli di vincolo fornita da Google. Il vincolo definisce i parametri che il modello di vincolo utilizza per valutare se gli spazi dei nomi hanno l'etichetta geo impostata su un valore specifico.

# ns-must-have-geo.yaml

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: ns-must-have-geo
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Namespace"]
  parameters:
    labels:
      - key: "geo"

Per creare il vincolo, utilizza kubectl apply -f:

kubectl apply -f ns-must-have-geo.yaml

Controlla un vincolo

Se il vincolo è configurato e installato correttamente, il suo campo status.byPod[].enforced è impostato su true, a prescindere che sia configurato o per applicare il vincolo o solo per verificarlo.

Per impostazione predefinita, i vincoli vengono applicati e una violazione di un vincolo impedisce una determinata operazione sul cluster. Puoi impostare un vincolo spec.enforcementAction per dryrun per segnalare le violazioni nel campo status.violations senza impedire l'operazione.

Per ulteriori informazioni, consulta l'articolo Controllare i vincoli.

Avvertenze durante la sincronizzazione dei vincoli

Durante la sincronizzazione dei vincoli, tieni presente quanto segue.

Coerenza finale

Puoi eseguire il commit dei vincoli nel repository Git e puoi limitarne gli effetti utilizzando ClusterSelector o NamespaceSelectors. Poiché la sincronizzazione è effettivamente coerente, tieni presente quanto segue:

  • Se un'operazione di cluster attiva un vincolo il cui spazio dei nomi NameSelecter fa riferimento a uno spazio dei nomi che non è stato sincronizzato, il vincolo viene applicato e l'operazione viene impedita. In altre parole, uno spazio dei nomi mancante "fails chiuso."
  • Se modifichi le etichette di uno spazio dei nomi, la cache potrebbe contenere dati obsoleti per un breve periodo di tempo.

Riduci al minimo la necessità di rinominare uno spazio dei nomi o di modificare le etichette e testa i vincoli che incidono su uno spazio dei nomi rinominato o rietichettato per assicurarti che funzionino come previsto.

Configurare Policy Controller per i vincoli di riferimento

Prima di poter abilitare i vincoli di riferimento, devi creare una configurazione che indichi a Policy Controller i tipi di oggetti da controllare, ad esempio gli spazi dei nomi.

Salva il seguente manifest YAML in un file e applicalo con kubectl. Il file manifest configura il controller dei criteri in modo da monitorare gli spazi dei nomi e le risorse Ingress. Crea una voce con group, version e kind in spec.sync.syncOnly, con i valori per ogni tipo di oggetto che vuoi guardare.

apiVersion: config.gatekeeper.sh/v1alpha1
kind: Config
metadata:
  name: config
  namespace: "gatekeeper-system"
spec:
  sync:
    syncOnly:
      - group: ""
        version: "v1"
        kind: "Namespace"
      - group: "extensions"
        version: "v1beta1"
        kind: "Ingress"

Abilita vincoli di riferimento

Un vincolo di riferimento fa riferimento a un altro oggetto nella relativa definizione. Ad esempio, puoi creare un vincolo che richiede che gli oggetti Ingress in un cluster abbiano nomi host univoci. Il vincolo è referenziale se il relativo modello di vincolo contiene la stringa data.inventory nel suo file Rego.

I vincoli di riferimento sono disabilitati per impostazione predefinita in Policy Controller. Garantiamo che i vincoli referenziali siano coerenti solo in modo coerente, il che comporta rischi:

  • Su un server API sovraccarico, i contenuti della cache del controller dei criteri potrebbero diventare obsoleti, causando il vincolo di riferimento di "open open", il che significa che l'azione di applicazione sembra funzionare quando non è disponibile. Ad esempio, puoi creare Ingress con nomi host duplicati troppo velocemente per consentire al controller di ammissione di rilevare i duplicati.

  • L'ordine di installazione dei vincoli e l'ordine di aggiornamento della cache sono entrambi casuali.

Se conosci questi rischi e vuoi comunque abilitare il supporto per i vincoli di riferimento, puoi attivare i vincoli di riferimento in Google Cloud Console. Per scoprire di più, consulta Installare Policy Controller.

Puoi anche impostare policyController.referentialRulesEnabled su true nel file config-management.yaml:

apiVersion: configmanagement.gke.io/v1
kind: ConfigManagement
metadata:
  name: config-management
  namespace: config-management-system
spec:
  clusterName: my-cluster
  channel: dev
  policyController:
    enabled: true
    referentialRulesEnabled: true

Elenca tutti i vincoli

Per elencare tutti i vincoli installati su un cluster, utilizza il seguente comando:

kubectl get constraint

Rimuovere un vincolo

Per trovare tutti i vincoli che utilizzano un modello di vincolo, utilizza il seguente comando per elencare tutti gli oggetti con lo stesso kind del modello di vincolo: metadata.name

kubectl get CONSTRAINT_TEMPLATE_NAME

Per rimuovere un vincolo, specifica kind e name:

kubectl delete CONSTRAINT_TEMPLATE_NAME CONSTRAINT_NAME

Se vuoi eliminare il modello di vincolo utilizzato dal vincolo, prendi nota del kind del vincolo.

Quando rimuovi un vincolo, ne viene interrotta l'applicazione non appena il server API lo contrassegna come eliminato.

Rimuovi tutti i modelli di vincolo

Imposta spec.policyController.templateLibraryInstalled su false. Ciò impedisce ad Anthos Config Management di reinstallare automaticamente la libreria.

Per rimuovere tutti i modelli e tutti i vincoli, utilizza il seguente comando:

kubectl delete constrainttemplate --all

Ripristinare la libreria di modelli di vincolo

Se hai disabilitato la libreria dei modelli di vincolo o hai disinstallato tutti i modelli di vincolo, puoi ripristinarlo impostando spec.policyController.templateLibraryInstalled su true nella configurazione di Anthos Config Management.

Risolvere i problemi relativi ai vincoli di Policy Controller

Errore durante la creazione di un modello di vincolo

Se viene visualizzato un errore che menziona un elemento disallowed ref, verifica di aver abilitato i vincoli di riferimento. Ad esempio, se utilizzi data.inventory in un modello di vincolo senza prima attivare i vincoli di riferimento, l'errore è simile al seguente:

admission webhook "validation.gatekeeper.sh" denied the request: check refs failed on module {templates["admission.k8s.gatekeeper.sh"]["MyTemplate"]}: disallowed ref data.inventory...

Passaggi successivi