跳到主要内容

Kubernetes 安装 (Helm)

PlantPulse 平台有一个 用于在 Kubernetes 上运行的 Helm Chart。

整个堆栈尚未完全验证

数据湖部分已通过此 Chart 进行全新安装并确认正常(2026-09-09,服务 19/19,无特权)。 但是 server · batch · warehouse · proxy 尚未实际运行验证过。

客户现场安装请使用 单线安装 或 Docker 安装 。

这是什么​

这是一个将 Docker Compose 配置 翻译成 Kubernetes 的 Chart,而不是替代方案。

权威版本仍然是 compose。如果两者不一致,以 compose 为准,Chart 是错误的。 新配置会先添加到 compose,Chart 随后跟进。

Chart 位置plantpulse-platform-k8s 仓库中的 charts/plantpulse-platform
镜像仓库平台使用 docker.kopens.io/pp,第三方使用 docker.kopens.io/proxy-dockerhub
验证环境k3s v1.32.5+k3s1 · 单节点
涉及的 compose 服务全部 10 个

开始之前​

Kubernetes 版本​

如果是 Oracle Linux 8.10,则 k3s 必须使用 v1.32 系列

该操作系统使用 cgroup v1,而 k3s v1.36(Kubernetes 1.36)已移除对 cgroup v1 的支持。 升级后 kubelet 会报如下错误并无法启动。

kubelet is configured to not run on a host using cgroup v1

存储 — 需要 RWX​

承载 TLS 材料的 pp-security 卷会被 多个 Pod 同时挂载。因此需要有支持 ReadWriteMany 的 Provisioner — 例如 NFS · CephFS · Longhorn RWX 等。

k3s 默认的 local-path 仅在单节点时有效

local-path 是 RWO 且位于节点本地。在单节点环境下,所有 Pod 都部署在该节点上, 因此可以工作,但 一旦加入第二个节点,就会悄无声息地出问题。 这不是 Chart 的缺陷,而是实际的限制, 在此记录,以免在客户现场部署时才发现。

资源​

平台资源需求不会因为使用 Kubernetes 而减少。 请遵循 系统要求 — 最低 16 vCPU · 128GB RAM · 1TB SSD 。


如果没有集群 — K3s → Rancher → Helm​

如果您已经使用 Kubernetes,请跳过本节,直接进入 安装。 如果从零开始,则 K3s 创建集群,Rancher 提供界面, 再在其上部署 PlantPulse Chart,这是最短路径。

Rancher 不是我们的产品

这是 SUSE 的开源 Kubernetes 管理 UI。可选组件,仅使用 kubectl 也能完全完成 安装和运维。当您想直观查看 Pod·日志·事件时,使用它会很方便,因此一并介绍。

1. 安装 K3s​

这是一个单节点集群。安装脚本会一并启动容器运行时 · kubelet · 默认 存储(local-path)。

# 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

要在普通账户下使用 kubectl,请复制 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 使用 6443(API)端口。如果打算加入其他节点,还需要节点之间的 8472/udp(flannel VXLAN) · 10250(kubelet)端口。 平台自身使用的端口见 端口配置 。

2. 安装 Rancher​

Rancher 需要证书,因此先部署 cert-manager。

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

在浏览器中访问 https://<호스트>,使用上面准备的 bootstrapPassword 进行首次登录, 并立即更改密码。登录后,此 K3s 集群会被识别为 local。

如果是私有网络,请先确定主机名

Rancher 使用 hostname 创建证书。如果计划用 IP 访问,请将该 IP 直接填入 hostname,并接受浏览器对自签名证书的警告。

3. 安装 PlantPulse​

从这里开始,无论是使用 kubectl 还是在 Rancher 界面操作,都是一样的。请严格按照下面的 安装 部分 执行。如果使用 Rancher,也可以将 Chart 仓库注册到 Apps → Charts → Repositories 并通过界面安装, 但处理值文件时,使用 helm 命令更好。

Rancher 真正有用的是安装之后 — 可以在一屏上查看 Pod 的 Init 阶段在哪里等待、 日志显示了什么、事件拒绝了什么。阅读启动顺序时尤其如此。


安装​

1. 将机密信息创建为 Secret​

Chart 不包含任何一行密码。 values.yaml 中也没有,而且在默认配置下, Chart 不会创建 Secret — 它只引用已有的 Secret。

权威版本是与 compose 相同的 sidecar 文件。逐字节使用相同内容。

kubectl -n plantpulse create secret generic plantpulse-platform-env \
--from-env-file=/etc/kopens/plantpulse-platform.env

2. 安装​

helm install pp charts/plantpulse-platform -n plantpulse --create-namespace

默认仓库(docker.kopens.io/pp · docker.kopens.io/pd)是公开的,外部也可以拉取。 因此,通常安装时不需要 --set。

3. 如果已镜像到私有仓库​

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

只覆盖前面两个镜像会导致 无法拉取用于启动顺序等待的 busybox。这样,依赖它的 Pod 将全部 在 Init:0/1 中永远等待,而这种失败看起来不像仓库问题。


启动顺序 — Kubernetes 不会自动保证​

平台有必须遵守的顺序。

certs → datalake → server → batch
→ warehouse · opcua · aasx · ha
server → proxy

Kubernetes 中没有与 compose 的 depends_on 相对应的机制。通常认为可以替代的方案 做的都是其他事情。

常用方案实际作用
readinessProbe阻止流向该 Pod 的流量。无法延迟其他 Pod 的启动
StatefulSet是同一个 StatefulSet 内部的 Pod 顺序。与其他工作负载无关
Helm hook · --wait是清单应用的顺序。不是已创建对象的就绪状态

