· Kubernetes  · 8 Min. Lesezeit

Pinniped: die sechzehn Stolpersteine bei Supervisor, Concierge und CLI

Die vollständige Fallsammlung zu Pinniped v0.47.0. Sechzehn dokumentierte Stolpersteine aus Doku und Release-Notes, geordnet nach Ausrollen, Verdrahten, Upgrade und Betrieb, jeder nach Symptom, Ursache, Prüfung und Lösung.

Die vollständige Fallsammlung zu Pinniped v0.47.0. Sechzehn dokumentierte Stolpersteine aus Doku und Release-Notes, geordnet nach Ausrollen, Verdrahten, Upgrade und Betrieb, jeder nach Symptom, Ursache, Prüfung und Lösung.

Wenn Sie Pinniped gerade einrichten, arbeiten Sie zuerst den Beitrag Kurzlebige Cluster-Logins mit Pinniped durch. Dort steht der Weg mit Prüfbefehl nach jedem Schritt, und dort sind auch die drei folgenreichsten Fälle bereits eingebaut.

Diese Sammlung ist für zwei Situationen gedacht. Erstens für die Vorbereitung: Wer ein Produktiv-Rollout oder einen Versionssprung plant, geht die Liste einmal durch und weiß danach, welche Punkte in der eigenen Umgebung überhaupt greifen. Zweitens für den Fehlerfall: Wenn der Login scheitert, die Gruppen nicht stimmen oder nach einem Upgrade Pods hängen, suchen Sie hier nach dem passenden Symptom.

Alle sechzehn Fälle stammen aus der offiziellen Dokumentation und den Release-Notes des Projekts. Die Nummerierung dient nur der Referenzierbarkeit und ist keine Rangfolge.

Beim Ausrollen

1. Ein öffentlicher LoadBalancer taucht ungefragt auf

Symptom: Nach dem Deploy des Concierge liegt ein Service vom Typ LoadBalancer mit externer IP im Cluster, den niemand angefordert hat.

Ursache: Die Default-Konfiguration des Concierge legt auf Cloud-Providern, bei denen das der Standard ist, einen öffentlichen LoadBalancer-Service an.

Prüfung:

kubectl get svc -n pinniped-concierge -o wide

Lösung: Statt der Default-Manifeste die angepasste Installation über ytt und kapp aus deploy/concierge fahren und die Werte aus der values.yaml überschreiben:

ytt --file . --file site/dev-env.yaml | kapp deploy --app pinniped-concierge --file -

2. Nicht-privilegierte Nutzer lesen die Pinniped-Secrets

Symptom: Ein Nutzer ohne Administratorrechte kann Secrets im Namespace pinniped-supervisor lesen.

Ursache: Die mitgelieferten Manifeste bringen keine Absicherung gegen Lesezugriffe auf den eigenen Namespace mit. Die Doku fordert diesen Schutz als eigenen Schritt ein, weil der Supervisor die Authentifizierung an allen angeschlossenen Clustern kontrolliert.

Prüfung: Die Antwort muss no lauten.

kubectl auth can-i get secrets -n pinniped-supervisor --as entwickler@lab.rz.jabi-it.de

Lösung: RBAC so setzen, dass Nicht-Administratoren die Ressourcen und insbesondere die Secrets in pinniped-concierge und pinniped-supervisor nicht lesen können.

3. Der interne API-Service wird nach außen exponiert

Symptom: Neben dem selbst angelegten Service ist auch pinniped-supervisor-api von außen erreichbar.

Ursache: Der Supervisor bringt neben dem OIDC-Port 8443 einen internen Service auf Port 10250 mit, der einem anderen Zweck dient.

Prüfung:

kubectl get svc -n pinniped-supervisor

Lösung: Ausschließlich den eigenen Service auf targetPort 8443 anlegen und pinniped-supervisor-api unangetastet im Cluster belassen.

Beim Verdrahten

4. Der Login scheitert, obwohl alles Ready meldet

Symptom: Supervisor und Concierge laufen, alle Ressourcen melden Ready, der Login schlägt trotzdem fehl.

Ursache: Der issuer im JWTAuthenticator weicht vom issuer der FederationDomain ab, etwa durch einen abweichenden Pfad oder einen Schrägstrich am Ende.

Prüfung: Beide Werte maschinell vergleichen, nicht mit dem Auge. Die Ausgaben müssen zeichengleich sein.

