Hey there, setting up an Ingress Controller on your Kubernetes cluster? After reading through many articles and the official docs, I was still having a hard time setting up Ingress. But after numerous attempts I managed to setup an nginx-ingress-controller to forward outside traffic to my in-cluster services, handling HTTP and HTTPS. This writeup is a step by step guide to do this.
Pssst… incase you are a newbie to Kubernetes like me, here is a nice writeup that explains Ingresses.
Kubernetes Ingress_A lot of people seem confused about how Ingress works in Kubernetes and questions come up almost daily in Slack. It’s…_medium.com
We will setup a simple “hello-world” api and expose the api using the nginx-ingress-controller on a local cluster using Minikube.
TL;DR — Here is a boilerplate that reflects what is explained.
Assuming that you already have Kubectl and Minikube setup, let’s deploy our hello-world
api and expose it within our cluster as a NodePort Service. We will be using a simple api for the purpose of the demo. The source code can be found here.
The config file consists of the deployment and the service. Normally we separate them into individual files.
kubectl create -f hello-world.yaml
Now you should be able to see the created resources when you run
kubectl get all | grep hello-world
We need to provide a default backend for the ingress-controller. The default backend
is the default service that Nginx falls backs to if it cannot route a request successfully. The default backend
needs to satisfy the following two requirements :
The nginx-ingress-controller project has an example default backend.
kubectl create -f default-backend.yaml
Create a self-signed certificate using OpenSSL. The common name specified while generating the SSL certificate should be used as the host in your ingress config. We create secrets for the given key, certificate and dhparam files. Use corresponding file names for the key, certificate and dhparam.
kubectl create secret tls tls-certificate --key <key-file>.key --cert <certificate-file>.crt
kubectl create secret generic tls-dhparam --from-file=<dhparam-file>.pem
Minikube versions > v0.14.0 ships with Nginx ingress setup as an add-on. It can be enabled by simply running:
minikube addons enable ingress
Enabling the add-on provisions the following:
Now we create a service for the controller. The service is of type LoadBalancer so that it is exposed outside the cluster.
The config consists of the deployment and service for the nginx-ingress. The following can be observed from the config :
Create the controller by running:
kubectl create -f nginx-controller.yaml
We should be able to see the created resources with the exposed IP address after a few seconds. To get the IP on Minikube run.
minikube service nginx-ingress --url
Running a Curl request to the exposed endpoint should give us a response from the default-backend as we still haven’t configured our ingress to point to our hello-world api.
curl http://<nginx-service-IP>:<port>
default backend - 404%
Coming to the part where we will be spending most of our time. We provide the forwarding rules to the ingress.
We use annotations here to pass configuration params to the underlying ingress-controller, Nginx in our case. You can find more about annotations here.
kubectl create -f ingress.yaml
We now have an Nginx web server configured that routes traffic for api.sample.com to our configured hello-world-svc. It falls back to the default-backend service for unhandled requests.
Also you might want to update /etc/hosts
file to resolve your host to your minikube IP. Assuming your Minikube IP is 192.168.99.101
Your entry should look like.
192.168.99.101 api.sample.com
You should be able to access the exposed endpoints via https.
GET api.sample.com/:namePOST api.sample.com/:namePUT api.sample.com/:name
Adding the annotation ingress.kubernetes.io/ssl-redirect: “true”
to the ingress.yaml
config enables traffic through HTTP and HTTPS.
Ingress does allow you to configure multiple Virtual Hosts, Sticky sessions, Path rewrites and also custom configs, providing a powerful, flexible routing mechanism for Kubernetes.
For more info on nginx-ingress-controller visit https://github.com/nginxinc/kubernetes-ingress
A similar procedure can be used to deploy to AWS, GKE instead of Minikube.
Kubernetes and Ingress in particular is constantly evolving I will try my best to keep this updated. Boy Scout Oath.
Hope you enjoyed reading this as much as I enjoyed writing it. If you think this will be of help to someone? Do not hesitate to share. If you liked it, tap the clap below so other people will see this here on Medium. Don’t forget to show some love by following the blog!
*Update on 11 November 2018* Added RBAC in the example setup. Thanks to Jens Madsen for his contribution.