Adding Contour/Envoy to my Kubernetes Cluster

Contour is and open source Kubernetes ingress controller providing the control plane for the Envoy edge and service proxy. I need a way for my web apps to be displayed. I used the Nginx ingress controller in the past but did not want to mess with annotations. Since my work is going to VMWare Tanzu, I decide to work with Contour.

Installation is pretty easy but there is a change I had to make before install. If you are building in AWS or Google there are plenty of help on the internet. I am building on my Hyper-V stack so load balancing would be different.

#Download the contour yaml to install
$ wget https://projectcontour.io/quickstart/contour.yaml

Locate the Envoy Service section and change the type from LoadBalancer to NodePort
$vim contour.yaml
-----------------------------------
apiVersion: v1
kind: Service
metadata:
  name: envoy
  namespace: projectcontour
...
  selector
    app:envoy                                                                                                                                                                                
  type: LoadBalancer  #<- NodePort
-----------------------------------
------------------------------------

After you have downloaded and changed the type to NodePort, you just issue the kubectl create command

$ kubectl create -f contour.yaml

This will create the projectcontour namespace. Contour install Envoy proxies on all nodes. You will only want to load balance across the work nodes. You will need to have the IPs of the worker nodes and the NodePort create by the contour yaml file.

# gets the node port
$ kubectl -n projectcontour get svc envoy -o=jsonpath='{.spec.ports[?(@.port==80)].nodePort}'

Now to load balance your web app across the worker nodes. I setup nginx on my master node to handle that

$ sudo apt install nginx

Next you need to modify nginx with the following load balancer setup.

$ sudo vim /etc/nginx/sites-available/default
#modify it to have the following
upstream backend {
	server <worker1 node ip>:<envoy port>;
	server <worker2 node ip>:<envoy port>;
}
server {
     listen 80; 
     location / {
       proxy_pass http://backend;
       proxy_set_header Host $host;
     }
}

Replace the worker node IPs section with the actual ips of the worker nodes. Also replace the envoy port with the actual port number you got from the previous kubectl command.

Now enable and start nginx

$ sudo systemctl enable nginx
$ sudo systemctl start nginx

Now on my laptop I modified my /etc/hosts file so the web URL goes to the IP address of the master node. You can setup a DNS resolution server but /etc/hosts works fine for my development operations.