Scrivi un modello di vincolo personalizzato

Questa pagina mostra come scrivere un modello di vincolo personalizzato e utilizzarlo per estendere Policy Controller se non riesci a trovare un modello di vincolo precompilato in base alle tue esigenze.

I criteri di Policy Controller sono descritti utilizzando Framework di vincoli OPA e sono scritte in Rego. Un criterio può valutare qualsiasi campo di un oggetto Kubernetes.

La scrittura dei criteri con Rego è una competenza specializzata. Per questo motivo, libreria di modelli di vincoli comuni è sono già installati per impostazione predefinita. Probabilmente puoi richiamare questi modelli di vincolo quando creando vincoli. Se hai esigenze specializzate, puoi creare modelli di vincolo personalizzati.

I modelli di vincolo consentono di separare la logica di un criterio dalla sua requisiti specifici, per il riutilizzo e la delega. Puoi creare vincoli utilizzando modelli di vincoli sviluppati da terze parti, come open source progetti, fornitori di software ed esperti di regolamentazione.

Prima di iniziare

Esempio di modello di vincolo

Di seguito è riportato un esempio di modello di vincolo che nega tutte le risorse il cui nome corrisponde a un valore fornito dall'autore del vincolo. Il resto della pagina illustra i contenuti del modello, evidenziando concetti importanti per in alcun modo.

Se utilizzi Config Sync con un repository gerarchico, ti consigliamo di creare i vincoli nella directory cluster/.

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8sdenyname
spec:
  crd:
    spec:
      names:
        kind: K8sDenyName
      validation:
        # Schema for the `parameters` field
        openAPIV3Schema:
          properties:
            invalidName:
              type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8sdenynames
        violation[{"msg": msg}] {
          input.review.object.metadata.name == input.parameters.invalidName
          msg := sprintf("The name %v is not allowed", [input.parameters.invalidName])
        }

Vincolo di esempio

Di seguito è riportato un esempio di vincolo che potresti implementare per negare tutte risorse denominate policy-violation:

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sDenyName
metadata:
  name: no-policy-violation
spec:
  parameters:
    invalidName: "policy-violation"

Parti di un modello di vincolo

I modelli di vincolo sono costituiti da due parti importanti:

  • Lo schema del vincolo che vuoi che venga creato dagli utenti. Lo schema di un il modello di vincolo è archiviato nel campo crd.

  • Il codice sorgente di reCAPTCHA che viene eseguito quando viene valutato il vincolo. La Il codice sorgente di reCAPTCHA per un modello è archiviato nel campo targets.

Schema (campo crd)

Il campo CRD è un progetto per la creazione Definizione di risorsa personalizzata Kubernetes che definisce la risorsa del vincolo per il server API Kubernetes. Devi eseguire compilare i campi seguenti.

Campo Descrizione
spec.crd.spec.names.kind Il tipo di vincolo. Se è minuscolo, il valore di questo campo deve essere uguale a metadata.name.
spec.crd.spec.validation.openAPIV3Schema

Lo schema per il campo spec.parameters dell'oggetto risorsa vincolo (Policy Controller definisce automaticamente resto dello schema del vincolo). Segue le stesse convenzioni come in una normale risorsa CRD.

L'aggiunta del nome K8s al modello di vincolo è una convenzione che consente di evitare collisioni con altri tipi di modelli di vincoli, come Modelli Forseti che hanno come target risorse Google Cloud.

Ripeti codice sorgente (campo targets)

Le sezioni seguenti forniscono ulteriori informazioni sull'origine di Rego le API nel tuo codice.

Località

Il codice sorgente di Rego viene archiviato nel campo spec.targets, dove targets è un array di oggetti nel seguente formato:

{"target": "admission.k8s.gatekeeper.sh","rego": REGO_SOURCE_CODE, "libs": LIST_OF_REGO_LIBRARIES}
  • target: indica a Policy Controller quale sistema stiamo esaminando (in questo case Kubernetes); è consentita una sola voce in targets.
  • rego: il codice sorgente per il vincolo.
  • libs: un elenco facoltativo di librerie di codice Rego che viene creato disponibili per il modello di vincolo; ha lo scopo di semplificare l'utilizzo librerie condivise e non rientra nell'ambito di questo documento.

Codice sorgente

Di seguito è riportato il codice sorgente di Rego per il vincolo precedente:

package k8sdenynames

violation[{"msg": msg}] {
   input.review.object.metadata.name == input.parameters.invalidName
   msg := sprintf("The name %v is not allowed", [input.parameters.invalidName])
}

Tieni presente quanto segue:

  • package k8sdenynames è richiesto dall'OPA (runtime di Rego). Il valore è ignorato.
  • La regola di recupero che Policy Controller richiama per verificare se sono presenti violazioni sono chiamate violation. Se questa regola presenta delle corrispondenze, viene violata in cui si è verificato il vincolo.
  • La regola violation ha la firma violation[{"msg": "violation message for the user"}], dove il valore "msg" è il messaggio di violazione che viene restituito all'utente.
  • I parametri forniti al vincolo vengono resi disponibili nella parola chiave input.parameters.
  • request-under-test viene memorizzato nella parola chiave input.review.

