· Kubernetes  · 8 Min. Lesezeit

Mattermost auf Kubernetes: die vollständige Stolperstein-Sammlung

Fünfzehn dokumentierte Fallen beim Betrieb von Mattermost über den Operator, von hängenden Init-Containern über das Write-Only-Verhalten von spec.size bis zu den Upgrade-Hinweisen aus dem v11-Changelog. Jeder Fall im Schema Symptom, Ursache, Prüfung, Lösung.

Fünfzehn dokumentierte Fallen beim Betrieb von Mattermost über den Operator, von hängenden Init-Containern über das Write-Only-Verhalten von spec.size bis zu den Upgrade-Hinweisen aus dem v11-Changelog. Jeder Fall im Schema Symptom, Ursache, Prüfung, Lösung.

Diese Sammlung ist als Nachschlagewerk gedacht, nicht als Lesestück. Sie richtet sich an alle, die eine Mattermost-Instanz auf Kubernetes erstinstallieren, ein Upgrade planen oder einen Fehler eingrenzen müssen, der sich nicht sofort erklärt. Die Reihenfolge folgt grob dem Lebenszyklus: erst die Fälle rund um Installation und Ressourcen-Definition, dann Filestore und Netzwerk, danach Upgrade und Anmeldung.

Wenn Sie die Instanz noch gar nicht stehen haben, arbeiten Sie zuerst die Anleitung in Mattermost auf Kubernetes: Operator, Datenbank und SSO durch. Dort sind die Kernschritte mit Prüfbefehlen beschrieben, und die drei folgenreichsten der hier gelisteten Fälle sind bereits an der passenden Stelle eingeordnet. Diese Seite wiederholt sie bewusst, damit die Sammlung vollständig bleibt.

1. Der Pod hängt im Init-Status und zieht ein postgres:13-Image

Symptom: Der Mattermost-Pod kommt nicht über Init hinaus. Im Cluster taucht ein Pull für postgres:13 auf, den niemand angefordert hat.

Ursache: Der Readiness-Modus external ist der Default. Er startet einen eigenen Init-Container mit postgres:13 und pg_isready und wertet DB_CONNECTION_CHECK_URL aus. In Umgebungen ohne freien Zugang zur Docker-Registry scheitert dieser Pull.

Prüfung:

kubectl -n mattermost describe pod <pod-name> | grep -A2 'Init Containers'

Lösung: spec.database.readinessCheck.mode: builtin setzen. Dann läuft der Check im Mattermost-Image selbst über mattermost db ping. Voraussetzung ist eine Mattermost-Version, die diesen Befehl mitbringt. Eine konkrete Mindestversion nennt die Doku nicht.

2. spec.size ist nach dem Anwenden leer, eigene Limits sind weg

Symptom: Sie tragen size: 5000users ein, und nach dem apply steht dort nichts mehr. Oder umgekehrt: gesetzte Ressourcen-Limits erscheinen im erzeugten Deployment nicht.

Ursache: Size ist im Operator als Write-Only-Feld dokumentiert, der Wert wird nach dem Setzen der abgeleiteten Werte gelöscht. Umgekehrt überschreiben manuell gesetzte Felder wie replicas oder scheduling.resources die aus size abgeleiteten Werte.

Prüfung:

kubectl -n mattermost get mattermost mattermost-lab -o yaml
kubectl -n mattermost get deploy mattermost-lab -o yaml

Lösung: Entscheiden Sie sich. Entweder size führt die Dimensionierung, oder Sie pflegen die Einzelfelder. Beides gemischt ergibt Werte, die niemand mehr herleiten kann. Zulässig sind laut Typdefinition des Operators genau fünf Werte: 100users, 1000users, 5000users, 10000users und 250000users.

3. Mehr Pods als erwartet, oder das Deployment startet nicht

Symptom: Der Operator erzeugt mehrere Mattermost-Pods, obwohl nur einer geplant war, und es gibt keine Lizenz.

