Skip to content

Berechtigungen und Richtlinien

In deinem Namespace bist du weitgehend frei, aber nicht unbegrenzt. Zwei Mechanismen ziehen die Grenze, und sie melden sich unterschiedlich:

  • RBAC entscheidet, welche Ressourcen du überhaupt anfassen darfst. Ein Verstoß endet mit Forbidden.
  • Plattformregeln entscheiden, ob ein konkretes Manifest akzeptiert wird. Ein Verstoß endet damit, dass dein kubectl apply abgelehnt wird.

Was RBAC freigibt

"Voll" heißt unten get, list, watch, create, update, patch und delete. Wo eine Zeile etwas Engeres nennt, ist das die gesamte Berechtigung.

API-GruppeRessourcenZugriff
appsdeployments, statefulsets, replicasetsVoll
appsdeployments/scale, statefulsets/scaleget, update, patch
"" (Core, Objekte)services, configmaps, secrets, serviceaccounts, persistentvolumeclaimsVoll
"" (Core, Laufzeit)pods, pods/log, pods/exec, pods/attach, pods/portforward, events, endpointsVoll
"" (Core, Kontingente)resourcequotas, limitrangesNur lesen
events.k8s.ioeventsNur lesen
batchjobs, cronjobsVoll
autoscalinghorizontalpodautoscalersVoll
autoscaling.k8s.ioverticalpodautoscalersVoll
policypoddisruptionbudgetsVoll
gateway.networking.k8s.iohttproutes, grpcroutesVoll
gateway.nginx.orgclientsettingspoliciesVoll
postgresql.cnpg.ioclusters, backups, scheduledbackups, poolers, databases, publications, subscriptions, imagecatalogsVoll
k8s.mariadb.commariadbs, databases, users, grants, connections, backups, restores, sqljobs, maxscalesVoll
dragonflydb.iodragonfliesVoll
keda.shscaledobjects, scaledjobs, triggerauthenticationsVoll
metrics.k8s.iopodsget, list

Alles gilt ausschließlich innerhalb deines Namespace.

Zwei Folgen der nur lesbaren Zeilen sind ausdrücklich erwähnenswert:

  • Dein eigenes Kontingent kannst du nicht ändern. Lesen ja, dafür sind kubectl get resourcequota und kubectl describe resourcequota da, aber Erhöhen ist eine Tarifsache, siehe Abrechnung und Kontingente.
  • Die Namespace-Standardwerte kannst du nicht ändern, die für Container ohne eigene Ressourcenangaben gelten.

Diese Tabelle beschreibt, was du mit kubectl tun kannst. Wenn du stattdessen deployst, indem du deinen Namespace auf ein Git-Repository zeigen lässt, werden über diesen Weg ein paar Arten nicht angenommen, obwohl sie hier stehen, derzeit Vertical Pod Autoscaler und ClientSettingsPolicies.

Alles andere ist verboten

Was nicht in der Tabelle steht, ist nicht erlaubt. Das betrifft insbesondere Nodes, Namespaces, ClusterRoles und das Verwalten von CRDs. Solche Befehle enden mit Forbidden, siehe Zugang und kubectl.

Die Storage-Klassen kannst du nicht auflisten

kubectl get storageclass ist ebenfalls gesperrt, du kannst die verfügbaren Klassen also nicht aus dem Cluster heraus herausfinden. Es gibt zwei, benannt und beschrieben unter Storage.

Plattformregeln

Zusätzlich zu RBAC prüft die Plattform jedes Manifest gegen einen festen Satz Regeln. Die sind hart: Ein Manifest, das dagegen verstößt, wird abgelehnt.

RegelWas du stattdessen tust
Volume-Typen direkt im Pod werden nicht angenommenFordere Speicher über ein PersistentVolumeClaim an
Services vom Typ NodePort, LoadBalancer und ExternalName werden nicht angenommen, spec.externalIPs ebenfalls nichtBleib bei ClusterIP und veröffentliche über eine HTTPRoute
Certificate-Ressourcen kannst du nicht selbst schreibenLass das Zertifikat über die Annotation an deiner HTTPRoute entstehen
Eine HTTPRoute muss mindestens einen Hostnamen angebenOhne Hostnamen würde sie sich als Catch-all an das gemeinsame Gateway hängen
Hostnamen müssen unter deiner Namespace-Subdomain liegen oder im Portal für deinen Namespace freigeschaltet seinSiehe Gateway API
Ein Pod darf sich seinen Node nicht selbst aussuchen und keine Toleration tragen, die auf alles passtÜberlass die Platzierung dem Scheduler. Eine pauschale operator: Exists-Toleration zählt dazu, kopier sie also nicht hinein
Ein Pod darf keine eigene PriorityClass setzenDie passende wird für dich gesetzt
Eine ClientSettingsPolicy darf die Request-Body-Größe nicht über 512 MiB heben und nicht auf null setzenSetz eine explizite Größe innerhalb dieser Grenze
Die HTTP-Ressourcen für Scale-to-Zero werden für dich verwaltetNimm die Annotation itsh.dev/scale-to-zero, siehe Autoscaling
Im Free Tier ist nfs-rwx die einzige zulässige Storage-KlasseSiehe Free Tier

Sandbox-Runtime

Deine Workloads laufen in einer Sandbox-Runtime. Sie wird automatisch gesetzt, und abwählen kannst du sie nicht. Für deine eigenen Workloads gibt es dabei nichts zu beachten: Sie wird auch dann gesetzt, wenn du nichts angibst.

An einer Stelle merkst du sie doch. Verwaltete PostgreSQL-Pods sind davon ausgenommen, und weil kubectl exec nur in sandboxed Pods erlaubt ist, kommst du dort nicht per Shell hinein. Siehe Datenbanken.

Inline-Volumes: nimm ein PVC

Volume-Typen, die du direkt im Pod definierst, werden abgelehnt. Das betrifft ausdrücklich auch ein nfs-Volume im Pod-Spec:

yaml
# Wird abgelehnt
spec:
  volumes:
    - name: data
      nfs:
        server: nfs.example.com
        path: /export/data

Brauchst du geteilten Speicher, fordere ihn über ein PVC mit der Klasse nfs-rwx an, siehe Storage:

yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: nfs-rwx
  resources:
    requests:
      storage: 10Gi

Kein NodePort, kein LoadBalancer

Nach außen geht es ausschließlich über eine HTTPRoute am gemeinsamen Gateway, siehe Gateway API. Ein Service mit type: LoadBalancer oder type: NodePort wird abgelehnt, ClusterIP ist der richtige Typ.

Zertifikate kommen von der Route

Eine Certificate-Ressource selbst anzulegen, wird abgelehnt. TLS entsteht über die Annotation cert-manager.io/cluster-issuer an deiner HTTPRoute, und zwar ohne dein Zutun.

Wie eine Ablehnung aussieht

Verstößt dein Manifest gegen eine Regel, sieht das beim kubectl apply ungefähr so aus:

text
Error from server: error when creating "app.yaml": admission webhook denied the
request: <Begründung, welche Regel verletzt wurde>

Zwei echte Beispiele stehen unter Gateway API, für einen Hostnamen, der dir nicht gehört, und unter Datenbanken, für exec in einen PostgreSQL-Pod.

Der Wortlaut hängt von der Regel ab. Wichtig ist der Unterschied zum Syntaxfehler: denied the request heißt, dass mit deinem YAML alles in Ordnung ist und eine Regel gegriffen hat. Am Manifest gibt es dann nichts zu reparieren, du brauchst einen anderen Ansatz. Welche Regel es war, steht in der Begründung dahinter.

Wie es weitergeht