50

I have exposed a service on an external port on all nodes in a kubernetes cluster from:

kubectl create -f nginx-service.yaml

You have exposed your service on an external port on all nodes in your cluster. If you want to expose this service to the external internet, you may need to set up firewall rules for the service port(s) (tcp:30002) to serve traffic.

See http://releases.k8s.io/release-1.2/docs/user-guide/services-firewalls.md for more details. service "nginx-service" created.`

Is there anyway to get the external ports of the kubernetes cluster?

user3079474
  • 1,653
  • 2
  • 24
  • 37
kevin
  • 501
  • 1
  • 4
  • 4
  • Are you using google cloud or aws or local docker as your kubernetes provider ? ... kubernetes should be agnostic yet on aws its sketchy – Scott Stensland Jun 14 '16 at 21:45

8 Answers8

76

kubectl get svc --all-namespaces -o go-template='{{range .items}}{{range.spec.ports}}{{if .nodePort}}{{.nodePort}}{{"\n"}}{{end}}{{end}}{{end}}'

This gets all services in all namespaces, and does basically: "for each service, for each port, if nodePort is defined, print nodePort".

Tim Hockin
  • 3,567
  • 13
  • 18
  • 1
    Can you add some explanation with your answer? It will help OP to understand what you are posting. – Guillaume Racicot Sep 01 '16 at 02:11
  • 14
    `kubectl get svc --all-namespaces -o go-template='{{range .items}}{{range.spec.ports}}{{if .nodePort}}{{.nodePort}}{{.}}{{"\n"}}{{end}}{{end}}{{end}}' ` this will give more information about each NodePort listed. – Anum Sheraz Mar 28 '18 at 23:42
  • What command does the same as this one but for a specific namespace (without the range)? – Akito Mar 09 '20 at 11:11
  • kubectl get svc -n -o go-template='{{range .items}}{{range.spec.ports}}{{if .nodePort}}{{.nodePort}}{{"\n"}}{{end}}{{end}}{{end}}' – Tim Hockin Mar 10 '20 at 15:26
  • 1
    ``` kubectl get svc --all-namespaces -o go-template='{{range .items}}{{range.spec.ports}}{{if .nodePort}}{{.nodePort}}{{"\t"}}{{.name}}{{"\n"}}{{end}}{{end}}{{end}}' | sort ``` in case you also want to identify services associated to each nodePort (in nodePorts ascend order) – Shondeslitch Jun 24 '20 at 09:16
28

I hope this answer is short and simple:

kubectl describe service --all-namespaces | grep -i nodeport

But, using go template is the ideal option and can be used to extract more details.

Eduardo Baitello
  • 10,469
  • 7
  • 46
  • 74
rajdeepbs29
  • 1,211
  • 12
  • 9
13

If you view your service using kubectl describe service NAME it should show you what port was assigned (in the NodePort field).

Robert Bailey
  • 17,866
  • 3
  • 50
  • 58
  • Yes, I know that. Is there a way to get all of the external ports in one command or others? – kevin Jun 06 '16 at 08:42
  • Do you mean the node ports for all of the services in your cluster? – Robert Bailey Jun 06 '16 at 23:15
  • Yes. Like the command :kubectl get endpoints. root@jya-SBCR:/home/jya/work# kubectl get endpoints NAME ENDPOINTS AGE ebaserdb-ommp-service 172.16.43.6:3306 10d ebaserdb-service 172.16.43.8:3306 11d ivlm2-service 172.16.43.4:8080 11d kubernetes 10.46.178.197:6443 26d Can I get the node ports for all of the services in one cluster? – kevin Jun 07 '16 at 01:17
  • The only way to do it (that I know of) is to write a short script that iterates over the services from `kubectl get services` and runs each one through `kubectl describe service`. – Robert Bailey Jun 11 '16 at 06:38
12

To get extended information about service ports:

kubectl describe service -A

To get only service endpoints:

kubectl get endpoints -A

To limit the output by node IP, you can grep by a network mask or use a more sophisticated script.

Vanuan
  • 31,770
  • 10
  • 98
  • 102
12
kubectl get svc --all-namespaces -o go-template='{{range .items}}{{ $save := . }}{{range.spec.ports}}{{if .nodePort}}{{$save.metadata.namespace}}{{"/"}}{{$save.metadata.name}}{{" - "}}{{.name}}{{": "}}{{.nodePort}}{{"\n"}}{{end}}{{end}}{{end}}'

This gets not just the used nodeports but the name of the nodeport, the service name and namespace of the service in this format:

<namespace>/<service name> - <nodeport name>: <nodeport>
H.Peter
  • 121
  • 1
  • 2
8

...and you can perform the same solution alternatively with a JsonPath...

  • get the external Port (the "nodePort") of myservice corresponding to the internal port 1234

     kubectl get svc myservice -o=jsonpath='{.spec.ports[?(@.port==1234)].nodePort}'
    
  • get a list of all IPs of the Nodes underlying your cluster, in one line

     kubectl get node -o=jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}'
    

Obviously this information can easily be combined into a convenient bash script to suit any specific needs...

#!/bin/bash
#
# discoverService - extract the externally visible Node-IP and port for a specific Service in Kubernetes
#
KUBECTL=kubectl
#
if [[ $# < 2 || "$1" == "-h" ]]
    then
    echo discoverService SERVICENAME INTERNALPORT
    exit -1
fi
SERVICENAME=$1
INTERNALPORT=$2

EXTPORT=`${KUBECTL} get svc $SERVICENAME -o=jsonpath="{.spec.ports[?(@.port==${INTERNALPORT})].nodePort}"`

EXTIP=`${KUBECTL} get node -o=jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}'`


if [[ -z $EXTPORT ]]
    then
    echo -e "ERROR: service=$SERVICENAME internal-port=$INTERNALPORT not found.\n"
    exit -2
elif [[ -z $EXTIP ]]
    then
    echo -e "ERROR: could not retrieve underlying node IPs.\n"
    exit -2
fi
# Success...
echo $EXTIP:$EXTPORT
zhrist
  • 1,169
  • 11
  • 28
Ichthyo
  • 8,038
  • 2
  • 26
  • 32
  • The `nodePort` example has a lil typo - it should read instead: `kubectl get svc myservice -o=jsonpath='{.items[*].spec.ports[?(@.port==1234)].nodePort}` – Carsten Nov 21 '20 at 23:39
0

Missing part for me was actual IP address of minikube

---->$:kubectl describe service --all-namespaces | grep -i nodeport
Name:                     my-nodeport-service
Type:                     NodePort
NodePort:                 <unset>  30007/TCP
---->$:curl $(minikube ip):30007
Ryu S.
  • 1,538
  • 2
  • 22
  • 41
0

For the ones who want to get the hostIP as well, here is a command who:

  • Use a specific NAMESPACE (default to the current-context one)
  • Get the HostIP
  • Get the NodePort
# if want to explicit choose a NAMESPACE uncomment the line bellow and change the value
# NAMESPACE=default && \
if [[ -z $NAMESPACE ]]; then NAMESPACE="$(kubectl config view --minify -o jsonpath='{..namespace}')"; fi && \
kubectl get pod -o=custom-columns=POD_NAME:.metadata.name,IP:.status.hostIP --namespace=${NAMESPACE} && \
kubectl get svc -o=custom-columns=SVC_NAME:.metadata.name,PORT:.spec.ports[0].nodePort --namespace=${NAMESPACE}
jvitor83
  • 220
  • 8
  • 20