Ursache: spec.size setzt abgeleitete Replica-Zahlen. Ein Deployment mit mehreren Servern verlangt laut Doku eine Enterprise-Lizenz.

Prüfung:

kubectl -n mattermost get mattermost -o jsonpath='{.items[*].spec.replicas}'; echo
kubectl -n mattermost get pods

Lösung: Bei Einzelserver-Betrieb ohne Lizenz replicas: 1 explizit in den spec-Block schreiben. Dieses Feld überschreibt den aus size abgeleiteten Wert.

4. TLS greift nicht, obwohl useIngressTLS gesetzt ist

Symptom: Der Ingress wird erzeugt, aber ohne TLS-Block. Der Browser bekommt kein passendes Zertifikat.

Ursache: useIngressTLS, ingressName und ingressAnnotations sind im Operator deprecated. Aktuell sind spec.ingress.tlsSecret, spec.ingress.host und spec.ingress.annotations.

Prüfung:

kubectl -n mattermost get ingress -o yaml

Im Ergebnis muss ein tls-Block mit dem erwarteten secretName stehen.

Lösung: Auf den spec.ingress-Block umstellen und das TLS-Secret über spec.ingress.tlsSecret referenzieren.

5. Der Filestore lehnt die Zugangsdaten ab, obwohl sie stimmen

Symptom: Uploads scheitern mit Authentifizierungsfehlern. Schlüssel und Secret sehen im Manifest korrekt aus.

Ursache: Das dokumentierte Filestore-Secret nutzt das Feld data, nicht stringData. Werte in data müssen base64-kodiert sein.

Prüfung:

kubectl -n mattermost get secret mattermost-filestore \
  -o jsonpath='{.data.accesskey}' | base64 -d; echo

Lösung: Die Werte vor dem Eintragen kodieren, oder das Secret mit kubectl create secret generic erzeugen und die Kodierung dem Werkzeug überlassen.

6. Der Datenbank-Connection-String ist doppelt kodiert

Symptom: Der Server kommt nicht an die Datenbank, obwohl das Secret angelegt ist und die Zugangsdaten stimmen.

Ursache: Die Doku zeigt den Datenbank-Block unter data. Wer dort bereits base64-kodierte Werte einträgt, die zusätzlich von einem Werkzeug kodiert werden, bekommt einen unbrauchbaren String.

Prüfung:

kubectl -n mattermost get secret mattermost-db-connection \
  -o jsonpath='{.data.DB_CONNECTION_STRING}' | base64 -d; echo

Lösung: Die dekodierte Ausgabe muss eine lesbare postgres://-URL sein. Steht dort erneut Base64, das Secret mit Klartextwerten über kubectl create secret generic neu anlegen oder im Manifest auf stringData wechseln.

7. Dateien verschwinden nach einem Pod-Neustart

Symptom: Angehängte Dateien sind nach einem Neustart nicht mehr abrufbar, oder sie erscheinen nur für einen Teil der Nutzer.

Ursache: Der lokale PVC-basierte Filestore ist im Operator-Quellcode ausdrücklich als nicht für Produktionsumgebungen empfohlen gekennzeichnet.

Prüfung:

kubectl -n mattermost get mattermost mattermost-lab -o jsonpath='{.spec.fileStore}'; echo

Lösung: Einen externen S3-kompatiblen Filestore über spec.fileStore.external mit url, bucket und secret anbinden.

8. Nach dem Upgrade auf v11 startet der Server nicht mehr

Symptom: Der Pod läuft in einen Fehler, die Datenbank wird nicht akzeptiert.

Ursache: Mit v11.0 im Oktober 2025 endete die MySQL-Unterstützung vollständig, und PostgreSQL v13 fiel aus der Unterstützung. Das Minimum ist PostgreSQL 14.

Prüfung:

SELECT version();

Lösung: Vor dem Sprung auf v11 auf PostgreSQL migrieren beziehungsweise die Postgres-Instanz auf mindestens Version 14 heben. Beides gehört in ein eigenes Wartungsfenster, nicht in dasselbe wie das Server-Upgrade.

