Skip to content

Memory leak via kernel slab growth causes OOMKill under high-target load #329

Description

@aahmadzada-png

What did you do?

Ran ipmi_exporter v1.10.1 in Kubernetes with 500 targets, 4 collectors
(ipmi, dcmi, chassis, bmc), scrape_interval=15s, container memory limit 500Mi.

What did you expect to see?

Stable memory usage, or at least a plateau well below the limit.

What did you see instead?

Linear memory growth over ~15 hours until OOMKill. Reproducible — both
replicas started simultaneously followed identical trajectories and
OOMKilled within the same second.

  • Pod A: 37 MiB → 461 MiB → OOMKill → restart
  • Pod B: 22 MiB → 452 MiB → OOMKill → restart
  • Growth rate: ~30 MiB/hour

Diagnosis

The growth is not in Go memory. Go metrics are flat:

  • go_memstats_heap_inuse_bytes: 12 MB
  • go_memstats_sys_bytes: 49 MB

The growth is in kernel slab (dentry/inode cache). From
/sys/fs/cgroup/memory.stat at ~223 MiB working set:

anon:               19 MB   (process memory, flat)
file:                0.9 MB
kernel_stack:        2 MB
slab_reclaimable:  192 MB   ← the growth
slab_unreclaimable:  1.5 MB

Other observations:

  • Only 5–6 live freeipmi subprocesses at any moment (no subprocess leak)
  • /tmp contains 1 file (no temp-file leak)
  • GOMEMLIMIT=156MiB and GOGC=80 had no effect (confirms it isn't Go heap)

Hypothesized cause

Each scrape creates a unique /tmp/ipmi_exporter-<hash> config file and
forks freeipmi binaries (ipmi-sensors, ipmi-dcmi, ipmi-chassis,
bmc-info), each loading ~15 shared libraries. At 500 targets × 4
collectors × 15s interval, that's ~130 fork+exec per second, generating
thousands of dentry/inode allocations per second. Kernel caches them
as slab_reclaimable. Under sustained churn near the memory limit,
reclaim can't keep pace → OOMKill.

Suggested fix (AI)

Avoid per-scrape temp file churn in
freeipmi.go:

  1. Use memfd_create(2) for the config — no dentry/inode, lives in memory.
  2. Or generate the config file once per target at startup and reuse it.

Environment

  • ipmi_exporter: v1.10.1
  • freeipmi:
  • Kubernetes:
  • Container runtime: containerd
  • cgroup: v2
  • Kernel: 6.8.0-100-generic (Alpine Linux v3.22)
  • Target count: 500
  • Scrape interval: 15s
  • Collectors: ipmi, dcmi, chassis, bmc

Note: we also see this reported which possibly related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions