Tag Archives: DevOps

Mapping service ports to nodes in Kubernetes

Kubernetes is a great project and cool/hot technology. Although it made me to hate JSON (and YAML), I still enjoy exploring the possibilities it brings to your applications deployment.

It's also a base for even more awesome project called OpenShift (*cough* shameless plug included *cough*).

Anyway, I ran into a problem where I needed to expose port(s) of my application to the outer world (i.e. from Vagrant box to my host) and I struggled to find the solution quickly.

Normally, when you are on the machine where Kubes run, you will do something like this

[vagrant@centos7-adb ~]$ kubectl get services | grep flower
flower-service component=flower app=taskQueue,component=flower 10.254.126.210 5555/TCP

IOW I just listed all running services and grepped for flower. I can take IP and port from there now and use curl to get contents provided by that service. This uses the Kubernetes virtual network to get to the endpoint.

I can also do this

[vagrant@centos7-adb ~]$ kubectl get endpoints | grep flower
flower-service 172.17.0.7:5555

which gets me directly to container IP and port.

But this all happens in my Vagrant box (as you can see from the CLI prompt). This setup is good for places like Google Cloud or AWS where you get load balancing and port forwarding for free. But what if I just want to access my app on the VM IP address?

Well, you take your Kubernetes service config/artefact/JSON/YAML and modify it a bit. By default, Kubernetes services are set to "ClusterIP" mode where they are accessible only by the ways showed above. You'll want to change the type to "NodePort".

This will "use a cluster IP, but also expose the service on a port on each node of the cluster (the same port on each node)" according to docs.

apiVersion: v1
 kind: Service
 metadata:
   labels:
     component: flower
     name: flower-service
spec:
  type: NodePort
  ports:
    - port: 5555
      nodePort: 31000
  selector:
    app: taskQueue
    component: flower

By default, type NodePort will give you a random port in a range 30000-32767. You can also pick a specific port from this range (as you can see above). Well, that's it. You only need to know the IP of the machine and the given/specified port.

[vagrant@centos7-adb vagrant]$ kubectl describe service flower-service | grep "^NodePort"
NodePort: <unnamed> 31000/TCP

This is particularly useful when you are developing (with VM, as the use case described above), or if you have some testing instance in the cloud (where the load balancers are not available) and want to expose the app easily without having to fiddle with too many other pieces.