9. Das Upgrade auf v11.9 läuft ungewöhnlich lange

Symptom: Der Pod scheint beim Start zu hängen, der Rollout kommt nicht weiter.

Ursache: v11.9 entfernt verwaiste Zeilen aus threadmemberships, bei denen der Nutzer kein Kanalmitglied mehr ist. Der v11-Changelog beschreibt das als irreversible, reine Datenmigration, die auf großen Instanzen langsam laufen kann.

Prüfung:

kubectl -n mattermost logs -f <pod-name>

Die Migrationsmeldungen stehen im Startlog.

Lösung: Vorher sichern, ein ausreichendes Wartungsfenster einplanen und den Rollout nicht vorzeitig abbrechen. Ein Abbruch mitten in einer irreversiblen Migration ist der teuerste Weg, Zeit zu sparen.

10. Übersprungene Releases übergehen die Upgrade-Hinweise

Symptom: Ein Sprung über mehrere Versionen läuft technisch durch, aber eine dokumentierte Vorbedingung wurde nicht erfüllt.

Ursache: Die Important Upgrade Notes im v11-Changelog sind verkettet. Zu v11.9 steht dort, dass bei einem Start vor v11.8 auch die übrigen Notes zu lesen sind, zu v11.8 gilt dasselbe für Versionen vor v11.7.

Prüfung:

kubectl -n mattermost get mattermost -o jsonpath='{.items[*].spec.version}'; echo

Lösung: Von der ermittelten Ausgangsversion an alle Upgrade-Notes bis zur Zielversion lesen, nicht nur die der Zielversion. Dasselbe Muster in ausgeprägterer Form beschreibt der Beitrag GitLab über mehrere Versionen upgraden.

11. Nach v11.9 werden funktionierende OAuth-Redirect-URIs abgelehnt

Symptom: Integrationen, die vor dem Upgrade liefen, bekommen ihre Redirect-URI nicht mehr durch.

Ursache: v11.9 ändert das Matching der Redirect-URI-Allowlist für OAuth Dynamic Client Registration. Muster werden jetzt pro URL-Komponente ausgewertet, also getrennt nach Schema, Host, Pfad und Query, statt als Glob über den gesamten String.

Prüfung: Nach dem Upgrade einen Client-Registrierungsflow durchspielen und die Server-Logs auf abgelehnte Redirect-URIs prüfen.

Lösung: Bestehende Allowlist-Muster auf Komponentenbasis neu formulieren.

12. Ein Feld in der System Console ist gesperrt

Symptom: Eine Einstellung lässt sich in der Oberfläche nicht ändern.

Ursache: Per Umgebungsvariable gesetzte Werte haben Vorrang und sind in der System Console nicht editierbar. Auf Kubernetes stammen solche Werte aus spec.mattermostEnv. Der Variablenname leitet sich mechanisch aus dem Pfad in der config.json ab: Präfix MM_, Großbuchstaben, Punkte werden zu Unterstrichen.

Prüfung:

kubectl -n mattermost get mattermost mattermost-lab -o jsonpath='{.spec.mattermostEnv}'; echo

Lösung: Den Wert in der Mattermost-Ressource ändern statt in der Oberfläche, oder die Variable entfernen, wenn die Oberfläche führen soll.

13. Der SSO-Knopf erscheint nicht

Symptom: OpenID Connect ist konfiguriert und gespeichert, die Anmeldeseite zeigt trotzdem nur Benutzername und Passwort.

Ursache: Zwei mögliche Gründe. Die Funktion ist lizenzpflichtig, die Doku zu OpenID Connect listet sie für die Pläne Entry, Professional, Enterprise und Enterprise Advanced. Zusätzlich verlangt die Doku nach dem Speichern einen Serverneustart.

Prüfung:

kubectl -n mattermost get mattermost mattermost-lab -o jsonpath='{.spec.licenseSecret}'; echo

