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 applyabgelehnt 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-Gruppe | Ressourcen | Zugriff |
|---|---|---|
apps | deployments, statefulsets, replicasets | Voll |
apps | deployments/scale, statefulsets/scale | get, update, patch |
"" (Core, Objekte) | services, configmaps, secrets, serviceaccounts, persistentvolumeclaims | Voll |
"" (Core, Laufzeit) | pods, pods/log, pods/exec, pods/attach, pods/portforward, events, endpoints | Voll |
"" (Core, Kontingente) | resourcequotas, limitranges | Nur lesen |
events.k8s.io | events | Nur lesen |
batch | jobs, cronjobs | Voll |
autoscaling | horizontalpodautoscalers | Voll |
autoscaling.k8s.io | verticalpodautoscalers | Voll |
policy | poddisruptionbudgets | Voll |
gateway.networking.k8s.io | httproutes, grpcroutes | Voll |
gateway.nginx.org | clientsettingspolicies | Voll |
postgresql.cnpg.io | clusters, backups, scheduledbackups, poolers, databases, publications, subscriptions, imagecatalogs | Voll |
k8s.mariadb.com | mariadbs, databases, users, grants, connections, backups, restores, sqljobs, maxscales | Voll |
dragonflydb.io | dragonflies | Voll |
keda.sh | scaledobjects, scaledjobs, triggerauthentications | Voll |
metrics.k8s.io | pods | get, 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 resourcequotaundkubectl describe resourcequotada, 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.
| Regel | Was du stattdessen tust |
|---|---|
| Volume-Typen direkt im Pod werden nicht angenommen | Fordere Speicher über ein PersistentVolumeClaim an |
Services vom Typ NodePort, LoadBalancer und ExternalName werden nicht angenommen, spec.externalIPs ebenfalls nicht | Bleib bei ClusterIP und veröffentliche über eine HTTPRoute |
Certificate-Ressourcen kannst du nicht selbst schreiben | Lass das Zertifikat über die Annotation an deiner HTTPRoute entstehen |
| Eine HTTPRoute muss mindestens einen Hostnamen angeben | Ohne 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 sein | Siehe 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 setzen | Die passende wird für dich gesetzt |
Eine ClientSettingsPolicy darf die Request-Body-Größe nicht über 512 MiB heben und nicht auf null setzen | Setz eine explizite Größe innerhalb dieser Grenze |
| Die HTTP-Ressourcen für Scale-to-Zero werden für dich verwaltet | Nimm die Annotation itsh.dev/scale-to-zero, siehe Autoscaling |
Im Free Tier ist nfs-rwx die einzige zulässige Storage-Klasse | Siehe 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:
# Wird abgelehnt
spec:
volumes:
- name: data
nfs:
server: nfs.example.com
path: /export/dataBrauchst du geteilten Speicher, fordere ihn über ein PVC mit der Klasse nfs-rwx an, siehe Storage:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-rwx
resources:
requests:
storage: 10GiKein 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:
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
- Die API sagt nein, wenn etwas abgelehnt wurde
- Gateway API für die Hostnamen-Regeln im Ganzen