kubectl get federationdomain -n pinniped-supervisor \
  -o jsonpath='{.items[*].spec.issuer}' --kubeconfig management-admin.yaml
kubectl get jwtauthenticator \
  -o jsonpath='{.items[*].spec.issuer}' --kubeconfig workload-admin.yaml

Lösung: Den Wert wörtlich aus der FederationDomain übernehmen. Die Doku verlangt eine exakte Übereinstimmung, keine sinngemäße.

5. Zwei Cluster teilen sich eine audience

Symptom: Ein Token, das für Cluster A ausgestellt wurde, wird auch von Cluster B akzeptiert.

Ursache: Die audience im JWTAuthenticator ist frei wählbar. Wer das Manifest von Cluster zu Cluster kopiert, hebt die Trennung auf.

Prüfung: Auf jedem Cluster einzeln ausführen und die Werte vergleichen.

kubectl get jwtauthenticator -o jsonpath='{.items[*].spec.audience}'

Lösung: Jedem Cluster eine eigene, eindeutige audience geben. Die Doku-Beispiele hängen dafür einen Zufallssuffix an, etwa workload1-ed9de33c370981f61e9c.

6. Zertifikatsfehler im Browser oder beim Concierge

Symptom: Der Browser bricht den Login mit einem Zertifikatsfehler ab, oder der Concierge lehnt das Token wegen TLS ab.

Ursache: Das FederationDomain-Zertifikat stammt von einer internen CA, die weder der Browser noch die Concierge-Pods kennen.

Prüfung: Der Aufruf muss ohne -k erfolgreich sein.

curl https://supervisor.lab.rz.jabi-it.de/produktion/.well-known/openid-configuration

Lösung: Für den Browser ein von einer bekannten CA signiertes Zertifikat verwenden. Für den Concierge zusätzlich spec.tls.certificateAuthorityData im JWTAuthenticator als base64-kodiertes PEM setzen.

Zur Auflösung im Supervisor: Ein per SNI passendes FederationDomain-Zertifikat hat Vorrang. Trifft kein SNI zu, greift das Default-Secret pinniped-supervisor-default-tls-certificate.

7. Der Provider lehnt die Redirect-URI ab

Symptom: Der Login beim Identity-Provider bricht mit einem Redirect-URI-Fehler ab.

Ursache: Beim Provider ist eine andere Callback-URL hinterlegt als die, die der Supervisor tatsächlich benutzt.

Prüfung: kubectl describe OIDCIdentityProvider -n pinniped-supervisor zentraler-idp muss phase: Ready zeigen, danach einen echten Login versuchen.

Lösung: Beim Provider exakt den FederationDomain-Issuer mit angehängtem /callback eintragen, hier also https://supervisor.lab.rz.jabi-it.de/produktion/callback.

8. Der zweite Identity-Provider bricht die Anmeldung

Symptom: Nach dem Anlegen eines zweiten Identity-Providers scheitert die Anmeldung, obwohl der erste vorher funktioniert hat.

Ursache: Ohne spec.identityProviders fällt die FederationDomain in einen Rückwärts-Kompatibilitätsmodus, der genau einen Provider im Namespace voraussetzt. Ein zweiter Provider bricht diesen Modus.

Prüfung: Der status nennt die Fehlerursache.

kubectl get federationdomain -n pinniped-supervisor -o yaml

Lösung: spec.identityProviders explizit mit displayName und objectRef pflegen, sobald mehr als ein Provider existiert. Das Feld gibt es seit v0.26.0.

9. --anonymous-auth=false sperrt alle Nutzer aus

Symptom: Nach dem Setzen von --anonymous-auth=false am API-Server kann sich niemand mehr anmelden.

Ursache: Die TokenCredentialRequest-API des Concierge ist auf anonymen Zugriff angewiesen. Wird der abgeschaltet, bricht der Login-Pfad.

Prüfung: Nach der Änderung einen kubectl-Aufruf mit der Pinniped-kubeconfig absetzen und pinniped whoami ausführen.

Lösung: --anonymous-auth=false nur auf Clustern setzen, die die Impersonation-Proxy-Strategie verwenden.

Beim Upgrade

10. Die Pods ziehen keine neuen Images mehr

Symptom: Nach einem Upgrade bleiben die Pods auf dem alten Image, oder ein gespiegeltes Registry-Setup läuft ins Leere.

