As a full-stack developer working with Kubernetes in production, you need visibility into the hundreds of nodes, thousands of deployments, pods, replica sets, services, secrets, and more running in your clusters. The kubectl CLI gives you access to all of this information. However, often you need to filter and extract specifics beyond what kubectl‘s default output provides.

Manually sifting through thousands of resources to find that exact piece of information would be tedious. This is where kubectl‘s Jsonpath option comes in handy, making filtering across large data sets a breeze.

Under the hood, every time you run kubectl it communicates with the Kubernetes API server, which responds with JSON-formatted data. kubectl then translates that into human-readable output printed to your terminal. To keep the output understandable, a lot of information gets hidden during this process, only showing the most relevant fields. We can use the -o wide option to get more, but still not everything. There are further details not shown.

Splitting Jsonpath Output into Separate Lines

A common task is getting kubectl jsonpath to output results onto distinct lines. For example, the following grabs the podIP for every running Pod across all namespaces. But having it all smushed together is less than ideal:

$ kubectl get pods -A -o jsonpath=‘{range .items[*]}{.status.podIP}{"\n"}{end}‘ 
192.168.64.2 192.168.64.3 192.168.64.4

We can iterate over the list using the range function in Jsonpath, adding a newline after each item with \n. Great! Now we can leverage all the usual UNIX tools that operate on newlines to work with the output (e.g. sort, xargs, uniq, etc).

$ kubectl get pods -A -o jsonpath=‘{range .items[*]}{.status.podIP}{"\n"}{end}‘
192.168.64.2
192.168.64.3 
192.168.64.4

Other whitespace can be used too. Say we want to print the pod namespace/name as well as its IP address separated by a comma:

$ kubectl get pods -A -o jsonpath=‘{range .items[*]}{.metadata.namespace}/{.metadata.name},{.status.podIP}{"\n"}{end}‘
default/foo,192.168.64.2
kube-system/bar,192.168.64.3

Occasionally printing output in jsonpath format can be handy too:

$ kubectl get pods -A -o=jsonpath=‘{range .items[*]}{{"Namespace:"}}{.metadata.namespace}{"\n"}{{"Name:"}}{.metadata.name}{"\n"}{{"IP:"}}{.status.podIP}{"\n"}{end}‘ 
Namespace:
default
Name:
foo
IP:  
192.168.64.2
Namespace:
kube-system
Name: 
bar
IP:
192.168.64.3 

Kubectl Jsonpath Expression Examples

Along with custom templates, kubectl supports Jsonpath expressions. These get enclosed in curly braces within a jsonpath template, allowing kubectl to filter and format the result. The syntax is the same as standard Jsonpath, plus some custom extensions:

  • Literal strings go in double quotes
  • Iterate lists with range and end
  • Negative slice indices to go backwards through a list
  • @ represents the current object
  • . or [] is the child operator. . does recursive descent
  • * for all objects
  • Union operator is [,]
  • " needs to be escaped or single quoted in literals

Since expressions are relative to root by default, you don‘t need to prefix with $. Use String() function to print.

Here‘s the JSON we‘ll query as an example:

{
  "kind": "List",
  "apiVersion": "v1",
  "metadata": {},
  "items": [
    {
      "kind": "Pod",
      "apiVersion": "v1",
      "metadata": {
        "name": "foo",
        "namespace": "default"
      }
    }, 
    {
       "kind": "Pod",
      "apiVersion": "v1",
      "metadata": {
        "name": "bar",
        "namespace": "kube-system"
      }
    }
  ] 
}

And here‘s some example usage of kubectl jsonpath expressions:

# Namespace and name of all pods 
$ kubectl get pods -A -o=jsonpath=‘{range .items[*]}{.metadata.namespace} / {.metadata.name}{"\n"}{end}‘
default / foo  
kube-system / bar

# All pod names
$ kubectl get pods -A -o jsonpath=‘{range .items[*]}{"\n"}{.metadata.name}{end}‘
foo
bar

# Just the first pod name 
$ kubectl get pods -A -o jsonpath=‘{.items[0].metadata.name}‘
foo

A few things to be aware of when using jsonpath with kubectl:

  • Regular expressions are not supported for matching. Use a tool like jq if you need regexes
  • On Windows, any template with spaces must be double quoted, not single quoted like in bash. So literals require single quotes or escaped double quotes
  • Watch out for spacing between operators. e.g {range.items[*]} is invalid, needs to be {range .items[*]}

Conclusion

This guide gave an overview of Kubernetes jsonpath: why it‘s used, how it allows filtering API responses from kubectl, and various examples of useful jsonpath expressions. Getting familiar with jsonpath in kubectl helps you efficiently query data from this complex system.

Similar Posts