因此,Chart 将等待逻辑放在 Kubernetes 真正能阻止的地方 — initContainer。 等待的不是「Pod 是否已启动」,而是 「产出物是否存在」。

Init:0/2 不是故障

这表示 Chart 正在运行。请询问它在等待什么。

kubectl -n plantpulse logs <파드> -c wait-for-certs

默认等待超时为 1800 秒,每 5 秒检查一次。超过超时后,等待会结束,kubelet 会 重新启动它 — 目的是让原因保留在 Pod 事件中。如果永远阻塞,则不会留下任何信息。

容器«内部»的顺序,Chart 不会干预。 数据湖内部的启动顺序由 pd 在容器内强制执行。如果 Chart 重新实现它,就会产生两个权威版本并导致分裂。


如果代理返回 502​

Docker 网络会转发容器的所有端口,但 Kubernetes Service 只转发 «自己声明的 端口»。 在 compose 中正常的 upstream,在 Kubernetes 中变成 502 的路径就在这里。

Chart 中有一个 Gate 来捕获此问题 — 检查所有代理 upstream 是否指向 «此 Chart 创建的 Service 的、 该 Service 已声明的端口»。

bash hack/run-gates.sh
Gate检查内容
gate-render.sh渲染结果中的代理 upstream 是否为真实存在的 Service · 端口
gate-no-plaintext-secrets.sh渲染结果中是否混入了明文机密
prove-gates-fail.shGate 是否在«应该失败时确实失败»(Gate 的 Gate)

在安装前运行并通过。502 的大部分问题会在这里被先行捕获。


节点需要多大​

🔴 Chart 声明的 requests 之和就是节点需求。 不足时 Pod 不会启动,而是停留在 Pending 状态 — 这是「看起来安装卡住了」的首要原因。

工作负载CPU 请求内存请求内存上限
datalake864 Gi64 Gi
server212 Gi16 Gi
batch16 Gi8 Gi
warehouse14 Gi8 Gi
opcua · aasx各 0.5各 2 Gi各 4 Gi
ha0.51 Gi4 Gi
proxy0.2256 Mi1 Gi
certs0.1256 Mi1 Gi
合计(默认配置)约 14约 92 Gi—
数据湖占了绝大部分

仅 datalake 就请求 CPU 8 · 内存 64 Gi(请求与上限相同 — 已设置为 Guaranteed)。如果要部署在单节点上,该节点必须至少具备 CPU 16 · 内存 128 Gi 的规格。

JVM 堆与 Pod 限制是«分开»声明的​

Java 应用套件的堆大小由 Chart 直接传递。它不是从 Pod 限制推导的 — 如果推导,则在降低限制时堆会静默缩小,而实际上镜像内的字面量会覆盖设置,导致无论怎么调整限制, JVM 都不知道。

应用堆直接内存相关变量
server8g4gPP_SERVER_HEAP · PP_SERVER_DIRECT
batch3g—PP_BATCH_HEAP
warehouse1g—PP_WAREHOUSE_HEAP

Chart 在渲染时会断言以下内容。如果违反,安装会立即失败。

힙 + 다이렉트 + 여유(기본 2048Mi) ≤ limits.memory
힙 + 여유 ≤ requests.memory

🔴 只增大堆而不提高 Pod 限制,会导致预触达期间 OOMKill。 -Xms=-Xmx 中 有 AlwaysPreTouch,堆会在启动时立即全部驻留,而此时代码不会留下指向堆的日志行。请同时提高两者。


目前验证到哪个阶段了​

验证环境是 k3s v1.32.5+k3s1 · 单节点,并且全部使用真实仓库镜像。

组件状态
plantpulse-certs✅ 就绪。TLS 材料已实际创建在共享卷上
plantpulse-datalake✅ 通过此 Chart 全新安装,19/19 启动(2026-09-09,2026.09 镜像,删除 PVC 后)
启动顺序等待✅ 已实际验证阻塞和解除
server · batch · warehouse · proxy⬜ 尚无实际启动记录 — 但 Chart 侧的缺陷仍在持续修复中(2026-09-09:备份卷 · JVM 堆约定 · 代理 upstream)
opcua · aasx · ha⬜ 仅确认到等待状态
mirror-maker默认关闭(对应 compose 的 mirror profile)

数据湖 Pod 现在可以无特权启动 — 由于镜像中 systemd 已从 PID 1 移除, privileged · SYS_ADMIN · cgroup:host 都不再需要。

TOTAL SERVICES : 19 RUNNING / 0 STOPPED
/proc/1/comm : bash # systemd 아님
securityContext: (비어 있음) # privileged·SYS_ADMIN·cgroup 없음
剩余的关卡

server → batch → warehouse → proxy 顺序是否被实际遵守,还没有人验证到那一步。

这并不意味着「没有在修复 Chart」。2026-09-09 修复了应用层的一组缺陷 — 备份卷未挂载到服务器、JVM 堆在 Kubernetes 中无法配置、代理 upstream 七个仍保持 Docker 形态。 但这些都是通过渲染对比和代码发现的,并未实际启动 Pod 验证。 「已修复」与「在此 Chart 中能启动」是不同的事实。客户现场安装请使用 单线安装 或 Docker 安装 。


遇到阻塞时​

症状首先检查
Pod 在 Init:0/1 中无进展可能是无法拉取 busybox — 检查 registryThirdParty
Pod 在 Init:0/2 中等待正常。使用 kubectl logs <파드> -c wait-for-certs 查看它在等待什么
代理路径返回 502bash hack/run-gates.sh — upstream 是否指向真实存在的 Service·端口
加入第二个节点后出现 TLS 相关错误pp-security 不是 RWX
数据仓库控制台的列表始终为空Iceberg 相关必需配置为空。空值会导致渲染失败,请查看安装日志

相关文档​