La parola chiave input.review ha i seguenti campi.

Campo Descrizione
uid L'ID univoco di questa richiesta specifica; non è disponibile durante per la revisione contabile.
kind

Le informazioni su Kind per object-under-test. Ha nel seguente formato:

  • kind: il tipo di risorsa
  • group: gruppo di risorse
  • version: la versione della risorsa
name Nome della risorsa. Potrebbe essere vuoto se l'utente si basa su API server per generare il nome su una richiesta CREATE.
namespace Lo spazio dei nomi della risorsa (non fornito per le risorse con ambito cluster).
operation L'operazione richiesta (ad esempio CREATE o UPDATE); non è disponibili durante il controllo.
userInfo

le informazioni dell'utente che ha inviato la richiesta; non sono disponibili durante il controllo. Ha il seguente formato:

  • username: l'utente che ha effettuato la richiesta
  • uid: l'UID dell'utente
  • groups: un elenco di gruppi di cui l'utente è membro
  • extra: eventuali informazioni utente aggiuntive fornite da Kubernetes
object L'oggetto che l'utente sta tentando di modificare o creare.
oldObject Lo stato originale dell'oggetto; è disponibile solo su UPDATE operations.
dryRun Se questa richiesta è stata richiamata con kubectl --dry-run; non sono disponibili durante il controllo.

Scrivi modelli di vincoli referenziali

I modelli di vincoli referenziali sono modelli che consentono all'utente di applicare vincoli di un oggetto rispetto ad altri. Un esempio potrebbe essere "Non consentire la creazione di un pod prima che esista un Ingress corrispondente". Un altro un esempio potrebbe essere "non consentire a due servizi di avere lo stesso nome host".

Policy Controller consente di scrivere vincoli referenziali esaminando il Server API per un insieme di risorse fornite dall'utente. Quando una risorsa viene modificata, Policy Controller lo memorizza localmente in modo che possa essere facilmente referenziato da Rego codice sorgente. Policy Controller rende disponibile questa cache nel data.inventory parola chiave.

Le risorse con ambito cluster vengono memorizzate nella cache nella seguente posizione:

data.inventory.cluster["GROUP_VERSION"]["KIND"]["NAME"]

Ad esempio, un nodo denominato my-favorite-node potrebbe essere trovato in

data.inventory.cluster["v1"]["Node"]["my-favorite-node"]

Le risorse con ambito di spazio dei nomi vengono memorizzate nella cache qui:

data.inventory.namespace["NAMESPACE"]["GROUP_VERSION"]["KIND"]["NAME"]

Ad esempio, un ConfigMap denominato production-variables nello spazio dei nomi Puoi trovare shipping-prod in

data.inventory.namespace["shipping-prod"]["v1"]["ConfigMap"]["production-variables"]

Tutti i contenuti dell'oggetto sono archiviati in questa posizione della cache e possono essere a cui si fa riferimento nel codice sorgente di Rego, come meglio ritieni.

Ulteriori informazioni su Rego

Le informazioni riportate sopra forniscono le funzionalità univoche di Policy Controller che semplifica la scrittura di vincoli sulle risorse Kubernetes in Rego. Un il tutorial su come scrivere in Rego non rientra nell'ambito di questa guida. Tuttavia, Apri la documentazione di Policy Agent contiene informazioni sulla sintassi e sulle caratteristiche del linguaggio Rego stesso.

Installa il modello di vincolo

Dopo aver creato il modello di vincolo, usa kubectl apply per applicarlo, e Policy Controller si occupa di importarli. Assicurati di controllare la status campo del modello di vincolo per assicurarti che non ci siano errori di creare un'istanza. Una volta completata l'importazione, il campo status dovrebbe mostrare created: true e observedGeneration indicati nel campo status devono uguale al campo metadata.generation.

Dopo aver importato il modello, puoi applicare vincoli come descritto in Creazione di vincoli.

Rimuovi un modello di vincolo

Per rimuovere un modello di vincolo, completa i seguenti passaggi:

  1. Verifica che nessun vincolo da conservare utilizzi il vincolo modello:

    kubectl get TEMPLATE_NAME
    

    Se esiste un conflitto di denominazione tra il nome del modello di vincolo e un un oggetto diverso nel cluster, usa invece il comando seguente:

    kubectl get TEMPLATE_NAME.constraints.gatekeeper.sh
    
  2. Rimuovi il modello di vincolo:

    kubectl delete constrainttemplate CONSTRAINT_TEMPLATE_NAME
    

Se rimuovi un modello di vincolo, non puoi più creare vincoli che vi fanno riferimento.

Passaggi successivi