How to expose a Kubernetes service on a specific Nodeport?

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.


I had the same problem and the only way I found to do it without modifying the files was:

k expose --type=NodePort deployment nginx --port 80 --name nginx-ep-patch  --overrides '{ "apiVersion": "v1","spec":{"ports": [{"port":80,"protocol":"TCP","targetPort":80,"nodePort":30080}]}}'
service/nginx-ep-patch exposed

In this way we path online the configuration and the port 30080 has been exposed:

$ k describe svc nginx-ep-patch
Name:                     nginx-ep-patch
Namespace:                default
Labels:                   app=nginx
Annotations:              <none>
Selector:                 app=nginx
Type:                     NodePort
IP:                       10.96.51.148
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30080/TCP
Endpoints:                10.244.0.6:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

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.


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.