Search code examples
kubernetesgoogle-kubernetes-enginekubectl

Troubleshooting kubectl get pods command: Why is .spec.containers.ports.containerPort returning <none>?


I am getting the IP address assigned to the pod using kubectl get pods -o custom-columns="POD_IP":.status.podIPs command.

And based on same approach, I am using kubectl get pods -o custom-columns="POD_PORT":.spec.containers.ports.containerPort command to get the port number but it is coming as blank.

cloudshell:~$ kubectl get pods -o custom-columns="POD_IP":.status.podIPs
POD_IP
[map[ip:10.32.0.194]]

cloudshell:~$ kubectl get pods -o custom-columns="POD_PORT":.spec.containers.ports.containerPort
POD_PORT
<none>

cloudshell:~$ kubectl get pods -o custom-columns="POD_PORT":.spec.containers
POD_PORT
[map[image:nginx:1.10.1 imagePullPolicy:IfNotPresent name:servic1 ports:[map[containerPort:8080 protocol:TCP]] resources:map[limits:map[cpu:500m ephemeral-storage:1Gi memory:2Gi] requests:map[cpu:500m ephemeral-storage:1Gi memory:2Gi]] securityContext:map[capabilities:map[drop:[NET_RAW]]] terminationMessagePath:/dev/termination-log terminationMessagePolicy:File volumeMounts:[map[mountPath:/var/run/secrets/kubernetes.io/serviceaccount name:kube-api-access-mgk8k readOnly:true]]]]

cloudshell:~$ 

I have tried to use kubectl get pods -o custom-columns="Port Number of Pod":.spec.containers command and I can see that my mapping (.spec.containers.ports.containerPort) is correct but somehow it is still not working.

I am totally sure that .spec.containers.ports.containerPort mapping correct, and same command format is giving IP address, so not able to catch what is wrong.

Is anyone able to catch what is wrong here?


Solution

  • Try:

    kubectl get pods \
    --output=custom-columns=\
    "POD_PORT":.spec.containers[*].ports[*].containerPort
    

    You can include .metadata.name too to aid clarity:

    kubectl get pods \
    --output=custom-columns=\
    "NAME":.metadata.name,\
    "POD_PORT":.spec.containers[*].ports[*].containerPort
    

    It's not clearly (!?) documented but I suspect the format is kubectl's JSONPath and there (appears to be) a subtle distinction between e.g. .spec.containers[] and .spec.containers[*] where the former stops when the property is not found and the latter includes everything.

    Because .spec will always include one or more .containers, but each container may not have .ports, you can also:

    kubectl get pods \
    --output=custom-columns=\
    "POD_PORT":.spec.containers[].ports[*].containerPort
    

    Which containers[] but ports[*] to the same effect.

    NOTE as explained in Container v1 core see "ports", ports that are exposed by the container need not be specified through ports i.e. this command will return documented ports but this list may exclude ports that are exposed by the containers (and not documented).