Kubernetes custom-columns select element from array

TLDR

for an element that is list use * in square bracket.

So your query should look like this:

$ kubectl get service -n kube-system  -o=custom-columns=NAME:.metadata.name,IP:.spec.clusterIP,PORT:.spec.ports[*].targetPort
NAME                   IP           PORT
kube-dns               10.0.0.10    53,53
kubernetes-dashboard   10.0.0.250   9090

Notice the * in PORT:.spec.ports[*].targetPort.

Details:

So kubernetes is expecting a json-path-expr after header. The error I got when playing with expressions was following:

expected <header>:<json-path-expr>

So to iterate over all elements in a list instead of putting an index just use *.

Various other json-path expressions can be found here.


You can use * for understanding which data in the json. For example:

kubectl get svc gdpr -o custom-columns=svc:*

As for me kubectl get svc -o custom-columns=svc:.metadata.name,IP:.metadata.annotations.domainName,PORT:.spec.ports[*].targetPort was perfect (due external IP info) and looks like:

event   site1.com 9000 
gdpr    site2.com 3333,8080
svcInt  none      80
ui      site6.com 80,6123,6124,6125,8081

p.s. About list external IP and hosts:

kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name} {.status.addresses[?(@.type=="ExternalIP")].address}{"\n"}'
ip-10-10-40-13.xxxxx.internal xx.xx.xx.175
ip-10-10-40-15.xxxxx.internal xx.xx.xx.236
ip-10-10-40-18.xxxxx.internal xx.xx.xx.207

kubectl get nodes -o jsonpath='{range .items[*]}{.status.addresses[?(@.type=="ExternalIP")].address}{"\n"}'
xx.xx.xx.175
xx.xx.xx.236
xx.xx.xx.207