Kubernetes detailed container memory usage
- After the pod starts, open a terminal into each container. For
example:
kubectl exec -n mynamespace -it podname -- bash - Change directory to
/tmp:cd /tmp - Write the following shell script:
cat > memorystats.sh << 'EOF' #!/bin/sh SLEEPTIMESECONDS=300 OUTPUTFILE="diag_memorystat_${HOSTNAME}_$(date +"%Y%m%d_%H%M%S").txt" while getopts "s:" opt; do case "$opt" in s) SLEEPTIMESECONDS="${OPTARG}" ;; esac done echo "Writing output to ${OUTPUTFILE}" while true; do echo "[$(date)] Performing iteration" >> "${OUTPUTFILE}" 2>>"${OUTPUTFILE}" for FILE in $(ls /proc/meminfo /sys/fs/cgroup/memory* /sys/fs/cgroup/*/*/memory* /proc/[0-9]*/smaps*); do echo "[$(date)] Gathering ${FILE}" >> "${OUTPUTFILE}" 2>>"${OUTPUTFILE}" cat "${FILE}" >> "${OUTPUTFILE}" 2>>"${OUTPUTFILE}" done echo "[$(date)] Sleeping for ${SLEEPTIMESECONDS} seconds..." >> "${OUTPUTFILE}" 2>>"${OUTPUTFILE}" sleep ${SLEEPTIMESECONDS} done EOF - Make the script executable:
chmod +x memorystats.sh - Start the script in the background, changing the interval in seconds
as needed:
nohup ./memorystats.sh -s 300 & - Write the script's PID into a file:
echo $! > pid_memorystats.txt - Reproduce the issue
- After the issue has been reproduced, stop the script:
kill -TERM $(cat pid_memorystats.txt) - List the resulting output file; for example:
$ ls diag* diag_memorystat_liberty1-b6cddccb4-m4c62_20260811_172419.txt - Exit the pod terminal
- Download the file locally:
kubectl cp -n mynamespace -it podname:/tmp/diag_memorystat_liberty1-b6cddccb4-m4c62_20260811_172419.txt diag_memorystat_liberty1-b6cddccb4-m4c62_20260811_172419.txt
Notes:
- Watch the disk usage in the script output directory. If a pod hits an ephemeral disk limit, it may be killed. Log volume will be a function of the interval.
- Instead of manually starting the script after the pod starts, this
can be done automatically by writing and executing the script in a
postStartconfiguration; for example (be careful with escaping quotes properly):spec: containers: - name: [...] lifecycle: postStart: exec: command: ["/bin/sh", "-c", "cd /tmp/; echo -e '#!/bin/sh \n SLEEPTIMESECONDS=600; OUTPUTFILE=\"stdout_memorystat_${HOSTNAME}_$(date +\"%Y%m%d_%H%M%S\").txt\"; sleep 5; echo \"[$(date)] Started $(basename \"${0}\") in background (PID $$)\" >> ${OUTPUTFILE}; while true; do echo \"[$(date)] Performing iteration\" >> ${OUTPUTFILE}; for FILE in $(ls /proc/meminfo /sys/fs/cgroup/memory* /sys/fs/cgroup/*/*/memory* /proc/[0-9]*/smaps*); do echo \"[$(date)] Gathering ${FILE}\" >> ${OUTPUTFILE}; cat ${FILE} >> ${OUTPUTFILE}; done; echo \"[$(date)] Sleeping for ${SLEEPTIMESECONDS} seconds...\" >> ${OUTPUTFILE}; sleep ${SLEEPTIMESECONDS}; done' > memorystat.sh; chmod +x memorystat.sh; ./memorystat.sh &> stderr_memorystat.txt &"]