Kubernetes-Installation (Helm)
Für den Betrieb der PlantPulse-Plattform in Kubernetes steht ein Helm-Chart zur Verfügung.
Bis zum Data Lake wurde mit diesem Chart eine saubere Installation durchgeführt und bestätigt (2026-09-09, 19/19 Dienste, keine Privilegien).
Die Punkte server · batch · warehouse · proxy sind jedoch noch nicht in der Praxis geprüft worden.
Verwenden Sie für Kundeninstallationen die Einzeileninstallation oder die Docker-Installation.
Was ist das?
Dieses Chart ist eine Übersetzung der Docker-Compose-Konfiguration nach Kubernetes. Es ist kein Ersatz.
Die maßgebliche Version bleibt weiterhin Compose. Wenn beide voneinander abweichen, hat Compose recht und das Chart ist falsch. Neue Einstellungen werden zuerst in Compose aufgenommen und das Chart folgt.
| Chart-Speicherort | plantpulse-platform-k8s-Repository unter charts/plantpulse-platform |
| Image-Registry | Plattform unter docker.kopens.io/pp, Drittanbieter unter docker.kopens.io/proxy-dockerhub |
| Testumgebung | k3s v1.32.5+k3s1 · Einzelner Knoten |
| Behandelte Compose-Dienste | Alle 10 |
Vor der Installation
Kubernetes-Version
Dieses Betriebssystem verwendet cgroup v1, und k3s v1.36 (Kubernetes 1.36) hat die Unterstützung für cgroup v1 entfernt. Beim Upgrade meldet kubelet dies und startet nicht.
kubelet is configured to not run on a host using cgroup v1
Speicher — RWX ist erforderlich
An das pp-security-Volume für das TLS-Material werden mehrere Pods gleichzeitig angeschlossen. Daher
ist ein Provisioner erforderlich, der ReadWriteMany unterstützt — z. B. NFS, CephFS, Longhorn RWX.
local-path von k3s funktioniert nur bei einem einzelnen Knotenlocal-path ist RWO und lokal am Knoten. Bei einem einzelnen Knoten laufen alle Pods auf diesem Knoten, daher
funktioniert es. Aber sobald ein zweiter Knoten hinzukommt, bricht es still. Dies ist kein Fehler des Charts, sondern eine reale Einschränkung,
die hier festgehalten wird, damit sie nicht erst bei einer Kundeninstallation entdeckt wird.
Ressourcen
Die Ressourcenanforderungen der Plattform reduzieren sich durch Kubernetes nicht. Es gelten die Systemanforderungen unverändert — mindestens 16 vCPU · 128 GB RAM · 1 TB SSD.
Wenn kein Cluster vorhanden ist — K3s → Rancher → Helm
Wenn Sie bereits Kubernetes nutzen, überspringen Sie diesen Abschnitt und gehen Sie zu Installation. Wenn Sie ohne Cluster starten, ist der kürzeste Weg: K3s für den Cluster, Rancher für die Benutzeroberfläche, und darauf das PlantPulse-Chart installieren.
Es ist eine Open-Source-Kubernetes-Verwaltungsoberfläche von SUSE. Optional, und kubectl allein reicht
für Installation und Betrieb vollständig aus. Es ist praktisch, wenn Sie Pods, Protokolle und Ereignisse visuell sehen möchten, daher wird es hier erwähnt.
1. K3s-Installation
Dies ist ein Ein-Knoten-Cluster. Das Installationsskript richtet Container-Runtime, kubelet und den Standard-
Speicher (local-path) mit ein.
# Oracle Linux 8.10 은 cgroup v1 이라 v1.32 라인을 고정합니다 (위 경고 참고)
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.32.5+k3s1 sh -
sudo systemctl status k3s # active (running)
sudo k3s kubectl get nodes # STATUS = Ready
Um kubectl mit einem normalen Benutzerkonto zu verwenden, kopieren Sie die kubeconfig.
mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown "$(id -u):$(id -g)" ~/.kube/config
kubectl get nodes
K3s verwendet 6443 (API). Wenn Sie weitere Knoten hinzufügen möchten, sind auch 8472/udp (Flannel VXLAN) · 10250 (kubelet) zwischen den Knoten erforderlich. Die von der Plattform selbst verwendeten Ports finden Sie unter Portkonfiguration.
2. Rancher-Installation
Rancher benötigt ein Zertifikat, daher wird zuerst cert-manager installiert.
helm repo add rancher-stable https://releases.rancher.com/server-charts/stable
helm repo add jetstack https://charts.jetstack.io
helm repo update
# 1) cert-manager
helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set crds.enabled=true
kubectl -n cert-manager rollout status deploy/cert-manager
# 2) Rancher — <호스트> 는 브라우저로 칠 주소입니다
helm install rancher rancher-stable/rancher --namespace cattle-system --create-namespace --set hostname=<호스트> --set bootstrapPassword=<초기비밀번호> --set replicas=1
kubectl -n cattle-system rollout status deploy/rancher
Rufen Sie https://<호스트> im Browser auf und melden Sie sich zum ersten Mal mit dem oben vorbereiteten bootstrapPassword an.
Ändern Sie sofort das Passwort. Nach der Anmeldung wird dieser K3s-Cluster als local erkannt.
Rancher erstellt Zertifikate basierend auf hostname. Wenn Sie den Zugriff über eine IP planen, geben Sie diese IP direkt
in hostname ein und akzeptieren Sie die Warnung des Browsers zum selbstsignierten Zertifikat.
3. PlantPulse-Installation
Ab hier ist es gleich, ob Sie kubectl oder die Rancher-Oberfläche verwenden. Folgen Sie dem Abschnitt Installation unten.
Wenn Sie Rancher verwenden, können Sie das Chart-Repository unter Apps → Charts → Repositories registrieren und von dort installieren.
Für die Arbeit mit Wertdateien ist jedoch der helm-Befehl besser geeignet.
Wo Rancher wirklich hilft, ist nach der Installation — Sie sehen auf einer Oberfläche, wo die Init-Phase eines Pods wartet, was die Protokolle aussagen und welche Ereignisse abgelehnt wurden. Besonders beim Lesen von Startreihenfolge ist das hilfreich.
Installation
1. Geheimnisse als Secret anlegen
Das Chart enthält keine einzige Zeile mit einem Passwort. Auch nicht in values.yaml, und in der Standardkonfiguration
erstellt das Chart kein Secret — es referenziert nur bereits vorhandene.
Die maßgebliche Datei ist die gleiche Sidecar-Datei wie bei Compose. Sie wird bytegenau übernommen.
kubectl -n plantpulse create secret generic plantpulse-platform-env \
--from-env-file=/etc/kopens/plantpulse-platform.env
2. Installation durchführen
helm install pp charts/plantpulse-platform -n plantpulse --create-namespace
Die Standard-Registries (docker.kopens.io/pp · docker.kopens.io/pd) sind öffentlich und daher von überall erreichbar.
Für die normale Installation ist also kein --set erforderlich.
3. Wenn Sie in eine private Registry gespiegelt haben
helm install pp charts/plantpulse-platform -n plantpulse --create-namespace \
--set global.image.registry=<사설 레지스트리>/pp \
--set global.image.registryDatalake=<사설 레지스트리>/pd \
--set global.image.registryThirdParty=<사설 레지스트리>/proxy-dockerhub \
--set global.imagePullSecrets[0].name=<레지스트리 시크릿>
registryThirdParty nicht ausWenn Sie nur die ersten beiden abdecken, kann das Busybox-Image für die Startreihenfolge-Warteschleife nicht abgerufen werden.
Dadurch warten alle abhängigen Pods endlos in Init:0/1, und dieser Fehler sieht nicht wie ein Registry-Problem aus.
Startreihenfolge — Kubernetes beachtet sie nicht
Die Plattform hat eine einzuhaltende Reihenfolge.
certs → datalake → server → batch
→ warehouse · opcua · aasx · ha
server → proxy
Das Äquivalent zu depends_on aus Compose gibt es in Kubernetes nicht. Die oft als Ersatz genannten
Mittel bewirken alle etwas anderes.
| Häufig genannt | Was es tatsächlich tut |
|---|---|
readinessProbe | Blockiert den Datenverkehr zu diesem Pod. Kann den Start anderer Pods nicht verzögern |
StatefulSet | Reihenfolge von Pods innerhalb desselben StatefulSets. Unabhängig von anderen Workloads |
Helm-Hook · --wait | Reihenfolge der Manifest-Anwendung. Nicht der Bereitschaftszustand erstellter Ressourcen |
Deshalb platziert das Chart die Warteschleife dort, wo Kubernetes tatsächlich blockiert — initContainer. Die Warteschleife prüft nicht „Ist der Pod gestartet?", sondern „Ist das Artefakt vorhanden?".
Init:0/2 ist kein FehlerEs bedeutet, dass das Chart funktioniert. Fragen Sie, worauf es wartet.
kubectl -n plantpulse logs <파드> -c wait-for-certs
Das Standard-Timeout beträgt 1800 Sekunden, geprüft wird alle 5 Sekunden. Nach Ablauf wird die Warteschleife beendet und kubelet startet den Pod neu — damit der Grund im Pod-Ereignisprotokoll bleibt. Bei einer dauerhaften Blockade bleibt nichts erhalten.
Die Reihenfolge «innerhalb» der Container wird vom Chart nicht beeinflusst. Die Startreihenfolge im Data Lake wird von
pd innerhalb des Containers erzwungen. Wenn das Chart dies erneut implementiert, gäbe es zwei maßgebliche Versionen, die auseinanderlaufen.
Wenn der Proxy 502 antwortet
Das Docker-Netzwerk leitet alle Ports eines Containers weiter, aber der Kubernetes-Dienst leitet nur die «selbst deklarierten Ports» weiter. Hier ist der Weg, auf dem ein in Compose funktionierender Upstream in Kubernetes zu 502 führt.
Das Chart enthält einen Gate zur Erkennung — er prüft, ob alle Proxy-Upstreams auf «den vom Chart erstellten Dienst und dessen deklarierten Port» zeigen.
bash hack/run-gates.sh
| Gate | Prüft |
|---|---|
gate-render.sh | Ob Proxy-Upstreams im gerenderten Ergebnis auf existierende Dienste und Ports zeigen |
gate-no-plaintext-secrets.sh | Ob Klartext-Geheimnisse im gerenderten Ergebnis enthalten sind |
prove-gates-fail.sh | Ob der Gate «tatsächlich fehlschlägt, wenn er fehlschlagen muss» (Gate des Gates) |
Führen Sie es vor der Installation aus und lassen Sie es durchlaufen. Die meisten 502-Fehler werden hier zuerst erkannt.
Wie groß muss ein Knoten sein
🔴 Die Summe der vom Chart deklarierten requests entspricht dem Knotenbedarf. Wenn dies nicht ausreicht, starten Pods nicht und
bleiben in Pending — die erste Ursache für den Eindruck, die „Installation sei hängen geblieben".
| Workload | CPU-Anforderung | Speicheranforderung | Speicherlimit |
|---|---|---|---|
datalake | 8 | 64 Gi | 64 Gi |
server | 2 | 12 Gi | 16 Gi |
batch | 1 | 6 Gi | 8 Gi |
warehouse | 1 | 4 Gi | 8 Gi |
opcua · aasx | jeweils 0.5 | jeweils 2 Gi | jeweils 4 Gi |
ha | 0.5 | 1 Gi | 4 Gi |
proxy | 0.2 | 256 Mi | 1 Gi |
certs | 0.1 | 256 Mi | 1 Gi |
| Summe (Standardkonfiguration) | ca. 14 | ca. 92 Gi | — |
Allein datalake fordert CPU 8 · Speicher 64 Gi an (Anforderung und Limit sind gleich —
es ist als Guaranteed konfiguriert). Für einen einzelnen Knoten muss dieser Knoten also mindestens
CPU 16 · Speicher 128 Gi haben.
JVM-Heap wird «separat» vom Pod-Limit deklariert
Für die Java-Anwendungen wird die Heap-Größe direkt vom Chart übergeben. Sie wird nicht vom Pod-Limit abgeleitet — würde sie abgeleitet, würde die Heap-Größe beim Reduzieren des Limits stillschweigend sinken, während tatsächlich das Literal im Image Vorrang hat. Das JVM wüsste nichts von einer Änderung des Limits in eine Richtung.
| App | Heap | Direkt | Übergebene Variable |
|---|---|---|---|
server | 8g | 4g | PP_SERVER_HEAP · PP_SERVER_DIRECT |
batch | 3g | — | PP_BATCH_HEAP |
warehouse | 1g | — | PP_WAREHOUSE_HEAP |
Beim Rendern stellt das Chart Folgendes sicher. Bei Verstoß schlägt die Installation sofort fehl.
힙 + 다이렉트 + 여유(기본 2048Mi) ≤ limits.memory
힙 + 여유 ≤ requests.memory
🔴 Wenn Sie nur den Heap erhöhen, ohne das Pod-Limit anzupassen, kommt es während des Vorwärmens zu einem OOMKill. -Xms=-Xmx
verwendet AlwaysPreTouch, sodass der Heap sofort beim Start vollständig belegt ist. Zu diesem Zeitpunkt enthält das Protokoll keine Zeile,
die auf den Heap hindeutet. Erhöhen Sie beide zusammen.
Was wurde bisher verifiziert
Die Testumgebung ist k3s v1.32.5+k3s1 · Einzelner Knoten, alles mit echten Registry-Images.
| Komponente | Status |
|---|---|
plantpulse-certs | ✅ Bereit. TLS-Material wurde tatsächlich auf dem gemeinsamen Volume erstellt |
plantpulse-datalake | ✅ Saubere Installation mit diesem Chart, 19/19 Dienste gestartet (2026-09-09, 2026.09-Image, nach Löschen des PVC) |
| Startreihenfolge-Warteschleife | ✅ Blockade und Freigabe in der Praxis bestätigt |
server · batch · warehouse · proxy | ⬜ Noch kein Protokoll eines Starts vorhanden — Chart-Fehler werden jedoch weiterhin behoben (2026-09-09: Backup-Volume · JVM-Heap-Vertrag · Proxy-Upstream) |
opcua · aasx · ha | ⬜ Nur bis zum Wartezustand geprüft |
mirror-maker | Standardmäßig deaktiviert (entspricht dem mirror-Profil in Compose) |
Data-Lake-Pods starten jetzt ohne Privilegien — mit dem Entfernen von systemd als PID 1 im Image sind
privileged · SYS_ADMIN · cgroup:host alle unnötig geworden.
TOTAL SERVICES : 19 RUNNING / 0 STOPPED
/proc/1/comm : bash # systemd 아님
securityContext: (비어 있음) # privileged·SYS_ADMIN·cgroup 없음
Ob die server → batch → warehouse → proxy-Reihenfolge in der Praxis eingehalten wird, hat noch niemand bis zu diesem Punkt geprüft.
Das bedeutet nicht, dass das Chart nicht verbessert wird. Am 2026-09-09 wurde ein Satz von Fehlern auf App-Ebene behoben — das Backup-Volume wurde nicht am Server gemountet, die JVM-Heap-Größe war unter Kubernetes nicht konfigurierbar, die sieben Proxy-Upstreams entsprachen exakt dem Docker-Layout. Alle drei wurden jedoch durch Rendering-Abgleich und Code-Analyse gefunden, nicht durch tatsächliches Starten von Pods. „Behoben" und „startet in diesem Chart" sind unterschiedliche Tatsachen. Verwenden Sie für Kundeninstallationen die Einzeileninstallation oder die Docker-Installation.
Bei Problemen
| Symptom | Zuerst prüfen |
|---|---|
Pod bleibt in Init:0/1 hängen | Möglicherweise kann das Busybox-Image nicht abgerufen werden — registryThirdParty prüfen |
Pod wartet in Init:0/2 | Normal. Prüfen Sie mit kubectl logs <파드> -c wait-for-certs, worauf gewartet wird |
| Proxy-Pfad liefert 502 | bash hack/run-gates.sh — Zeigt der Upstream auf einen existierenden Dienst und Port? |
| TLS-bezogene Fehler nach Hinzufügen eines zweiten Knotens | pp-security ist nicht RWX |
| Liste in der Warehouse-Konsole ist immer leer | Erforderliche Iceberg-Einstellungen sind leer. Leere Werte führen zum Fehler beim Rendern, daher Installationsprotokoll prüfen |
Verwandte Dokumente
- Einzeileninstallation — derzeit empfohlene Installationsmethode
- Docker-Installation — detailliertes Verfahren auf Compose-Basis
- Systemanforderungen — Ressourcenanforderungen sind identisch
- Cluster-Installation — horizontale Skalierung von Master und Worker