Ursache: Ab v0.40.0 werden Images nicht mehr nach ghcr.io/vmware-tanzu/pinniped/pinniped-server gepusht. GitHub leitet Container-Repositories im Gegensatz zu anderen Ressourcen nicht automatisch um.

Prüfung:

kubectl get deploy -n pinniped-concierge \
  -o jsonpath='{.items[*].spec.template.spec.containers[*].image}'

Lösung: Alle Deployments, Skripte und Mirror-Konfigurationen auf ghcr.io/vmware/pinniped/pinniped-server oder docker.io/getpinniped/pinniped-server umstellen. Das Release-Image der aktuellen Version ist ghcr.io/vmware/pinniped/pinniped-server:v0.47.0.

11. Ein Automatismus liest status.kubeConfigInfo und bekommt nichts mehr

Symptom: Ein Skript, das CredentialIssuer.status.kubeConfigInfo auswertet, liefert nach dem Upgrade leere Werte.

Ursache: Das lange als deprecated markierte Feld wurde in v0.38.0 entfernt.

Prüfung:

kubectl get credentialissuer -o yaml

Lösung: Vor dem Upgrade auf eine andere Quelle umstellen, in der Regel auf pinniped get kubeconfig.

12. Eine bisher akzeptierte FederationDomain wird abgelehnt

Symptom: Das Anlegen einer FederationDomain schlägt fehl, obwohl dieselbe Ressource früher akzeptiert wurde.

Ursache: Seit v0.38.0 wird die Bedingung, dass spec.issuer mit https:// beginnt, bereits bei der Erstellung geprüft statt erst danach. Die Ressourcenerstellung schlägt fehl statt nur der Status.

Prüfung:

kubectl get federationdomain -A -o jsonpath='{.items[*].spec.issuer}'

Lösung: Alle FederationDomain-Manifeste vor dem Upgrade auf https:// im Issuer prüfen und korrigieren.

Ein Ausblick auf das übernächste Upgrade: v0.47.0 führt Gos natives GOFIPS140 ein und markiert die bisherige Kompilierung mit boring crypto als deprecated. Sie wird in einem künftigen Release entfernt. Wer FIPS-Builds erzeugt, stellt jetzt um, solange beide Wege unterstützt werden.

Im Betrieb

13. Der nicht-interaktive Login in CI/CD funktioniert nicht

Symptom: Ein Pipeline-Job kann sich trotz gesetzter PINNIPED_USERNAME und PINNIPED_PASSWORD nicht anmelden.

Ursache: Zwei mögliche Gründe. Bei OIDC-Providern muss der Passwort-Flow erst durch den Administrator über allowPasswordGrant im OIDCIdentityProvider freigeschaltet werden. Bei GitHub geht es grundsätzlich nicht, denn die GitHubIdentityProvider-Ressource unterstützt den cli_password-Flow wegen Einschränkungen von GitHubs OAuth-2.0-System nicht.

Prüfung:

kubectl get oidcidentityprovider -n pinniped-supervisor -o yaml

Lösung: Bei OIDC allowPasswordGrant setzen und die kubeconfig für nicht-menschliche Konten mit dem passenden Flow erzeugen:

pinniped get kubeconfig --kubeconfig "$HOME/admin-kubeconfig.yaml" \
  --upstream-identity-provider-flow=cli_password > ci-kubeconfig.yaml

export PINNIPED_USERNAME="ci-runner@lab.rz.jabi-it.de"
export PINNIPED_PASSWORD="${CI_PINNIPED_SECRET}"
kubectl get deployments -n produktion --kubeconfig ci-kubeconfig.yaml

Bei GitHub konfigurieren Sie stattdessen einen zweiten Provider per OIDC, LDAP oder Active Directory auf derselben FederationDomain und stellen für die nicht-menschlichen Konten eine eigene kubeconfig aus.

14. Credentials landen im Klartext im Log

Symptom: In den Server-Logs tauchen Zugangsdaten auf.

Ursache: Die Log-Level trace und all protokollieren laut Doku möglicherweise Credentials mit.

Prüfung: Den Wert unter log.level prüfen.

kubectl get cm pinniped-concierge-config -n pinniped-concierge -o yaml

Lösung: trace und all niemals auf Produktivsystemen setzen. Nach dem Debugging zurück auf info und die Pods neu starten:

