- Authors

- Name
- Phillip Pham
- @ddppham
Error from server Forbidden: welches Recht fehlt
TL;DR
Error from server (Forbidden) heißt: der API-Server hat den Request gesehen und abgelehnt. Verbindung und Zertifikat sind in Ordnung. Die Meldung nennt meist User oder ServiceAccount, Verb und Ressource. Diesen Satz prüfen, nicht raten:
kubectl auth can-i VERB RESOURCE -n NAMESPACE
kubectl auth can-i --list -n NAMESPACE
yes für get pods und no für get secrets ist ein normales Least-Privilege, kein defekter Cluster. Die Rolle, die das Recht tragen sollte, fehlt oder gilt im falschen Scope. Wer stattdessen cluster-admin vergibt, schließt das Symptom und öffnet das Cluster. Der ausführliche Audit-Weg: RBAC Audit.
Was in der Zeile steht
Eine typische Meldung: User "system:serviceaccount:prod:deploy" cannot list resource "secrets" in API group "" in the namespace "prod".
Vier Felder, alle brauchbar:
| Feld | Bedeutung |
|---|---|
| User | Mensch aus dem kubeconfig oder system:serviceaccount:NS:NAME |
| Verb | get, list, watch, create, update, patch, delete |
| Ressource | pods, secrets, deployments, … |
| Scope | Namespace oder Cluster |
list ist nicht get. Ein Dashboard, das die Übersicht lädt, braucht list. Ein kubectl get pod POD braucht get. deployments liegen in der API-Gruppe apps, Pods in "". Eine Role, die nur pods erlaubt, lässt kubectl get deploy weiter mit Forbidden scheitern.
Role und Binding
Das Recht steht in einer Role oder ClusterRole. Es gilt erst durch ein RoleBinding oder ClusterRoleBinding, das diese Role an den User oder ServiceAccount hängt.
kubectl get rolebinding,clusterrolebinding -A -o wide | grep ACCOUNT
Ein RoleBinding gilt nur in seinem Namespace. Ein Binding in default hilft dem Pod in prod nicht. Ein ClusterRoleBinding gilt clusterweit. Für einen CI-Account, der nur in einem Namespace deployen soll, ist das ClusterRoleBinding zu weit. Dann Role plus RoleBinding in genau diesem Namespace, mit den Verben, die die Pipeline wirklich aufruft.
kubectl auth can-i create deployments.apps -n prod --as=system:serviceaccount:prod:deploy prüft, was der Deploy-Account darf, ohne sich als dieser Account anzumelden. --as braucht selbst das Recht, andere Identitäten zu impersonieren. Ohne dieses Recht die Frage im Pod stellen: kubectl exec mit dem ServiceAccount des Pods, oder can-i aus einem Pod dieses Accounts.
Forbidden ist nicht 6443 und nicht der Pod
connection refused auf 6443 erreicht den API-Server nicht. Forbidden schon. Ein Pod auf CrashLoopBackOff kann zusätzlich Forbidden in seinen eigenen Logs haben, wenn die Anwendung die API aufruft und ihr ServiceAccount das Recht nicht hat. Dann ist der Exit der Anwendung oft 1, und die Zeile cannot list resource steht im Previous-Log. Das Recht gehört an den ServiceAccount des Pods, nicht an Ihren kubectl-User.
Quellen
📖 Verwandte Artikel
Weitere interessante Beiträge zu ähnlichen Themen
kubectl connection refused 6443 beheben
kubectl connection refused auf Port 6443: der API-Server antwortet nicht. kubeconfig, Kontext, Firewall, API-Prozess. Der Pod-Status kommt erst danach.
Exit Code 1: die erste Zeile im Previous-Log
Exit Code 1 auf Kubernetes: die Anwendung beendet sich selbst. kubectl logs --previous zeigt die Zeile. Speicher, Image-Pull und SIGKILL sind andere Codes.
Pod startet nicht: Status lesen, dann der Fix
Pod startet nicht: ein kubectl get pod, dann der Status. Pending, ImagePull, CrashLoop, Evicted und die Befehle, die den jeweiligen Fehler wirklich zeigen.
CrashLoopBackOff beheben: Logs, Probes, Exit-Code
CrashLoopBackOff beheben: kubectl logs --previous, Exit-Codes 1, 137 und 139, Liveness-Probes. Der Unterschied zu ImagePullBackOff in wenigen Minuten.
ImagePullBackOff beheben: Auth, Name, Limit
ImagePullBackOff beheben: Image-Name, imagePullSecrets und Registry-Rate-Limits. Welches Event den Unterschied macht und wann es kein CrashLoopBackOff ist.
Pod Terminating hängt: Finalizer entfernen
Pod Terminating hängt: Finalizer finden, Grace-Period abwarten, Force-Delete nur wenn der Node weg ist. Der kubectl-Patch, und wann er ein Volume beschädigt.
ContainerCreating hängt: Volume, Sandbox, CNI
ContainerCreating hängt: der Pod hat einen Node, der Container startet nicht. FailedMount, Pod-Sandbox und CNI stehen in den Events, nicht in den Logs.
CreateContainerConfigError: Secret und ConfigMap
CreateContainerConfigError: fehlendes Secret, falscher Key oder Namespace. Der Container startet nicht, logs --previous bleibt leer. Das Event nennt das Objekt.