Voraussetzung: ein Cluster mit oc login
als Admin (kubeadmin reicht), Namespace library
(oc new-project library oder oc project library).
1 Das RBAC-Modell
Zwei Objektarten, sauber getrennt: was erlaubt ist und wer es darf.
Nach dem Anmelden (A4) weiß der Cluster wer du bist – aber noch nicht, was du darfst. Das klärt RBAC mit genau zwei Objektarten: einer Rolle (Liste erlaubter Aktionen) und einem Binding (hängt die Rolle an eine Person, Gruppe oder einen ServiceAccount). Ein frischer User darf zuerst fast nichts.
Role/ClusterRole
zählt erlaubte Aktionen auf (verbs × resources × apiGroups),
ein RoleBinding hängt sie an einen User, eine Group oder einen
ServiceAccount – im Namespace, oder clusterweit per ClusterRoleBinding.
Die Default-Rollen view/edit/admin decken den Alltag ab, oc new-project
gibt dir admin auf dein Projekt. RBAC kann nur erlauben, nie verbieten – Entzug heißt: Binding löschen.- es gibt zwei Objektarten:
RoleundClusterRolesind die Regelliste,RoleBindingundClusterRoleBindingsind die Zuordnung - eine Regel kreuzt drei Achsen:
verbs(get, list, watch, create, update, patch, delete),resourcesundapiGroups(der leere String steht für die Kern-Gruppe) - eine
Rolegilt in einem Namespace, eineClusterRoleclusterweit oder als wiederverwendbare Vorlage - Subjekte sind: ein
User(aus dem IdP, A4), eineGroupoder eineServiceAccount(system:serviceaccount:<ns>:<name>, A6) - die Default-ClusterRoles:
viewdarf lesen (ohne Secrets),editdarf Workloads ändern und Secrets lesen (ohne RBAC),admindarf zusätzlich RBAC im Namespace (aber nicht Quota),cluster-admindarf alles oc new-projectlegt eineadmin-RoleBinding auf den Anleger an (A2) – darum darfst du im eigenen Projekt sofort fast alle normalen Namespace-Ressourcen verwalten- eine Rolle binden:
oc adm policy add-role-to-user <role> <user> -n <ns>,-z <sa>statt des Namens für eine ServiceAccount,add-cluster-role-to-userfür clusterweit - aggregierte Rollen:
admin,editundviewsammeln automatisch jede ClusterRole mit dem Labelaggregate-to-*, so erweitern Operatoren sie von selbst - RBAC ist rein additiv, es gibt kein „deny“ – Entzug geht über
remove-role-from-useroder das Löschen des Bindings - prüfen mit
oc auth can-i --as <user> <verb> <resource>,oc adm policy who-can <verb> <resource>oderoc describe clusterrole edit - Bibliothek: die SA
pipelineinlibrarybekommt drei Bindings –admin(Helm-Deploy),system:image-builderundregistry-editor(Push in die interne Registry). Sonst nichts (E1, B12) - bei einem kaputten Jenkins-Deploy ist
oc auth can-i --as=system:serviceaccount:library:pipeline <verb> <resource> -n librarydie schnellste Antwort auf „darf die pipeline-SA das“ - auch die SCC wird über dieselbe Mechanik vergeben:
add-scc-to-userbindet die ClusterRolesystem:openshift:scc:<name>(A7)
| Objekt | ist | Geltung |
|---|---|---|
Role | eine Regelliste | ein Namespace |
ClusterRole | eine Regelliste | clusterweit – oder als wiederverwendbare Vorlage, per RoleBinding auf einen Namespace begrenzt |
RoleBinding | ordnet ein Subjekt einer Role/ClusterRole zu | ein Namespace |
ClusterRoleBinding | ordnet ein Subjekt einer ClusterRole zu | clusterweit |
Eine Regel kreuzt drei Achsen: verbs (get,
list, watch, create, update,
patch, delete), resources und apiGroups
(der leere String meint die Kern-API). Subjekte sind ein User (aus dem IdP),
eine Group, oder eine ServiceAccount
(system:serviceaccount:<ns>:<name>).
# eine Rolle ansehen: oc get clusterrole edit -o yaml | head -20 # alle Rollen, die an ein Subjekt gebunden sind: oc get rolebinding,clusterrolebinding -n library -o wide
2 view / edit / admin live
Leg drei ServiceAccounts an, binde je eine Default-Rolle, und vergleiche live, was jede darf.
oc create sa demo-view -n library oc create sa demo-edit -n library oc create sa demo-admin -n library oc adm policy add-role-to-user view -z demo-view -n library oc adm policy add-role-to-user edit -z demo-edit -n library oc adm policy add-role-to-user admin -z demo-admin -n library # Secrets lesen: oc auth can-i get secrets --as=system:serviceaccount:library:demo-view -n library # no oc auth can-i get secrets --as=system:serviceaccount:library:demo-edit -n library # yes # RBAC selbst aendern: oc auth can-i create rolebindings --as=system:serviceaccount:library:demo-edit -n library # no oc auth can-i create rolebindings --as=system:serviceaccount:library:demo-admin -n library # yes
| Rolle | darf | darf nicht |
|---|---|---|
view | alles lesen | Secrets lesen, irgendetwas ändern |
edit | Workloads ändern, Secrets lesen | RBAC ändern, Quota sehen/ändern |
admin | zusätzlich RBAC im Namespace, ResourceQuota | den Namespace selbst löschen, clusterweite Objekte |
cluster-admin | alles, überall | – |
Aggregierte Rollen: admin, edit und view
sammeln automatisch jede ClusterRole mit dem Label rbac.authorization.k8s.io/
aggregate-to-edit: "true" – so erweitern Operatoren die Default-Rollen, ohne dass
du etwas änderst.
3 Eine Rolle binden
Der Befehl, der die Bibliothek-Pipeline real benutzt.
oc create sa pipeline -n library oc adm policy add-role-to-user admin -z pipeline -n library oc adm policy add-cluster-role-to-user system:image-builder -z pipeline -n library oc adm policy add-cluster-role-to-user registry-editor -z pipeline -n library # das Ergebnis nachsehen: oc describe rolebinding -n library | grep -A3 pipeline oc get sa/pipeline -n library -o yaml
-z <sa> statt eines Namens bindet eine ServiceAccount im
aktuellen (oder mit -n angegebenen) Namespace – kurz für
system:serviceaccount:library:pipeline.
4 Prüfen: can-i / who-can
| Befehl | beantwortet |
|---|---|
oc auth can-i <verb> <resource> --as=<subjekt> -n <ns> | darf dieses Subjekt das tun? |
oc adm policy who-can <verb> <resource> -n <ns> | welche Subjekte dürfen es – alle auf einmal |
oc whoami / oc whoami --show-token | wer bin ich gerade, und mit welchem Token |
Erster Griff bei einem kaputten Jenkins-Deploy:
oc auth can-i create deployments --as=system:serviceaccount:library:pipeline -n library
– sekundenschnell die Antwort, ob es RBAC ist oder etwas anderes.
5 RBAC ist additiv
Es gibt kein deny. jedes Binding gibt Rechte dazu,
nie weg.
# Entzug = die Bindung weg, nicht ein Verbot: oc adm policy remove-role-from-user edit demo-edit -n library # oder direkt das RoleBinding-Objekt loeschen: oc delete rolebinding-n library
Wenn zwei Bindings sich „widersprechen“ (eine erlaubt, eine erlaubt nicht),
gewinnt immer die erlaubende – ein zweites, engeres Recht schränkt
ein weiteres nie ein. Das ist der wichtigste Unterschied zu Firewall-Regeln oder
NetworkPolicy (F2), wo Reihenfolge und deny zählen.
6 Was eine SCC ist
Eine Security Context Constraint ist eine OpenShift-Admission
für den securityContext eines Pods – sie begrenzt ihn und setzt
offene Felder selbst. Älter als Kubernetes-PodSecurity, und Kern-OpenShift.
Eine SCC ist eine OpenShift-Admission, die beim Erstellen eines Pods prüft, was sein securityContext darf – und Felder, die der Pod offen lässt, selbst setzt (vor allem die UID). Welche SCC ein Pod bekommt, hängt daran, welche SCCs seine ServiceAccount (A6) per RBAC (A5) nutzen darf. Die Vorgabe restricted-v2 verbietet Root – das ist die häufigste Starthürde bei fremden Images.
ServiceAccount nutzen darf und die den Pod
(ggf. nach Mutation der UID) zulässt, und schreibt sie in openshift.io/scc.
restricted-v2 gilt für alle: zufällige UID, privileged: false, alle
Capabilities weg, kein Host-Zugriff. Startet ein Image nicht, ist fast immer das Image schuld
(will Root, fester UID, kleiner Port) – der Fix ist das Image, nicht reflexhaft eine lockere SCC.- eine SCC ist eine OpenShift-Admission für den
securityContext– sie begrenzt ihn und setzt offene Felder selbst. Älter als das Kubernetes-PodSecurity - die Auswahl: die Admission nimmt alle SCCs, die die
ServiceAccount(A6) per RBAC (A5) nutzen darf, sortiert nach Priorität absteigend und dann Restriktivität aufsteigend, und nimmt die erste, die passt - welche SCC gewonnen hat, steht in der Pod-Annotation
openshift.io/scc(sie wird generiert) - die Vorgabe
restricted-v2gilt für jeden authentifizierten Account, über die Gruppesystem:authenticated restricted-v2setzt eine zufällige UID (runAsUser: MustRunAsRange),privileged: false, wirft alle Capabilities weg, verlangt seccompRuntimeDefaultund erlaubt keinen Host-Zugriff- UID, MCS-Label und fsGroup kommen aus den Namespace-Annotationen
openshift.io/sa.scc.*, gesetzt beioc new-project(A2) - die eingebauten SCCs von locker nach streng:
privileged,anyuid,hostmount-anyuid,hostnetwork-v2,nonroot-v2,restricted-v2 - Unterschied
restricted(v1) zurestricted-v2: v2 verlangt seccomp undallowPrivilegeEscalation:falseausdrücklich - typische Startfehler: das Image hat
USER 0und schreibt ins RootFS, bindet einen Port unter 1024, erwartet einen festen UID und machtchown, oder gerät in denrunAsNonRoot-Konflikt - Fix in dieser Reihenfolge: erstens das Image UID-agnostisch bauen (UBI ist es schon), zweitens ein Chart-Override oder
adaptSecurityContext=auto, drittens als letztes eine lockere SCC an genau die eine SA - zuweisen mit
oc adm policy add-scc-to-user nonroot-v2 -z <sa> -n <ns>– das erzeugt eine RoleBinding auf die ClusterRolesystem:openshift:scc:<name>(A5) - Bibliothek: die 8 Spring-Dienste passen unter
restricted-v2, die Bitnami-Images brauchenglobal.compatibility.openshift.adaptSecurityContext=auto(Keycloak, Postgres, Redis, Kafka) - library-frontend läuft als
nginx-unprivileged– trotzdem braucht das Imagechmod g+w /etc/nginx/conf.d, weil der Entrypoint die Config zur Laufzeit schreibt und die zufällige UID sonst nicht darf - Legacy-Vertiefung: was bei einer EJB- oder WAS-App bricht, die UID 0 erwartet, steht in H1
ServiceAccount des Pods per RBAC nutzen darf (genau das Binding aus Schritt 3), sortiert nach Priorität absteigend, dann Restriktivität aufsteigendopenshift.io/sccrestricted-v2 gilt für jeden authentifizierten Account, über die Gruppe system:authenticated – ohne ein SA-spezifisches Binding landest du immer hierrestricted-v2 setzt eine zufällige UID
(runAsUser: MustRunAsRange), privileged: false, wirft alle
Capabilities weg, verlangt Seccomp RuntimeDefault und erlaubt keinen
Host-Zugriff. UID, MCS-Label und fsGroup kommen dabei aus den
Namespace-Annotationen openshift.io/sa.scc.* (von oc new-project
gesetzt).
7 Eine SCC live gewinnen
Ein Image, das USER 0 erwartet, scheitert unter
restricted-v2 – dann geben wir ihm die passende SCC.
oc create sa demo-root -n library
oc run rootcheck -n library --image=registry.access.redhat.com/ubi9/ubi-minimal \
--overrides='{"spec":{"serviceAccountName":"demo-root"}}' -- id
oc get pod rootcheck -n library # CreateContainerConfigError / Error
oc get events -n library --field-selector involvedObject.name=rootcheck
# die Pod-Annotation zeigt die gewonnene (Vorgabe-)SCC:
oc get pod rootcheck -n library -o jsonpath='{.metadata.annotations.openshift\.io/scc}{"\n"}'
# jetzt die SA-Bindung geben und neu starten:
oc adm policy add-scc-to-user anyuid -z demo-root -n library
oc delete pod rootcheck -n library --ignore-not-found
oc run rootcheck -n library --image=registry.access.redhat.com/ubi9/ubi-minimal \
--overrides='{"spec":{"serviceAccountName":"demo-root"}}' -- id
oc get pod rootcheck -n library -o jsonpath='{.metadata.annotations.openshift\.io/scc}{"\n"}'
# jetzt: anyuid
Die eingebauten SCCs, von locker nach streng: privileged,
anyuid, hostmount-anyuid, hostnetwork-v2,
nonroot-v2, restricted-v2. Unterschied restricted
(v1, älter) zu restricted-v2: v2 verlangt Seccomp und
allowPrivilegeEscalation: false ausdrücklich.
oc adm policy add-scc-to-user ist selbst nur
RBAC – der Befehl erzeugt eine RoleBinding auf die ClusterRole
system:openshift:scc:<name>. SCC-Vergabe ist RBAC, nur mit einem
speziellen Rollen-Namensschema.
8 Die Fix-Reihenfolge
Ein Image scheitert unter restricted-v2. In dieser Reihenfolge
vorgehen – nicht umgekehrt.
root gehören lassen und chmod g+w auf die Pfade, in die zur Laufzeit geschrieben wirdglobal.compatibility.openshift.adaptSecurityContext=auto eingebaut, genau dafürsystem:authenticated, das hält niemanden mehr unter restricted-v2Typische Startfehler, die auf Schritt 1 zeigen: das Image hat USER 0 und
schreibt ins RootFS, bindet einen Port unter 1024, erwartet eine feste UID und macht
chown, oder gerät in den runAsNonRoot-Konflikt.
9 Wie die Bibliothek es macht
| SA / Konsument | Bindings |
|---|---|
pipeline | admin in library (Helm-Deploy) + system:image-builder + registry-editor (Registry-Push) – keine SCC-Sonderrechte |
| die 8 Spring-Dienste | laufen unter der default-SA, ganz normal unter restricted-v2 – kein Override nötig |
| Bitnami-Infra (Postgres/Redis/Kafka/Keycloak) | brauchen keine SCC-Binding, sondern global.compatibility.openshift.adaptSecurityContext=auto im Helm-Wert – der Chart passt sich restricted-v2 selbst an |
library-frontend (nginx-unprivileged) | läuft ebenfalls unter restricted-v2, das Image braucht trotzdem chmod g+w /etc/nginx/conf.d, weil der Entrypoint die Config zur Laufzeit schreibt |
Keiner der Bibliothek-Workloads hat eine SCC-Sonderrechte-Binding – das
ist genau der Beweis, dass Schritt 1 und 2 der Fix-Reihenfolge (Image + Chart-Override)
fast immer reichen. Nur eine Legacy-App, die UID 0 fest erwartet, bräuchte
Schritt 3 (Novaris, H1).
+ Die Kurzfassung
Role/ClusterRole = was, *Binding = wer. Rein additiv, kein deny. Prüfen mit oc auth can-i --as=<subjekt>system:authenticated