Kubernetes Disk Troubleshooter
This skill helps you troubleshoot disk and block I/O issues in Kubernetes. Symptoms include slow file operations, database query latency, pods that are I/O-bound, or applications reporting high storage latency. The workflow moves from a cluster-wide latency profile, to identifying the noisiest pod, to pinpointing the exact file responsible.
gadget_profile_blockio Tool
Use this tool first to build a latency histogram of block I/O activity across the cluster (or a specific namespace/pod). It traces every block device request and buckets completion times so you can immediately see whether latency is in the microsecond, millisecond, or second range before drilling deeper.
Key fields returned:
dev– block device identifier (e.g.sda,nvme0n1)cmd_flags– the type of operation (read/write/flush/discard)latency– histogram of I/O completion latencies bucketed by duration
Recommended usage:
- Run for a short foreground window (10–30 seconds) to capture a representative sample while the workload is under load.
- Scope to a specific namespace with
operator.KubeManager.namespaceto reduce noise when you already have a suspect workload. - If the histogram shows a significant tail (p99 >> p50), there is a real I/O latency problem worth investigating further with
gadget_top_blockio.
Example parameters:
{
"duration": 15,
"params": {
"operator.KubeManager.namespace": "default"
}
}
gadget_top_blockio Tool
Use this tool second, after gadget_profile_blockio confirms elevated latency, to rank pods and processes by their block I/O activity. It periodically samples I/O throughput so you can quickly identify which pod or container is the heaviest consumer of block device bandwidth or is issuing the most I/O operations (which can saturate the device even at low individual latencies).
Key fields returned:
k8s.namespace,k8s.podName,k8s.containerName– Kubernetes context of the processproc.comm,proc.pid,proc.tid– process and thread performing the I/Orw– direction:readorwritebytes– total bytes transferred in the sampling intervalus– time spent waiting for I/O in microseconds (high values indicate I/O pressure)io– number of I/O operations issuedmajor/minor– block device numbers
Key filtering and sorting options:
operator.KubeManager.namespace– restrict to one namespaceoperator.KubeManager.podname– restrict to a specific podoperator.KubeManager.selector– filter by pod label selector (e.g.app=postgres)operator.KubeManager.all-namespaces– scan all namespacesoperator.sort.sort– sort results; use-bytesor-usto surface the highest-impact entries firstoperator.filter.filter– apply field-level filters, e.g.rw==writeto focus on write trafficoperator.limiter.max-entries– cap the number of rows returned per interval
Run modes:
- Foreground (default): Pass a
durationin seconds. The tool blocks and returns aggregated results when the window closes. Good for a quick snapshot. - Background: Pass
duration: 0. The gadget runs continuously; retrieve results later withig_gadgets. Use this when you need to correlate I/O spikes with application events over a longer window.
Example parameters (foreground, sorted by bytes descending):
{
"duration": 10,
"params": {
"operator.KubeManager.all-namespaces": "true",
"operator.sort.sort": "-bytes"
}
}
gadget_top_file Tool
Use this tool third, once you have identified the offending pod or container from gadget_top_blockio, to rank individual files by their read/write activity inside that workload. This maps raw block device I/O back to the filesystem, telling you exactly which file, database data file, WAL segment, or log is responsible for the pressure.
Key fields returned:
file– absolute path of the file being accessedt– file type:R(regular file),S(socket),O(other including pipes). Regular files are shown by default.proc.comm,proc.pid,proc.tid– process performing the I/Ok8s.namespace,k8s.podName,k8s.containerName– Kubernetes contextreads/writes– count of read/write operations in the intervalrbytes_raw/wbytes_raw– bytes read/written (userbytes/wbytesfor human-readable)inode/dev– inode and device, useful for cross-referencing with filesystem tools
Key filtering options:
operator.KubeManager.containername– narrow to the specific container identified in the previous stepoperator.KubeManager.podname– narrow to the specific podoperator.KubeManager.namespace– restrict to one namespaceoperator.oci.ebpf.all-files– set to"true"to also trace sockets and pipes (useful for database processes that use Unix sockets)operator.oci.ebpf.pid– trace only a specific process PID (use theproc.pidvalue fromgadget_top_blockio)operator.sort.sort– sort by-wbytes_rawto surface the most-written file, or-rbytes_rawfor the most-read fileoperator.filter.filter– e.g.t==Rto restrict to regular files only
Run modes:
- Foreground (default): Pass a
durationin seconds for a bounded snapshot. Suitable for interactive investigation. - Background: Pass
duration: 0to trace continuously. Useful when the I/O issue is intermittent and you need to wait for it to recur.
Example parameters (foreground, scoped to a pod, sorted by write bytes):
{
"duration": 10,
"params": {
"operator.KubeManager.namespace": "default",
"operator.KubeManager.podname": "postgres-0",
"operator.sort.sort": "-wbytes_raw"
}
}
Troubleshooting Process
Follow these steps in order to methodically root-cause disk / block I/O latency in a Kubernetes cluster.
Step 1 – Profile block I/O latency cluster-wide
Run gadget_profile_blockio for 15–30 seconds to capture a latency histogram.
- If the histogram is clean (all operations complete in < 1 ms), block I/O is not the bottleneck — look elsewhere (network, CPU, application logic).
- If you see a heavy tail or operations in the tens-of-milliseconds range, proceed to Step 2.
- Note the
devvalue(s) with high latency — this tells you which physical or virtual disk is under pressure.
Step 2 – Identify the noisiest pod with gadget_top_blockio
Run gadget_top_blockio scoped to the relevant namespace (or all namespaces) sorted by -bytes or -us.
- The top entries reveal which
k8s.podNameandk8s.containerNameare consuming the most I/O bandwidth or spending the most time waiting on the block device. - Note both the pod name and
proc.pidof the top offending process — you will need these in Step 3. - Check the
rwfield: sustained write pressure often points to log spam, checkpoint storms (databases), or runaway writes; sustained read pressure can indicate missing caches or repeated cold reads. - If the culprit pod is a database (Postgres, MySQL, etcd), pay special attention to
us— even moderatebyteswith very highusindicates severe I/O queue depth or slow disk.
Step 3 – Pinpoint the file with gadget_top_file
Run gadget_top_file scoped to the offending pod (and optionally filtered by the proc.pid from Step 2), sorted by -wbytes_raw or -rbytes_raw depending on whether writes or reads dominated in Step 2.
- The
filefield will show the absolute path inside the container, e.g.:/var/lib/postgresql/data/base/16384/1259→ a Postgres data file or system catalog/var/lib/postgresql/data/pg_wal/000000010000000000000001→ WAL segment (heavy writes here = checkpoint pressure)/var/log/app/access.log→ log file (runaway logging)/tmp/sort_temp_001→ temporary sort spill (query needs morework_mem)
- Use the file path to guide the remediation: tune database configuration, reduce log verbosity, add indexes to eliminate large sequential scans, or move the workload to a faster storage class.
- If no files appear or paths look like
/procentries, enableoperator.oci.ebpf.all-files=trueto capture non-regular-file I/O.
Source: mayasingh17/ig-mcp-server-scale — distributed by TomeVault.