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.
| 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. Jede Bindung 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 Bindungen 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.
ServiceAccount des Pods per RBAC nutzen darf (genau die Bindung 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 eine SA-spezifische Bindung 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 | Bindungen |
|---|---|
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-Bindung, 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-Bindung – 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