Benutzerdefinierte Einschränkungsvorlage schreiben

Auf dieser Seite wird gezeigt, wie Sie eine benutzerdefinierte Einschränkungsvorlage schreiben und damit Policy Controller erweitern können, wenn Sie keine vorgefertigte Einschränkungsvorlage finden können, die Ihren Anforderungen entspricht.

Richtlinien für Richtlinienverantwortliche werden mit dem OPA Constraint Framework beschrieben und in Rego geschrieben. Eine Richtlinie kann jedes Feld eines Kubernetes-Objekts auswerten.

Das Schreiben von Richtlinien mit Rego erfordert Fachkenntnis. Aus diesem Grund wird standardmäßig eine Bibliothek mit allgemeinen Einschränkungsvorlagen installiert. Sie können diese Einschränkungsvorlagen wahrscheinlich beim Erstellen von Einschränkungen aufrufen. Wenn Sie spezielle Anforderungen haben, können Sie Ihre eigenen Einschränkungsvorlagen erstellen.

Mit Beschränkungsvorlagen können Sie die Logik einer Richtlinie zur Wiederverwendung und Delegierung von ihren spezifischen Anforderungen trennen. Sie können Einschränkungen erstellen, wenn Sie von Drittanbietern entwickelte Vorlagen verwenden, z. B. Open-Source-Projekte, Softwareanbieter oder rechtliche Experten.

Hinweise

Beispiel für eine Einschränkungsvorlage

Im Folgenden finden Sie eine Beispiel-Einschränkungsvorlage, die alle Ressourcen ablehnt, deren Name mit einem vom Ersteller der Einschränkung bereitgestellten Wert übereinstimmt. Im Folgenden werden die Inhalte der Vorlage behandelt und wichtige Konzepte vorgestellt.

Wenn Sie ein strukturiertes Repository verwenden, empfehlen wir, die Einschränkungen im Verzeichnis cluster/ zu erstellen.

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])
        }

Beispieleinschränkung

Im Folgenden finden Sie eine Beispieleinschränkung, die Sie implementieren können, um alle Ressourcen mit dem Namen policy-violation abzulehnen:

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

Teile einer Einschränkungsvorlage

Einschränkungsvorlagen bestehen aus zwei wichtigen Elementen:

  • Das Schema der Einschränkung, die Nutzer erstellen sollen. Das Schema einer Einschränkungsvorlage wird im Feld crd gespeichert.

  • Der Rego-Quellcode, der ausgeführt wird, wenn die Einschränkung ausgewertet wird. Der Rego-Quellcode für eine Vorlage wird im Feld targets gespeichert.

Schema (crd-Feld)

Das CRD-Feld ist eine Blaupause zum Erstellen der Kubernetes Custom Resource Definition, die die Einschränkungsressource für den Kubernetes API-Server definiert. Sie müssen nur die folgenden Felder ausfüllen:

Feld Beschreibung
spec.crd.spec.names.kind Der Typ der Einschränkung. Im Kleinbuchstaben muss der Wert dieses Feldes gleich metadata.name sein.
spec.crd.spec.validation.openAPIV3Schema

Das Schema für das Feld spec.parameters der Einschränkungsressource (Policy Controller definiert automatisch den Rest des Einschränkungsschemas). Es folgt den gleichen Konventionen wie bei einer regulären CRD-Ressource.

Die Einschränkungsvorlage wird mit dem Namen K8s vorangestellt, um Konflikte mit anderen Arten von Einschränkungsvorlagen zu vermeiden, z. B. Forseti-Vorlagen, die auf Google Cloud-Ressourcen abzielen.

Rego-Quellcode (Feld targets)

In den folgenden Abschnitten finden Sie weitere Informationen zum Rego-Quellcode.

Ort

Der Rego-Quellcode wird im Feld spec.targets gespeichert, wobei targets ein Array von Objekten im folgenden Format ist:

{"target": "admission.k8s.gatekeeper.sh","rego": REGO_SOURCE_CODE, "libs": LIST_OF_REGO_LIBRARIES}
  • target: teilt Policy Controller mit, welches System geprüft werden soll (in diesem Fall Kubernetes). Nur ein Eintrag in targets ist zulässig.
  • rego: Der Quellcode für die Einschränkung.
  • libs: Eine optionale Liste von Bibliotheken für den Go-Code, die der Einschränkungsvorlage zur Verfügung gestellt wird Er soll die Verwendung gemeinsam genutzter Bibliotheken erleichtern und wird in diesem Dokument nicht behandelt.

Quellcode

Dies ist der Rego-Quellcode für die vorherige Einschränkung:

package k8sdenynames

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

Wichtige Hinweise:

  • package k8sdenynames wird von OPA (Regos Laufzeit) benötigt. Der Wert wird ignoriert.
  • Die Rego-Regel, die Policy Controller aufruft, um festzustellen, ob Verstöße vorliegen, heißt violation. Wenn diese Regel übereinstimmt, ist ein Verstoß gegen die Einschränkung aufgetreten.
  • Die Regel violation hat die Signatur violation[{"msg": "violation message for the user"}], wobei der Wert von "msg" die Richtlinienmeldung ist, die an den Nutzer zurückgegeben wird.
  • Die für die Einschränkung bereitgestellten Parameter werden unter dem Schlüsselwort input.parameters verfügbar gemacht.
  • Die request-under-test wird unter dem Keyword input.review gespeichert.

