K8S 中实现程序 OOM 后 dump 上传到阿里云 OSS (一)
背景
在日常工作中发现,JAVA 程序部署在 K8S 上后,若发生 OOM,程序生成的 dump 文件在 Pod 重启后会丢失,无法给开发人员分析起原因,造成了很多不便。
方案考虑
经过上网查询资料,思考,大概列出了下面这几种方式:
- 使用 hostPath,把 dump 挂在宿主机上。 --- 主要排除因素:K8S 节点有多个,不好管理
- 使用阿里云 NAS 挂载 pod 的 dump 目录。 --- 主要排除因素:每个 pod 都要挂一个目录,不好管理,引入了额外的开销
- 构建 JAVA 程序镜像时,配置 java 命令参数 -XX:OnOutOfMemoryError=/dumpError.sh,OOM 发生时调用 dumpError.sh 脚本,上传。 --- 改动少,只需要修改基础镜像即可,但实际测试时,发现 dump 没上传完成,POD 就重启了, 只能放弃
- 在 K8S 中使用 Sidecar,让 POD 中包含2个容器,并且共享 dump 所在目录,OOM时让 sidecar 容器进行 dump 上传,主容器重启也不影响。 --- 本次选择这个方案
编写 dump 上传到阿里云 OSS 的程序
该程序采用go语言编写,原因是 go 语句可以直接编译成可在Linux系统直接运行的程序,不依赖其他额外的软件环境。
可以参考阿里云的文档:https://help.aliyun.com/zh/oss/user-guide/multipart-upload?spm=5176.8466032.console-base_help.dexternal.500614501X6Zj7#12bca60a3dshn
注意!要记得创建 OSS 的 bucket 和配置对应的 RAM 的权限~
程序我是采用 Trae ,让它来帮我写,测试通过后,让他帮编译成Linux系统可运行的程序。

制作 Sidecar 镜像
我这里上一步生成的可执行程序是:traeAliOSS
mkdir -p /data/images/alpine-ossutil
cd /data/images/alpine-ossutil
# 上传 traeAliOSS 到该目录下
# 下面是检测和调用 traeAliOSS 程序上传 dump 的脚本,简单说明一下功能
# 判断 /tmp/ 目录下是否有 dump 且没有带时间的?
# 有:则重命名,在后面加上时间,并上传;
# 无:则继续循环。
cat dumpError.sh
#!/bin/sh
# 每分钟执行一次检查
while true; do
# 查找 /tmp 目录下所有 .dump 文件
for file in /tmp/*.dump; do
# 跳过不存在的文件(当没有.dump文件时,循环会进入一次)
[ -e "$file" ] || continue
# 提取文件名(不含路径)
filename=$(basename "$file")
# 检查文件名是否已包含时间戳格式(-YYYYMMDD_HHMM)
if echo "$filename" | grep -qE '.*-[0-9]{8}_[0-9]{4}\.dump$'; then
# 文件名已包含时间戳,跳过处理
continue
else
# 文件名不包含时间戳,需要处理
# 获取文件基本名(不含扩展名)
base_name=$(echo "$filename" | sed 's/\.dump$//')
# 生成时间戳(格式:年月日_时分)
timestamp=$(date +%Y%m%d_%H%M)
# 新文件名
new_name="/tmp/${base_name}-${timestamp}.dump"
# 重命名文件
mv "$file" "$new_name"
# 上传文件, 需要通过环境变了获取 ALI_OSS_BUCKET,即是 阿里云 Bucket 的值
traeAliOSS -bucket "$ALI_OSS_BUCKET" -file "$new_name" -object "$(basename "$new_name")" > /tmp/traeAliOSS.log 2>&1
fi
done
# 等待60秒
sleep 60
done
chmod +x dumpError.sh
chmod +x traeAliOSS
# 编写 Dockerfile ,因为要用到 https 证书信任链,所以要安装 ca-certificates 软件
cat Dockerfile
FROM alpine:3.23.2
RUN apk add --no-cache ca-certificates
ADD traeAliOSS /usr/bin/traeAliOSS
ADD dumpError.sh /dumpError.sh
CMD /dumpError.sh
现在目录的情况:

# 制作镜像并上传
# 根据自身情况进行调整:
docker build -t harbor.klvchen.com/library/alpine-ossutil:0.1
docker push harbor.klvchen.com/library/alpine-ossutil:0.1

浙公网安备 33010602011771号