Exposing pod as a NodePort service

Expose service via nodeport.

I recently started building a Kubernetes cluster in my on-premise network where I do not have OpenStack or OpenShift that can provide me load balancer IP. Almost all cloud platforms come with ready-made load balancer logic that automatically assigns an IP address when a service of type LoadBalancer is created. In my scenario, 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-premise load balancer. If you have an automation that can do for you, that’s 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

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

Defining YAML file to create NodePort.

vi nginx-demo-nodeport-svc.yaml

Insert the below details in the above file.

apiVersion: v1
kind: Service
metadata:
  name: nginx-demo
  labels:
    name: nginx-demo-nodeport-svc
spec:
  type: NodePort
  ports:
    - port: 80
      nodePort: 30180
      name: http
    - port: 443
      nodePort: 31443
      name: https
  selector:
    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 services.

rahil@k8s-master-node:~$ kubectl get services
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP                      4d
nginx-demo   NodePort    10.98.148.146   <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

output:

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       10.244.1.15   k8s-worker-node1
$ nslookup k8s-worker-node1Address: 192.168.0.151

Performing test

Using Curl:

rahil@k8s-master-node:~$ curl 192.168.0.151:30180
<!DOCTYPE html>
<html>

<head>
    <title>Welcome to nginx!</title>
    <style>
        body {
            width: 35em;
            margin: 0 auto;
            font-family: Tahoma, Verdana, Arial, sans-serif;
        }
    </style>
</head>

<body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed andworking. 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>
</body>

</html>

Using the command line to create NodePort service

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

Output:

rahil@k8s-master-node:~$ kubectl get services
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        4d
nginx-demo   NodePort    10.100.95.81    <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.

Leave a Comment

Scroll to Top