Das Keyword input.review hat folgende Felder.

Feld Beschreibung
uid Die eindeutige ID für diese Anfrage; Sie ist während der Prüfung nicht verfügbar.
kind

Die Artinformationen für object-under-test. Sie hat folgendes Format:

  • kind die Art der Ressource
  • group die Ressourcengruppe
  • version die Ressourcenversion
name Der Ressourcenname Es kann leer sein, wenn sich der Nutzer auf den API-Server verlässt, um den Namen für eine CREATE-Anforderung zu generieren.
namespace Der Ressourcen-Namespace (nicht für clusterbezogene Ressourcen bereitgestellt).
operation Der angeforderte Vorgang (z. B. CREATE oder UPDATE); Sie ist während der Prüfung nicht verfügbar.
userInfo

Daten des anfragenden Nutzers Sie ist während der Prüfung nicht verfügbar. Sie hat folgendes Format:

  • username: der Nutzer, der die Anfrage stellt
  • uid: die UID des Nutzers
  • groups: eine Liste der Gruppen, in denen der Nutzer Mitglied ist
  • extra: alle zusätzlichen Nutzerinformationen, die von Kubernetes bereitgestellt werden
object Das Objekt, das der Nutzer ändern oder erstellen möchte
oldObject Der ursprüngliche Zustand des Objekts ist nur für UPDATE-Vorgänge verfügbar.
dryRun Gibt an, ob diese Anfrage mit kubectl --dry-run aufgerufen wurde. Während der Prüfung ist sie nicht verfügbar.

Vorlagen für referenzielle Einschränkungen schreiben

Vorlagen für referenzielle Einschränkung sind Vorlagen, mit denen der Nutzer ein Objekt in Bezug auf andere Objekte einschränken kann. Ein Beispiel hierfür könnte sein: "Erlaube nicht, dass ein Pod erstellt wird, bevor bekannt ist, dass ein übereinstimmender Eingang vorhanden ist." Ein anderes Beispiel könnte sein: „Nicht zulassen, dass zwei Dienste denselben Hostnamen haben“.

Mit Policy Controller können Sie referenzielle Einschränkungen schreiben, indem Sie den API-Server auf einen vom Nutzer bereitgestellten Ressourcensatz überwachen. Wenn eine Ressource geändert wird, speichert Policy Controller sie lokal zwischen, damit sie vom Rego-Quellcode problemlos referenziert werden kann. Policy Controller stellt diesen Cache unter dem Schlüsselwort data.inventory zur Verfügung.

Ressourcen mit Cluster-Gültigkeitsbereich werden an folgendem Speicherort zwischengespeichert:

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

Beispiel: Ein Knoten mit dem Namen my-favorite-node befindet sich unter

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

Ressourcen mit Namespace-Bereich werden hier zwischengespeichert:

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

Beispielsweise könnte eine ConfigMap mit dem Namen production-variables im Namespace shipping-prod unter gefunden werden

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

Der vollständige Inhalt des Objekts wird an diesem Cache-Speicherort gespeichert und kann in Ihrem Rego nach Belieben referenziert werden.

Weitere Informationen zu Rego

Die obigen Informationen stellen die einzigartigen Funktionen von Policy Controller bereit, was das Schreiben von Einschränkungen für Kubernetes-Ressourcen in Rego erleichtert. Eine vollständige Anleitung zum Schreiben in Rego wird in dieser Anleitung nicht behandelt. Die Dokumentation zum Open Policy Agent enthält jedoch Informationen zur Syntax und zu den Funktionen der Rego-Sprache.

Einschränkungsvorlage installieren

Nachdem Sie die Einschränkungsvorlage erstellt haben, verwenden Sie kubectl apply, um sie anzuwenden, und der Policy Controller übernimmt die Aufnahme. Prüfen Sie das Feld status Ihrer Einschränkungsvorlage, um sicherzustellen, dass es keine Fehler bei der Instanziierung gab. Bei erfolgreicher Aufnahme sollte das Feld status created: true anzeigen und das im Feld status angegebene observedGeneration sollte dem Feld metadata.generation entsprechen.

Nachdem die Vorlage aufgenommen wurde, können Sie Einschränkungen anwenden, wie unter Einschränkungen erstellen beschrieben.

Einschränkungsvorlage entfernen

So entfernen Sie eine Einschränkungsvorlage:

  1. Vergewissern Sie sich, dass keine Einschränkungen, die Sie beibehalten möchten, die Einschränkungsvorlage verwenden:

    kubectl get TEMPLATE_NAME
    

    Wenn zwischen dem Namen der Einschränkungsvorlage und einem anderen Objekt im Cluster ein Namenskonflikt besteht, verwenden Sie stattdessen den folgenden Befehl:

    kubectl get TEMPLATE_NAME.constraints.gatekeeper.sh
    
  2. Entfernen Sie die Einschränkungsvorlage:

    kubectl delete constrainttemplate CONSTRAINT_TEMPLATE_NAME
    

Wenn Sie eine Einschränkungsvorlage entfernen, können Sie keine Einschränkungen mehr erstellen, die darauf verweisen.

Nächste Schritte