kubectl get -o custom-columns: Tabular Output
kubectl get -o custom-columns=<HEADER>:<jsonpath>,... prints exactly the columns you define as a clean table.
When the default columns are noisy or missing the field you need, custom-columns lets you compose a table that is easy to grep and diff in CI.
What it does
kubectl get with -o custom-columns takes comma-separated HEADER:jsonpath pairs and renders one column per pair across the matched resources. It is the readable cousin of jsonpath: still field-precise, but laid out as a table with headers (suppress them with --no-headers).
Common usage
kubectl get pods -o custom-columns=\
NAME:.metadata.name,NODE:.spec.nodeName,STATUS:.status.phase
# images per deployment, no header for scripting
kubectl get deploy -o custom-columns=\
NAME:.metadata.name,IMAGE:.spec.template.spec.containers[0].image \
--no-headers
# combine with server-side sort
kubectl get pods --sort-by=.status.startTimeOptions
| Syntax / Flag | What it does |
|---|---|
| HEADER:jsonpath | Define a column header and its source field |
| --no-headers | Omit the header row for scripting |
| -o custom-columns-file=<f> | Read the column spec from a file |
| --sort-by=<jsonpath> | Sort rows by a field server-side |
| <missing field> | Renders as <none> rather than failing |
In CI
A missing field shows as <none>, not an error, which makes custom-columns safe for heterogeneous lists. Avoid spaces inside the spec; the comma-separated list must be a single argument, so use line continuations carefully or pass a custom-columns-file.
Common errors in CI
"error: unknown columns ... expected format ... NAME:.metadata.name" means a malformed spec, often a stray space splitting the argument. "error: provided options ... not supported" means you mixed custom-columns with another -o. An empty table usually means the selector matched nothing, not a bad spec.
Using this in CI
A runner has no kubeconfig, no cached context, and no interactive auth. Every kubectl invocation in CI needs the context supplied explicitly, and most confusing CI failures here are the command running against the wrong cluster or no cluster at all.
# never rely on the ambient context on a runner
kubectl --context "$KUBE_CONTEXT" -n "$NAMESPACE" get pods
# confirm what you are actually connected to before mutating anything
kubectl config current-context
kubectl cluster-info
# fail fast instead of hanging on an unreachable API server
kubectl --request-timeout=30s get nodes