How to expose a Kubernetes service on a specific Nodeport?

9/26/2018

I have create a pod with the below yaml definition.

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image: praveensripati/docker-demo:1.2
    ports:
    - containerPort: 3000

And now I expose the pod, which creates a service.

kubectl expose pod myapp-pod --type=NodePort

The port 3000 on the container is exposed to port 31728 on the nodes. And I am able to do access the page using curl on port 31728.

kubectl get service myapp-pod
NAME        TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
myapp-pod   NodePort   10.107.254.254   <none>        3000:31728/TCP   5s

This time I wanted to expose the service not a random port, but on port 80. And so I specify the port number as 80, by using --port. The service details are a bit odd. It says that port 80 on the container is exposed to port 31316 on the nodes. Also, I am able to access the page using curl on the random port (31316 in this case) and not port 80.

kubectl expose pod myapp-pod --type=NodePort --target-port=3000 --port=80

kubectl get service myapp-pod
NAME        TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
myapp-pod   NodePort   10.105.123.73   <none>        80:31316/TCP   12s

I am not able to expose a service on a specific port and not on a random port. I tried a few combinations and read the k8s documentation, but no success.

How do I expose a service on a specific port instead of a random port?

-- Praveen Sripati
kubernetes
service

5 Answers

9/26/2018

Your question is about exposing the NodePort type of service on a specific port. For that you need to specify the nodePort field under ports in your service definition.

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  selector:
    app: myapp
  ports:
  - protocol: TCP
    port: 3000
    nodePort: 32321
  type: NodePort

Note that it has to be within a given range provided in the configs. Which defaults to 30000-32767. This range can be specified in the kube-apiserver configs using the --service-node-port-range option.

-- Rico
Source: StackOverflow

3/15/2019

If your cluster does not have a LoadBalancer Provider, you can specify externalIPs in IP of nodes' network interface.

For example:

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:   
  type: ClusterIP
  externalIPs:
    - 125.100.99.101 # Node1-IP
    - 125.100.99.102 # Node2-IP
    - 192.168.55.112 # Node2-IP2
  selector:
    pod: nginx
  ports:
    - name: http
      port: 80      
    - name: https
      port: 443      

This will listen 80 and 443 on the specified node, and forward to the nginx service.

-- RFC 7676
Source: StackOverflow

4/14/2019

When an existing Dashboard service already exists, remove it.

kubectl delete service kubernetes-dashboard -n kube-system

Expose the Dashboard deployment as a NodePort.

kubectl expose deployment kubernetes-dashboard -n kube-system --type=NodePort

The above will assign a random port >= 30000. So use the Patch command to assign the port to a known, unused and desired port >= 30000.

kubectl patch service kubernetes-dashboard --namespace=kube-system --type='json' --patch='[{"op": "replace", "path": "/spec/ports/0/nodePort", "value":30000}]'

Caution: Never expose your dashboard publicly without authentication.

-- javajon
Source: StackOverflow

9/26/2018

I will try to answer your query here.

Also, I am able to access the page using curl on the random port (31316 in this case) and not port 80.

-- Because, kubernetes exposed the port 31316 on the host (maps to the service) and hence it can be accessed on host:31316.

-- Service port is visible only within the kubernetes cluster. You can exec into a pod container and do a curl on servicename:service port instead of the NodePort.

Note the terms - container port: the port container listens on. Service port: the port where kubernetes service is exposed on cluster internal ip and mapped to the container port. Nodeport: the port exposed on the host and mapped to kubernetes service.

-- techuser soma
Source: StackOverflow

2/5/2019

we can expose Kubernetes service on specific node port.

Port value must be between 30000-32767.

We can expose service to specific port of below service types:

  1. NodePort

  2. LoadBalancer

Find the sample myservice.yaml file below:

apiVersion: v1
kind: Service
metadata:
  name: app1
spec:
  type: NodePort/LoadBalancer
  ports:
  - name: "80"
    port: 80
    nodePort: 32062
    targetPort: 80
  selector:
    appone: app1
    app: test

Note: In above service yaml file we can specify service type either NodePort or Loadbalancer.

-- kalyani chaudhari
Source: StackOverflow