Load Balancing "Hello World" Kubernetes application

2/23/2020

To start playing with Kubernetes I created a small project where I create a three nodes cluster on my local machine using Vagrant and Vbox: https://github.com/sasadangelo/k8s-cluster

Just typing vagrant up my cluster is up and running and I can start to play with it. I got familiar with the main concepts and commands and created a simple "Hello World" application composed by a docker image with an NGINX web server where you can connect via browser and a "Hello World" message appears with the hostname. The hostname helps me to understand which Pod responded to my request.

Here the project: https://github.com/sasadangelo/k8s-tutorials/tree/master/hello-k8s

Currently, I can create a deployment with kubectl create exposing it as a service with kubectl expose and then increase replica with kubect scale. At the moment, I am able to use use NodePort service, so with kubectl describe service I can see on which IP the 5 Pods listen, I connect to them and everything works fine.

My problem is that now I want to load balance the traffic. I want to connect to a single IP and as soon as I click on the browser Reload button I want to see that different Pod names appear.

I know that Kubernetes by default offers only NodePort service and if I want a load balancer I need something like an Ingress. I also know that a simple reverse proxy like Ingress Nginx is a good implementation for my needs.

However, I read lot of tutorials but I have hard time understanding how I should configure it to achieve what I need.

Here code I have so far: https://github.com/sasadangelo/k8s-cluster/tree/master/ingress

Can anyone help me how to fix Ingress code to achieve what I need?

-- Salvatore D'angelo
kubernetes
kubernetes-ingress
nginx-ingress

2 Answers

3/4/2020

Here is what I have done in detail to solve the issue. First of all, I installed Nginx Ingress resources:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml

then I create an Nginx Ingress resource in a ingress-nginx.yaml file:

---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: hello-k8s-ingress
  annotations:
     nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - host: hello-k8s.info
      http:
      paths:
    - path: /
      backend:
        serviceName: hello-k8s
        servicePort: 80

and installed it with the command:

kubectl apply -f ingress-nginx.yaml

You can see code here.

Inside the cluster (doing vagrant ssh on whatever node) I tested:

curl -H "Host: hello-k8s.info" IP

where IP is got from the command:

kubectl get ingress

Suppose it is 10.97.139.101. Outside the cluster, on my Mac (Running on 3 VirtualBox on my Mac) to access the application I needed to add a route:

sudo route add -net 10.97.0.0/16 192.168.205.10

where 192.168.205.10 is the IP of the master node. In /etc/hosts I added the line:

10.97.139.101 hello-k8s.info

Now typing hello-k8s.info in the browser I see the "Hello World" web page appear. Thanks to Arghya Sadhu for help.

-- Salvatore D'angelo
Source: StackOverflow

2/23/2020

Kube Proxy which is a kubernetes component provides load balancing at L4 layer via iptables load balancing.So with ClusterIP type service itself you get load balancing between pods. But with clusterIP type service you can not access it from outside the cluster i.e from a browser. Nodeport type service provides access to the pods from outside the cluster with load balancing at L4 layer by kube proxy.

LoadBalancer and Ingress provides load balancing and rule based routing at L7 layer if that's what you are looking for.

Looking at your code you have yamls for nginx ingress controller and exposed it as Nodeport. What you need next is to create an ingress resource

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
  - host: hello-world.info
    http:
      paths:
      - path: /
        backend:
          serviceName: web
          servicePort: 8080

Once you create above ingress and you have a ClusterIP type service for your pod with a name web which exposed port 8080, You should be able to access it.

Here is the doc on using nginx ingress for an hello world application on Minikube which you can follow to make ingress work in your setup as well.

-- Arghya Sadhu
Source: StackOverflow