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.