'How to check what port a pod is listening on with kubectl and not looking at the dockerFile?

I have a pod running and want to port forward so i can access the pod from the internal network. I don't know what port it is listening on though, there is no service yet.

I describe the pod:

$ kubectl describe pod queue-l7wck 
Name:         queue-l7wck
Namespace:    default
Priority:     0
Node:         minikube/192.168.64.3
Start Time:   Wed, 18 Dec 2019 05:13:56 +0200
Labels:       app=work-queue
              chapter=jobs
              component=queue
Annotations:  <none>
Status:       Running
IP:           172.17.0.2
IPs:
  IP:           172.17.0.2
Controlled By:  ReplicaSet/queue
Containers:
  queue:
    Container ID:   docker://13780475170fa2c0d8e616ba1a3b1554d31f404cc0a597877e790cbf01838e63
    Image:          gcr.io/kuar-demo/kuard-amd64:blue
    Image ID:       docker-pullable://gcr.io/kuar-demo/kuard-amd64@sha256:1ecc9fb2c871302fdb57a25e0c076311b7b352b0a9246d442940ca8fb4efe229
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Wed, 18 Dec 2019 05:14:02 +0200
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-mbn5b (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  default-token-mbn5b:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-mbn5b
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age        From               Message
  ----    ------     ----       ----               -------
  Normal  Scheduled  <unknown>  default-scheduler  Successfully assigned default/queue-l7wck to minikube
  Normal  Pulling    31h        kubelet, minikube  Pulling image "gcr.io/kuar-demo/kuard-amd64:blue"
  Normal  Pulled     31h        kubelet, minikube  Successfully pulled image "gcr.io/kuar-demo/kuard-amd64:blue"
  Normal  Created    31h        kubelet, minikube  Created container queue
  Normal  Started    31h        kubelet, minikube  Started container queue

even the JSON has nothing:

$ kubectl get pods queue-l7wck -o json
{
    "apiVersion": "v1",
    "kind": "Pod",
    "metadata": {
        "creationTimestamp": "2019-12-18T03:13:56Z",
        "generateName": "queue-",
        "labels": {
            "app": "work-queue",
            "chapter": "jobs",
            "component": "queue"
        },
        "name": "queue-l7wck",
        "namespace": "default",
        "ownerReferences": [
            {
                "apiVersion": "apps/v1",
                "blockOwnerDeletion": true,
                "controller": true,
                "kind": "ReplicaSet",
                "name": "queue",
                "uid": "a9ec07f7-07a3-4462-9ac4-a72226f54556"
            }
        ],
        "resourceVersion": "375402",
        "selfLink": "/api/v1/namespaces/default/pods/queue-l7wck",
        "uid": "af43027d-8377-4227-b366-bcd4940b8709"
    },
    "spec": {
        "containers": [
            {
                "image": "gcr.io/kuar-demo/kuard-amd64:blue",
                "imagePullPolicy": "Always",
                "name": "queue",
                "resources": {},
                "terminationMessagePath": "/dev/termination-log",
                "terminationMessagePolicy": "File",
                "volumeMounts": [
                    {
                        "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
                        "name": "default-token-mbn5b",
                        "readOnly": true
                    }
                ]
            }
        ],
        "dnsPolicy": "ClusterFirst",
        "enableServiceLinks": true,
        "nodeName": "minikube",
        "priority": 0,
        "restartPolicy": "Always",
        "schedulerName": "default-scheduler",
        "securityContext": {},
        "serviceAccount": "default",
        "serviceAccountName": "default",
        "terminationGracePeriodSeconds": 30,
        "tolerations": [
            {
                "effect": "NoExecute",
                "key": "node.kubernetes.io/not-ready",
                "operator": "Exists",
                "tolerationSeconds": 300
            },
            {
                "effect": "NoExecute",
                "key": "node.kubernetes.io/unreachable",
                "operator": "Exists",
                "tolerationSeconds": 300
            }
        ],
        "volumes": [
            {
                "name": "default-token-mbn5b",
                "secret": {
                    "defaultMode": 420,
                    "secretName": "default-token-mbn5b"
                }
            }
        ]
    },
    "status": {
        "conditions": [
            {
                "lastProbeTime": null,
                "lastTransitionTime": "2019-12-18T03:13:56Z",
                "status": "True",
                "type": "Initialized"
            },
            {
                "lastProbeTime": null,
                "lastTransitionTime": "2019-12-18T03:14:02Z",
                "status": "True",
                "type": "Ready"
            },
            {
                "lastProbeTime": null,
                "lastTransitionTime": "2019-12-18T03:14:02Z",
                "status": "True",
                "type": "ContainersReady"
            },
            {
                "lastProbeTime": null,
                "lastTransitionTime": "2019-12-18T03:13:56Z",
                "status": "True",
                "type": "PodScheduled"
            }
        ],
        "containerStatuses": [
            {
                "containerID": "docker://13780475170fa2c0d8e616ba1a3b1554d31f404cc0a597877e790cbf01838e63",
                "image": "gcr.io/kuar-demo/kuard-amd64:blue",
                "imageID": "docker-pullable://gcr.io/kuar-demo/kuard-amd64@sha256:1ecc9fb2c871302fdb57a25e0c076311b7b352b0a9246d442940ca8fb4efe229",
                "lastState": {},
                "name": "queue",
                "ready": true,
                "restartCount": 0,
                "started": true,
                "state": {
                    "running": {
                        "startedAt": "2019-12-18T03:14:02Z"
                    }
                }
            }
        ],
        "hostIP": "192.168.64.3",
        "phase": "Running",
        "podIP": "172.17.0.2",
        "podIPs": [
            {
                "ip": "172.17.0.2"
            }
        ],
        "qosClass": "BestEffort",
        "startTime": "2019-12-18T03:13:56Z"
    }
}

How do you checker what port a pod is listening on with kubectl?

Update

If I ssh into the pod and run netstat -tulpn as suggested in the comments I get:

$ kubectl exec -it queue-pfmq2 -- sh
~ $ netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 :::8080                 :::*                    LISTEN      1/kuard

But this method is not using kubectl.



Solution 1:[1]

Your container image has a port opened during the build (looks like port 8080 in your case) using the EXPOSE command in the Dockerfile. Since the exposed port is baked into the image, k8s does not keep track of this open port since k8s does not need to take steps to open it.

Since k8s is not responsible for opening the port, you won't be able to find the listening port using kubectl or checking the pod YAML

Solution 2:[2]

Try the combination of both kubectl and your Linux command to get the Port container is listening on:

kubectl exec <pod name here> -- netstat -tulpn

Further you can pipe this result with grep to narrow the findings if required eg.

kubectl exec <pod name here> -- netstat -tulpn | grep "search string"

Note: It will work only if your container's base image supports the command netstat. and as per your Update section it seems it supports. Above solution is nothing but a smart use of the commands you have used in two parts first to exec the container in interactive mode using -it second in the container to list the listening port.

Solution 3:[3]

kubectl get pod PODNAME --template='{{(index (index .spec.containers 0).ports 0).containerPort}}{{"\n"}}'

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Patrick W
Solution 2 Anoop
Solution 3 Philcz