kubectl delete --all pods -n pinniped-concierge

Für die Fehlersuche auf der Client-Seite genügt in aller Regel die Umgebungsvariable PINNIPED_DEBUG=true, die die CLI-Ausgabe erweitert und keinen Eingriff am Server verlangt.

15. Falsche Gruppen aus dem Active Directory

Symptom: Gruppenzuordnungen stimmen nicht, wenn Common Names im AD Kommata enthalten.

Ursache: Bei leerem groupSearch.attributes.groupName hat der ActiveDirectoryIdentityProvider Kommata innerhalb von DN-Feldwerten falsch interpretiert.

Prüfung: pinniped whoami ausführen und die ausgegebenen Gruppen mit dem AD abgleichen.

Lösung: Auf v0.47.0 aktualisieren. Der Fehler ist dort behoben, und die Release-Notes zu v0.47.0 empfehlen betroffenen Nutzern das Upgrade ausdrücklich.

16. Der Provider lehnt die Pinniped-CLI als Client ab

Symptom: Bei direkter Anbindung des Concierge an einen externen OIDC-Provider, also ohne Supervisor, weist der Provider den Client zurück.

Ursache: Die Pinniped-CLI arbeitet ausschließlich als Public Client ohne Client-Secret. Provider, die vertrauliche Clients verlangen, akzeptieren das nicht.

Prüfung: kubectl describe jwtauthenticator <name> und ein Test-Login mit PINNIPED_DEBUG=true.

Lösung: Den Supervisor davorschalten, statt den Concierge direkt gegen den Provider zu konfigurieren. Der Supervisor ist genau für diesen Zweck da.

Was diese Liste nicht abdeckt

Die Sammlung behandelt Fehlerbilder, keine Architekturentscheidungen. Ob Sie den Concierge über das Kube-Cluster-Signing-Certificate oder über den Impersonation Proxy betreiben, welche Lebensdauern Pinniped vergibt und warum der Entzug einer Identität nicht sofort wirkt, steht im Hauptbeitrag Kurzlebige Cluster-Logins mit Pinniped unter den Abschnitten zu den Strategien, den Lebensdauern und den Grenzen. Diese Punkte sind keine Fehler, sondern Eigenschaften, die Sie vor dem Rollout kennen sollten.

Sie wollen den Zugang zu Ihren Systemen an echte Identitäten binden, statt an Schlüssel, die nie ablaufen? Ich baue Zugangswege, die zentral steuerbar sind und mit der Sitzung enden. Mehr unter IT-Sicherheit & ISMS, das Erstgespräch ist unverbindlich.

Alex Jabi, Jabi IT

Alex Jabi

Ich betreue IT, Informationssicherheit und Datenschutz für KMU und Praxen an der Bergstraße und im Odenwald, persönlich, dokumentiert und ohne Cloud-Zwang.

Mehr über mich
Zurück zum Blog

Passende Artikel

Alle Artikel »
Wenn der einzige Zugang die Rancher-Shell ist

Wenn der einzige Zugang die Rancher-Shell ist

Kein kubeconfig, kein kubectl von außen, nur die Kubectl-Shell im Browser. Wie man darin sauber arbeitet: Rechte feststellen, Manifeste ohne Datei-Upload anlegen, vor dem Schreiben prüfen und Ergebnisse einsammeln, ohne interaktiv im Cluster herumzustochern.

ArgoCD an Keycloak hängen: SSO für das GitOps-Werkzeug

ArgoCD an Keycloak hängen: SSO für das GitOps-Werkzeug

Vom leeren Keycloak-Realm bis zur Gruppe, die in ArgoCD eine Rolle bekommt. Beide Seiten Schritt für Schritt, mit dem Mapper, an dem es hängt, und vier Stolpersteinen, darunter einer, bei dem eine Verbotsregel wirkungslos bleibt.

Die eigene Registry mit Harbor: scannen, cachen, absichern

Die eigene Registry mit Harbor: scannen, cachen, absichern

Harbor speichert Container-Images nicht nur, es scannt sie mit Trivy und spiegelt fremde Registries als Proxy-Cache. Der Scanner ist dabei nicht im Standard-Setup enthalten, und die Sperre für verwundbare Images greift beim Pull statt beim Push. Aufbau mit Prüfbefehlen und die dokumentierten Fallen.