当 core dump 过大时如何压缩并上传至对象存储

解读

国内线上容器普遍启用 core dump 便于定位段错误,但 Kubernetes 默认把 core 文件写到宿主机 /var/lib/kubelet/pods/*/volumes/* 或容器层内,单文件超过 GiB 级 时直接 kubectl cp 会拖慢节点甚至触发磁盘 eviction。面试官想看你是否:

  1. 能在 容器视角 快速截断、压缩、校验;
  2. 熟悉 国内云厂商 OSS/COS/OBS 的 multipart/STS 上传;
  3. 兼顾 敏感信息脱敏自动化闭环(CI/CD、告警、清理)。

知识点

  • Linux core_pattern 管道模式:把 core 直接重定向到用户态脚本,避免落盘。
  • Docker 单进程文件系统限制:overlayfs 写大文件触发 copy-up 性能陷阱。
  • 多阶段压缩lz4 追求速度、zstd 平衡压缩率与 CPU、pigz 多线程。
  • 国内云对象存储 multipart 规则:阿里云 OSS 分片 ≤10000、最小 100 KB;腾讯云 COS 支持 32 并发、单分片 5 GB。
  • RAMFS/TMPFS 临时卷emptyDir.medium=Memorykubelet 预留内存 足够时可行。
  • Docker 非 root 运行与 CAP_SYS_PTRACE:core 收集脚本需具备 CAP_DAC_READ_SEARCH
  • 安全:core 含堆内存明文密钥,需 AES-256-GCM 客户端加密或 OSS 服务端加密 KMS-OSS
  • 成本治理:生命周期规则 3 天转低频、7 天转归档、30 天删除

答案

  1. 改造 core_pattern
    在宿主机 /etc/sysctl.d/90-core.conf 写入:
    kernel.core_pattern=|/usr/local/bin/core_pipe %E %p %t
    容器内如需独立 core,可在 ENTRYPOINT 脚本里执行 echo '/tmp/core.%e.%p' > /proc/self/core_pattern,但须 privilegedCAP_SYS_ADMIN,生产环境建议统一宿主机收集。

  2. core_pipe 脚本(宿主机视角)

    #!/bin/bash
    # $1=可执行路径 $2=pid $3=timestamp
    CORE_TMP=$(mktemp -p /var/cores --suffix=.core)
    cat > "$CORE_TMP"          # 从 stdin 读入 core
    lz4 -z -9 -q "$CORE_TMP" "${CORE_TMP}.lz4"
    SIZE=$(stat -c%s "${CORE_TMP}.lz4")
    # 计算 SHA256
    SHA=$(sha256sum "${CORE_TMP}.lz4" | awk '{print $1}')
    # 使用阿里云 OSSUTIL
    ossutil64 cp "${CORE_TMP}.lz4" \
         oss://prod-dump-cores/$(hostname)/$(date +%F)/$SHA.core.lz4 \
         --meta "x-oss-object-acl:private" \
         --tagging "env=prod&app=$1"
    # 回调
    curl -X POST http://alerta.internal/core -d "host=$(hostname)&size=$SIZE&sha=$SHA"
    rm -f "$CORE_TMP" "${CORE_TMP}.lz4"
    

    该脚本常驻宿主机,不依赖容器内工具,避免镜像膨胀。

  3. 纯容器侧方案(无宿主机权限时)

    • 在 Dockerfile 中引入 zstd + ossutil 二进制(合计 <10 MB)。
    • 启动脚本预设 ulimit -c unlimited,并把 core 目录挂到 emptyDir 卷:
      volumes:
      - name: coredump
        emptyDir:
          medium: Memory
          sizeLimit: 2Gi
      
    • 应用崩溃后,由 sidecar 容器 运行:
      zstd -19 -T0 /coredump/core.* -o /coredump/core.zst
      ossutil cp /coredump/core.zst oss://prod-dump/coredump/${POD_NAME}.zst
      
    • 上传完成通过 Kubernetes EventSLS 日志 通知研发,emptyDir 自动回收。
  4. 上传优化

    • 文件 >100 MB 启用 multipartossutil 默认并发 3,可 -c 10 提速。
    • VPC 内网域名(如 oss-cn-shanghai-internal.aliyuncs.com)节省公网流量费。
    • 若集群跨多账号,通过 STS 临时凭证AssumeRole)授权 sidecar,避免明文 AK/SK。
  5. 安全与合规

    • 客户端使用 ossutil --encryption-method AES256 加密后再传。
    • Bucket 策略 限定 IP=PodCIDRSecureTransport=true
    • 开启 OSS 日志 投递到同一账号 SLS,满足等保审计。
  6. 自动化闭环

    • CI/CD 中增加 core 解析 Job:下载 core.zst → gdb app -c core → 生成 backtrace.txt → 上传 Jira。
    • 若解析成功,调用 OSS API DeleteObject 立即删除,降低存储费用。
    • 未解析 core 通过 生命周期规则 7 天转归档、30 天删除。

拓展思考

  • 如果业务对延迟极度敏感,可把 core_pattern 设为 systemd-coredump,利用 coredumpctl 直接转储到 Ceph RGW 的 S3 接口,再配置 RGW 压缩插件(lz4/zstd)实现 “零脚本” 运维。
  • 对 Windows 容器,可借助 ProcDump 生成小型 minidump,再使用 AzCopy 上传至 Azure Blob(国内世纪互联),思路与 Linux 侧一致。
  • 未来可替换 sidecar 为 eBPF+fluent-bit:在 do_coredump 内核 tracepoint 捕获,流式压缩并直接 PUT,无需落盘,实现 “coreless” 即时上传。