kubectl
custom-columns
output formatting
Kubernetes
command-line tools

kubectl Use custom-columns output with maps

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

kubectl -o custom-columns is useful when you want a short table instead of raw JSON or YAML. It works well for simple scalar fields, and it can also read values from maps such as labels and annotations, but only when you know the exact key you want. When you need dynamic iteration over all map entries, custom-columns stops being the right tool.

Read Specific Keys from Maps

Kubernetes resources often store metadata in maps such as metadata.labels and metadata.annotations. If you know the key in advance, you can project it into a custom column.

bash
kubectl get pods \
  -o custom-columns=NAME:.metadata.name,APP:.metadata.labels.app

This works because app is a simple map key. The result is a compact table showing pod name and the app label.

Handle Keys with Dots or Slashes

Real Kubernetes label keys often contain dots and slashes, such as app.kubernetes.io/name. Those characters make dotted path syntax ambiguous, so bracket notation is safer.

bash
kubectl get pods \
  -o custom-columns=NAME:.metadata.name,APP:.metadata.labels['app.kubernetes.io/name']

The same idea works for annotations:

bash
kubectl get deploy \
  -o custom-columns=NAME:.metadata.name,RESTARTED:.metadata.annotations['kubectl.kubernetes.io/restartedAt']

If the key is missing on some objects, the column is simply blank for those rows.

Know the Limitation with Whole Maps

custom-columns is good at "show me this one known field." It is not good at "loop through every key/value pair in this map and print them." For example, printing every label on every pod in a clean, dynamic table is not what custom-columns was built to do.

If you try to point a column at the whole map, the output becomes hard to read because the map is rendered as a single serialized value. That may be acceptable for quick inspection, but it is not a reliable reporting format.

bash
kubectl get pods \
  -o custom-columns=NAME:.metadata.name,LABELS:.metadata.labels

This can be useful for a quick glance, but it is not great for automation or stable terminal output.

Use the Right Output Mode for Dynamic Maps

When you need to iterate over arbitrary map keys, switch to a more expressive format:

  • '-o jsonpath for targeted extraction.'
  • '-o go-template for loops and formatting.'
  • '-o json piped to jq for serious transformation work.'

For example, if you want all labels as JSON:

bash
kubectl get pod my-pod -o jsonpath='{.metadata.labels}'

Or if you want a richer transformation pipeline:

bash
kubectl get pods -o json | jq '.items[] | {name: .metadata.name, labels: .metadata.labels}'

That is a better fit than forcing dynamic map formatting into custom-columns.

Use Label-Specific Helpers When Available

For node labels, pod labels, and similar metadata, kubectl sometimes offers shortcuts that are easier than building a custom column by hand. For example, -L adds label columns directly to the output:

bash
kubectl get pods -L app -L tier

This is convenient when you specifically want label values as additional columns and do not need a completely custom layout.

Choose custom-columns for Stable, Known Fields

The best use case is operational dashboards in the terminal: known keys, fixed headers, predictable output. If the key names are stable and you only want a few columns, custom-columns is excellent. If the structure is dynamic, move to JSONPath, Go templates, or jq early instead of trying to fight the formatting layer.

Common Pitfalls

  • Expecting custom-columns to iterate through all entries in a map.
  • Using dotted syntax for keys that contain dots or slashes.
  • Forgetting that missing map keys produce blank output.
  • Printing entire maps in a table and expecting stable formatting.
  • Using custom-columns when jq or jsonpath would be a better fit.

Summary

  • 'custom-columns works well for specific known map keys.'
  • Use bracket notation for label or annotation keys with punctuation.
  • Whole maps can be displayed, but the output is usually poor for automation.
  • Switch to JSONPath, Go templates, or jq when you need dynamic map iteration.
  • Prefer custom-columns for stable operational tables, not complex transformations.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.