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 adatto alle tue esigenze.
I criteri di Policy Controller sono descritti utilizzando il framework del vincolo OPA e sono scritti in Rego. Un criterio può valutare qualsiasi campo di un oggetto Kubernetes.
La scrittura di norme con Rego è una competenza specializzata. Per questo motivo, per impostazione predefinita viene installata una libreria di modelli di vincolo comuni. Probabilmente puoi richiamare questi modelli di vincolo durante la creazione dei vincoli. Se hai esigenze speciali, puoi creare modelli di vincolo personalizzati.
I modelli di vincolo consentono di separare la logica di un criterio dai relativi requisiti specifici per il riutilizzo e la delega. Puoi creare vincoli utilizzando modelli di vincolo sviluppati da terze parti, ad esempio progetti open source, fornitori di software o esperti di regolamentazione.
Prima di iniziare
- Installa Policy Controller.
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. Nel resto di questa pagina vengono esaminati i contenuti del modello, evidenziando concetti importanti.
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 vincolo di esempio che potresti implementare per negare tutte le 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 gli utenti creino. Lo schema di un modello di vincolo è archiviato nel campo
crd
.Il codice sorgente di Rego eseguito al momento della valutazione del vincolo. Il codice sorgente di un modello viene archiviato nel campo
targets
.
Schema (campo crd
)
Il campo CRD è un progetto per la creazione della definizione di risorsa personalizzata di Kubernetes che definisce la risorsa vincolo per il server API Kubernetes. Devi solo compilare i seguenti campi.
Campo | Descrizione |
---|---|
spec.crd.spec.names.kind |
Il tipo del vincolo. In minuscolo, il valore di questo campo deve essere uguale a metadata.name . |
spec.crd.spec.validation.openAPIV3Schema |
Schema per il campo |
L'aggiunta di un prefisso al modello di vincolo con il nome K8s
è una convenzione che consente di evitare conflitti con altri tipi di modelli di vincolo, come quelli Forseti che hanno come target le risorse Google Cloud.
Ripeti codice sorgente (campo targets
)
Le seguenti sezioni forniscono ulteriori informazioni sul codice sorgente Rego.
Località
Il codice sorgente 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 caso, Kubernetes); è consentita una sola voce intargets
.rego
: il codice sorgente del vincolo.libs
: un elenco facoltativo di librerie di codice Rego reso disponibile per il modello di vincolo; ha lo scopo di semplificare l'utilizzo delle librerie condivise e non rientra nell'ambito di questo documento.
Codice sorgente
Di seguito è riportato il codice sorgente 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 da OPA (runtime di Rego). Il valore viene ignorato.- La regola di Rego richiamata da Policy Controller per verificare se sono presenti violazioni è denominata
violation
. Se questa regola ha corrispondenze, si è verificata una violazione del vincolo. - La regola
violation
ha la firmaviolation[{"msg": "violation message for the user"}]
, dove il valore di"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 chiaveinput.review
.
La parola chiave input.review
include i campi seguenti.
Campo | Descrizione |
---|---|
uid |
L'ID univoco per questa richiesta specifica. Non è disponibile durante il controllo. |
kind |
Le informazioni relative al tipo per
|
name |
Nome della risorsa. Potrebbe essere vuoto se l'utente si affida al server API per generare il nome su una richiesta CREATE. |
namespace |
Lo spazio dei nomi delle risorse (non fornito per le risorse con ambito cluster). |
operation |
L'operazione richiesta (ad esempio, CREATE o UPDATE); non è disponibile durante il controllo. |
userInfo |
Le informazioni dell'utente richiedente; non sono disponibili durante il controllo. Il formato è il seguente:
|
object |
L'oggetto che l'utente sta tentando di modificare o creare. |
oldObject |
Lo stato originale dell'oggetto; è disponibile solo per le operazioni UPDATE. |
dryRun |
Indica se questa richiesta è stata richiamata con kubectl --dry-run ;
non è disponibile durante il controllo. |
Scrivi modelli di vincoli referenziali
I modelli di vincoli referenziali sono quelli che consentono all'utente di vincolare un oggetto rispetto ad altri oggetti. Un esempio potrebbe essere "non consentire la creazione di un pod prima che sia nota l'esistenza di una risorsa Ingress corrispondente". Un altro esempio potrebbe essere "non consentire a due servizi di avere lo stesso nome host".
Policy Controller consente di scrivere vincoli di riferimento osservando il server API per un insieme di risorse fornite dall'utente. Quando una risorsa viene modificata, Policy Controller la memorizza nella cache localmente in modo che sia facilmente accessibile dal codice sorgente di Rego. Policy Controller rende disponibile questa cache sotto la parola chiave data.inventory
.
Le risorse con ambito a livello di cluster vengono memorizzate nella cache nella seguente località:
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 sono memorizzate nella cache qui:
data.inventory.namespace["NAMESPACE"]["GROUP_VERSION"]["KIND"]["NAME"]
Ad esempio, un ConfigMap denominato production-variables
nello spazio dei nomi
shipping-prod
si potrebbe trovare in
data.inventory.namespace["shipping-prod"]["v1"]["ConfigMap"]["production-variables"]
L'intero contenuto dell'oggetto viene archiviato in questa posizione della cache e può essere utilizzato come riferimento nel codice sorgente Rego.
Ulteriori informazioni su Rego
Le informazioni precedenti forniscono le funzionalità uniche di Policy Controller che semplificano la scrittura di vincoli sulle risorse Kubernetes in Rego. Un tutorial completo su come scrivere in Rego non rientra nell'ambito di questa guida. Tuttavia, la documentazione aperta di Policy Agent contiene informazioni sulla sintassi e sulle funzionalità del linguaggio Rego stesso.
Installa il modello di vincolo
Dopo aver creato il modello di vincolo, utilizza kubectl apply
per applicarlo e Policy Controller si occupa di importarlo. Assicurati di controllare il campo status
del modello di vincolo per assicurarti che non siano presenti errori che lo confermano. Una volta eseguita l'importazione, il campo status
dovrebbe mostrare created: true
e il valore observedGeneration
indicato nel campo status
deve essere uguale al campo metadata.generation
.
Dopo aver importato il modello, puoi applicare vincoli come descritto in Creare vincoli.
Rimuovi un modello di vincolo
Per rimuovere un modello di vincolo:
Verifica che nessun vincolo che vuoi conservare utilizzi il modello di vincolo:
kubectl get TEMPLATE_NAME
Se esiste un conflitto di denominazione tra il nome del modello di vincolo e un oggetto diverso nel cluster, utilizza il comando seguente:
kubectl get TEMPLATE_NAME.constraints.gatekeeper.sh
Rimuovi il modello di vincolo:
kubectl delete constrainttemplate CONSTRAINT_TEMPLATE_NAME
Quando rimuovi un modello di vincolo, non puoi più creare vincoli che vi fanno riferimento.
Passaggi successivi
- Scopri di più su Policy Controller.
- Visualizza la documentazione di riferimento della libreria dei modelli di vincolo.
- Scopri come utilizzare i vincoli invece di PodSecurityPolicies.