I recently started building Kubernetes cluster in my on-prem network where I do not have OpenStack or OpenShift that can provide me load balancer IP. Most cloud platforms have load balancer logic already written that can provision IP address upon service is created with type LoadBalancer. In my senario, I will expose my application service via type NodePort that will expose port on all the worker nodes and redirect traffic to right pod.

NOTE: You will need to manually enter NODE_IP:EXPOSE_PORT in your on-prem load balancer. If you have an automation that can do for you thats great!

To expose your pod to outside Kubernetes cluster, you need to create a yaml file and then deploy it on your master node. There are other ways to expose pod service via command line as well. I will go over in the end of this section.

I will first create a pod and then I will go over services. If you already know how to create pods with labels, you can skip this section.

Deploy Pod

kubectl run nginx-demo --image=nginx --port=80 --labels="name=nginx-demo"

Execute kubectl get pods to get status of the pod that was just created

rahil@k8s-master-node:~$ kubectl get pods
NAME                             READY     STATUS    RESTARTS   AGE
nginx-demo-74df6b89b6-lkjvq      1/1       Running   0          1m

Once the pod is created and it is in running status, we will go ahead and get started with services to create NodePort.

Create NodePort service

NodePort service exposes a port on every server that will redirect traffic to your pod. You can dynamically generate a port or assign static port as long as it is available.

Defining yaml file to create NodePort.

vi nginx-demo-nodeport-svc.yaml

Insert below details in above file.

apiVersion: v1
kind: Service
  name: nginx-demo
    name: nginx-demo-nodeport-svc
  type: NodePort
    - port: 80
      nodePort: 30180
      name: http
    - port: 443
      nodePort: 31443
      name: https
    name: nginx-demo

Let's create a deployment to create NodePort service.

kubectl create -f nginx-demo-nodeport-svc.yaml

Execute kubectl get services to get services for recently created service.

rahil@k8s-master-node:~$ kubectl get services
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
kubernetes   ClusterIP       <none>        443/TCP                      4d
nginx-demo   NodePort   <none>        80:30180/TCP,443:31443/TCP   1m

Once you have created a service you should see nginx-demo service created with ports that were defined in yaml file.

Now let's get the node IP where our pod is hosted. Then we can execute curl or browse it in browser.

kubectl get pods -o wide


rahil@k8s-master-node:~$ kubectl get pods -o wide
NAME                             READY     STATUS    RESTARTS   AGE       IP            NODE
nginx-demo-74df6b89b6-lkjvq      1/1       Running   0          44m   k8s-worker-node1
$ nslookup k8s-worker-node1


Performing test

Using Curl:

rahil@k8s-master-node:~$ curl
<!DOCTYPE html>
<title>Welcome to nginx!</title>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>

Browse in browser:

Using Command line to create NodePort service

kubectl expose deployment nginx-demo --port=80 --type=NodePort


rahil@k8s-master-node:~$ kubectl get services
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP       <none>        443/TCP        4d
nginx-demo   NodePort    <none>        80:32546/TCP   4s

NOTE: When you create deployment for NodePort via command line, you cannot manually assign port. Cluster will automatically assign one dynamically. If you must assign port manually. Use yaml template and create a deployment.