NodePort

NodePort Exposes the service on each Node’s IP at a static port (the NodePort). A ClusterIP service, to which the NodePort service will route, is automatically created. You’ll be able to contact the NodePort service, from outside the cluster, by requesting <NodeIP>:<NodePort>.

We can access the service on any <NodeIP>:NodePort. If you set the type field to “NodePort”, the Kubernetes master will allocate a random port from a range (default range is 30000-32767), and each Node will proxy that port (the same port number on every Node) into your Service. You can specify the particular nodeport also.

How nodePort works

NodePort

kube-proxy watches the Kubernetes master for the addition and removal of Service and Endpoints objects.

(We will discuss about Endpoints later in this session.)

For each Service, it opens a port (randomly chosen) on the local node. Any connections to this “proxy port” will be proxied to one of the Service’s backend Pods (as reported in Endpoints). Lastly, it installs iptables rules which capture traffic to the Service’s clusterIP (which is virtual) and Port and redirects that traffic to the proxy port which proxies the backend Pod.

nodePort workflow.

  1. nodePort -> 30391
  2. port -> 80
  3. targetPort -> 9090

When would you use this?

There are many downsides to this method:

  • You can only have once service per port
  • You can only use ports 30000–32767
  • If your Node/VM IP address change, you need to deal with that
  • For these reasons, I don’t recommend using this method in production to directly expose your service. If you are running a service that doesn’t have to be always available, or you are very cost sensitive, this method will work for you. A good example of such an application is a demo app or something temporary.
Create a deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx-ctr
        image: nginx:1.15.4
        ports:
        - containerPort: 80

Let’s Deploy

$ kubectl apply -f nginx-deploy.yaml

Let’s create a NodePort Service

apiVersion: v1
kind: Service
metadata:
  name: nginx-nodesvc
  labels:
    app: nginx
spec:
  type: NodePort
  ports:
  - port: 80
    nodePort: 31009
    protocol: TCP
  selector:
    app: nginx

Let’s deploy the service

$ kubectl apply -f nodeport-svc.yaml
$ kubectl get svc

Get the node IP

$ kubectl get node -o wide

Now try to access the service by http://<IP>:<PORT>

You may need to update the security group of your nodes to allow access to the port.

Delete Service and Pod

$ kubectl delete svc nginx-nodesvc
$ kubectl delete deploy nginx-deployment