Skip to content

Die API sagt nein

Zwei verschiedene Mechanismen lehnen Dinge ab, und sie sehen unterschiedlich aus. Lies die erste Zeile des Fehlers, dann weißt du, mit welchem du es zu tun hast.

  • Forbidden heißt RBAC: Du darfst diese Art von Objekt überhaupt nicht anfassen.
  • denied the request heißt Plattformregel: Dein YAML ist in Ordnung, aber was es verlangt, ist nicht erlaubt.

Das Zweite ist wichtig, weil es am Manifest nichts zu reparieren gibt. Du brauchst einen anderen Ansatz, und die Meldung sagt, welche Regel gegriffen hat.

Forbidden bei einem kubectl-Befehl

Drei Ursachen, in der Reihenfolge, in der sie tatsächlich vorkommen.

Dein Standard-Namespace ist nicht gesetzt. Der Befehl lief gegen default, worauf du keinen Zugriff hast. Prüf, was der aktuelle Kontext mitbringt:

bash
kubectl config view --minify | grep namespace

Steht da nichts, setz ihn einmal, siehe Zugang und kubectl.

Die Ressource gehört nicht zu denen, die du anfassen darfst. Dein Namespace gibt eine bestimmte Liste frei, alles andere ist verboten. Frag direkt, statt zu raten:

bash
kubectl auth can-i create scaledobjects
kubectl auth can-i list nodes

Die vollständige Liste steht unter Berechtigungen und Richtlinien. Manche Berechtigungen sind nur lesend, insbesondere dein Kontingent und die LimitRanges. get kann also durchgehen, während edit am selben Objekt abgelehnt wird.

Cluster-weite Lesezugriffe werden immer abgelehnt, auch harmlos wirkende:

text
Error from server (Forbidden): nodes is forbidden: User "..." cannot list
resource "nodes" in API group "" at the cluster scope

Das ist so gewollt und kein kaputtes Setup. Es heißt auch, dass du kubectl get storageclass nicht ausführen kannst; die beiden Klassennamen stehen unter Storage.

KUBECONFIG zeigt woanders hin. Prüf, wo du bist:

bash
kubectl config current-context

denied the request beim Apply

Eine Plattformregel hat gegriffen. Die Form ist immer gleich:

text
Error from server: error when creating "app.yaml": admission webhook denied the
request: <die Regel, die gegriffen hat, und warum>

Die vollständige Liste der Regeln steht unter Berechtigungen und Richtlinien. Die häufigsten:

Die Meldung nenntWas gemeint istWas zu tun ist
Volume type not allowedEin Inline-Volume im Pod-SpecFordere Speicher über ein PersistentVolumeClaim an
Only ClusterIP Services are permittedNodePort, LoadBalancer oder ExternalNameBleib bei ClusterIP und veröffentliche über eine HTTPRoute
may not create CertificateEin selbst geschriebenes CertificateLass es über die Annotation an deiner HTTPRoute entstehen
Hostname is not allowed in namespaceEin Hostname, den dein Namespace nicht ausliefern darfSiehe unten
must declare at least one hostnameEine HTTPRoute ohne hostnamesTrag einen ein
Free-tier namespaces may only use the nfs-rwx StorageClassBlockspeicher im Free TierNimm nfs-rwx, siehe Free Tier
may not tolerateEine Toleration, die auf alles passtNimm sie raus und überlass die Platzierung dem Scheduler
may not set spec.nodeNameEin handverlesener NodeNimm es raus
body.maxSizeEin Body-Limit über der Grenze oder auf nullSetz eine explizite Größe bis maximal 512 MiB

Hostname is not allowed in namespace

text
Hostname is not allowed in namespace 'tenant-7'. Tenant namespaces may only use
*.tenant-7.itsh.dev (paid) or *.tenant-7.itsh-apps.dev (free) subdomains or
hostnames listed in the itsh.dev/allowed-hostnames namespace annotation.

Dein Namespace besitzt eine Subdomain und kann jeden Namen darunter sofort ausliefern. Alles andere musst du zuerst im Portal eintragen und per DNS-Eintrag nachweisen, dass die Domain dir gehört.

Free-Tier-Namespaces können überhaupt keine eigene Domain nutzen. Die vollständigen Regeln stehen unter Gateway API.

Exec/attach is only allowed into gVisor-sandboxed pods

Du hast versucht, eine Shell in einem verwalteten PostgreSQL-Pod zu bekommen. Die laufen außerhalb der Sandbox, und exec ist nur in sandboxed Pods erlaubt. Diese Kombination wird also abgelehnt.

Das betrifft nur PostgreSQL. In MariaDB- und Dragonfly-Pods kommst du wie überall sonst hinein. Um SQL auszuführen, leite den Port weiter und nimm einen lokalen Client, das ist nicht betroffen. Siehe Datenbanken.

Wie es weitergeht