K8s 上 DolphinScheduler Master / Worker 反复重启?别让默认 4G 堆撞上 2Gi Limit

适合人群:Kubernetes / k3s / OrbStack 部署 DolphinScheduler 3.2.x,Master 或 Worker 一直 CrashLoop / OOMKilled / 不 Ready
环境:OrbStack Ubuntu + k3s、DolphinScheduler 3.2.2
关键词:DolphinScheduler、OOMKilled、JAVA_OPTS、-Xmx、容器内存


一、现象:节点「活着」,调度却不稳

常见表现有几种,看起来不像同一类问题,根因往往是同一个:

表象

你会怎么猜

真正可能是

Master / Worker Pod OOMKilled

机器内存不够

JVM 堆大于 Pod limit

Pod 反复重启,Ready 一直红

镜像坏了 / 探针太严

启动即被 kubelet 杀

UI「节点不存在」或任务派发不稳

注册中心挂了

进程根本没稳下来

TaskInstanceLogPath is empty

下发逻辑 bug

节点半死不活,派发失败

在本地 k3s / OrbStack 上,很多人会给 Master / Worker 配:

resources:
  limits:
    memory: "2Gi"

而 DolphinScheduler 官方镜像默认 JVM 堆往往偏大(常见接近 4G)。
容器说只能用 2Gi,JVM 一上来就要 4G——这仗必输。


二、根因:容器内存 ≠ JVM 默认堆

2.1 Kubernetes 怎么杀进程?

当容器内存使用超过 limits.memory,kubelet 会:

  1. 记录事件:OOMKilled

  2. 杀掉容器

  3. 按重启策略拉起 → 再撞墙 → CrashLoop

你在 kubectl describe pod 里常会看到:

Last State:     Terminated
Reason:         OOMKilled
Exit Code:      137

2.2 为什么官方默认堆这么大?

物理机 / 大内存虚拟机上,4G 堆很常见;
一进「本地 K8s 最小清单」,大家习惯把 limit 压到 1~2Gi,配置没一起改,就炸了。

一句话:

Pod limit 是硬顶;-Xmx 必须明显小于这个硬顶,还要给元空间、直接内存、线程栈留余量。

经验公式(单进程容器):

-Xmx ≈ limits.memory × 0.6 ~ 0.75

例如 limit=2Gi-Xmx1536m 通常比较稳妥。


三、怎么确认是堆撞墙?

3.1 看事件与退出码

kubectl -n dolphinscheduler describe pod -l component=master | tail -40
kubectl -n dolphinscheduler get pod -l 'component in (master,worker)' -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.containerStatuses[0].lastState.terminated.reason}{"\n"}{end}'

出现 OOMKilled / 137,优先怀疑内存。

3.2 看当前 JAVA_OPTS

kubectl -n dolphinscheduler exec deploy/dolphinscheduler-master -- printenv JAVA_OPTS
kubectl -n dolphinscheduler exec deploy/dolphinscheduler-worker -- printenv JAVA_OPTS

如果没有显式 -Xmx,或仍是很大的默认值,就对上了。

3.3 对照 resources

kubectl -n dolphinscheduler get deploy dolphinscheduler-master dolphinscheduler-worker -o jsonpath='{range .items[*]}{.metadata.name}{" limit="}{.spec.template.spec.containers[0].resources.limits.memory}{"\n"}{end}'

四、修复:显式 JAVA_OPTS + UseContainerSupport

4.1 推荐配置(2Gi limit)

env:
  - name: JAVA_OPTS
    value: >-
      -server
      -Xms512m
      -Xmx1536m
      -XX:+UseContainerSupport
      -Duser.timezone=Asia/Shanghai

要点:

  • -Xms512m:避免启动瞬时申请过大

  • -Xmx1536m:给 2Gi limit 留出余量

  • -XX:+UseContainerSupport:让 JVM 感知 cgroup 限制(JDK 8u191+ / 11+ 常见)

4.2 调参清单(可直接收藏)

  1. 先定 Pod limit(本地开发 2Gi 够用)

  2. 再写 JAVA_OPTS(堆 < limit)

  3. 重启后验证 Ready、无 OOMKilled

4.3 落地到清单

Master / Worker Deployment 都要改(只改一边会出现「半边集群活着」)。
改完后:

kubectl apply -f k8s/dolphinscheduler.yaml
kubectl -n dolphinscheduler rollout restart deploy/dolphinscheduler-master deploy/dolphinscheduler-worker
kubectl -n dolphinscheduler rollout status deploy/dolphinscheduler-master deploy/dolphinscheduler-worker

五、验证:怎样算修好了?

# 1. Pod Ready
kubectl -n dolphinscheduler get pods

# 2. 近期没有 OOMKilled
kubectl -n dolphinscheduler get events --field-selector reason=OOMKilling --sort-by='.lastTimestamp' | tail

# 3. 进程内堆配置生效
kubectl -n dolphinscheduler exec deploy/dolphinscheduler-master -- printenv JAVA_OPTS

期望:

  • Master / Worker 1/1 Running

  • 监控中心节点在线

  • 重新跑工作流可正常下发(若之前还有 DNS 注册问题,需一并修好)


六、和「任务不下发」的关系

堆内存问题经常和另一个坑连环出现

  1. 默认大堆 → OOM / 不 Ready

  2. 节点半死 → 任务派不出去

  3. UI 报 TaskInstanceLogPath is empty

所以排查「不下发」时,请同时问两句:

  • ZK 注册地址能不能解析?(见同系列第一篇)

  • JVM 堆有没有超过 Pod limit?(就是本篇)

两篇合起来,本地 k3s 上大半「节点假活 / 任务不跑」都能覆盖。


七、写在最后

本地 K8s 部署 DolphinScheduler,最容易复制「生产大堆配置」到「玩具级 limit」。
记住:

先看 limits.memory,再写 -Xmx;永远给容器留余量。

如果你的 limit 是 1Gi,就把 -Xmx 降到 512m~768m,并同步下调 readiness 的启动等待预期——小堆冷启动往往更快,但不代表业务并发能力够用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值