Lösung: Lizenz über spec.licenseSecret einspielen und die Pods neu starten lassen:

kubectl -n mattermost rollout restart deploy mattermost-lab
kubectl -n mattermost rollout status deploy mattermost-lab

14. Der Identity-Provider lehnt die Redirect-URI ab

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

Ursache: Mattermost erwartet ein festes Callback-Format. Abweichende Pfade schlagen fehl.

Prüfung: Den beim Provider hinterlegten Callback mit dem konfigurierten SiteURL abgleichen.

Lösung: Exakt {your-mattermost-url}/signup/openid/complete hinterlegen, mit dem tatsächlichen SiteURL davor. Für eine Instanz unter chat.lab.rz.jabi-it.de also https://chat.lab.rz.jabi-it.de/signup/openid/complete.

15. LDAP-Gruppen kommen über OIDC nicht an

Symptom: Der Login über den Identity-Provider funktioniert, aber erwartete LDAP-Attribute und Gruppen fehlen in Mattermost.

Ursache: LDAP-Daten sind laut Doku nicht mit OpenID kompatibel.

Prüfung: Abgleichen, welche Attribute der Provider im Token liefert und welche davon Mattermost tatsächlich übernimmt.

Lösung: Wenn Sie LDAP-Attribute und Gruppen brauchen, SAML oder LDAP als Login-Provider konfigurieren statt OIDC. Diese Entscheidung gehört vor die Einführung, nicht danach.

Einordnung

Ein Teil dieser Fälle geht auf dasselbe Grundmuster zurück: Der Operator leitet vieles aus wenigen Feldern ab, und wer diese Ableitung mit manuellen Werten mischt, bekommt ein Ergebnis, das sich aus dem Manifest allein nicht mehr erklären lässt. Der andere Teil geht auf Systeme zurück, die gar nicht zu Mattermost gehören: Datenbank, Objektspeicher, Zertifikate und Identity-Provider. Drei davon können den Chat lahmlegen, ohne dass an Mattermost selbst etwas falsch wäre.

Die Installationsanleitung mit den Kernschritten und den Prüfbefehlen nach jedem Schritt steht im Beitrag Mattermost auf Kubernetes: Operator, Datenbank und SSO.

Sie wollen Team-Kommunikation self-hosted, mit einem zentralen Login? Ich betreibe Chat, Identity und die Datenbank als zusammenhängendes, dokumentiertes System. Mehr unter Sichere Kommunikation, 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 »
Mattermost auf Kubernetes: Operator, Datenbank und SSO

Mattermost auf Kubernetes: Operator, Datenbank und SSO

Ein selbst gehosteter Team-Chat als Slack-Alternative, betrieben über den Mattermost-Operator. Voraussetzungen, externe Datenbank und Filestore, die Mattermost-Ressource, Login über OpenID Connect und die drei folgenreichsten Fallen.

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.

Zalando-Postgres-Operator: adoptieren und die PVC-Falle

Zalando-Postgres-Operator: adoptieren und die PVC-Falle

Der Operator löscht PersistentVolumeClaims beim Entfernen des Cluster-Manifests standardmäßig mit, unabhängig von der Retention-Policy des StatefulSets. Welche Schalter Sie vorher setzen, wie weit der eingebaute Löschschutz trägt, und warum es keinen dokumentierten Weg gibt, eine bestehende Instanz einfach zu übernehmen.

Zalando-Postgres-Operator: alle Stolpersteine im Überblick

Zalando-Postgres-Operator: alle Stolpersteine im Überblick

Die vollständige Fallsammlung zum Zalando-Postgres-Operator. Gelöschte PVCs, ein Löschschutz der nicht blockiert, CRD-Konflikte mit ArgoCD, der Registry-Wechsel nach ghcr.io, entfallene Postgres-Versionen und der anstehende Wechsel der Leader-Wahl. Jeder Fall im Schema Symptom, Ursache, Prüfung, Lösung.