NGINX Ingress Controller in GKE
GKE in Production - Part 2
This tutorial is part of a series I am creating on creating, running and managing Kubernetes on GCP the way I do in my day job. In this episode, we are covering how to setup a nginx ingress controller to handle incoming requests.
Note: There may be some things I have skimmed over, if so or you see a glaring hole in my configuration, please drop me a line via the contact page linked at the top of the site.
What we will build
In this second installment, we will be adding an nginx ingress controller to our GKE cluster from part 1. (You can find it here: https://www.ianbrown.id.au/kubenetes_basic_setup)
What you will need
You will need:
- Everything already running from Part 1.
- Willingness to learn k8s, helm, let’s encrypt and nginx configurations.
Pre-Requisites
In order to complete this tutorial, we will need to install helm.
Helm is the package manager for kubernetes. It is a simple tool that allows any admin to deploy new applications within a cluster using predictable commands.
Download and Install Helm
The first thing to do is head over to https://github.com/helm/helm/releases and download the latest version of the helm client for your machine.
For me, this is https://get.helm.sh/helm-v3.0.0-linux-amd64.tar.gz
Now we need to unpack it with the following command:tar -zxvf helm-v3.0.0-linux-amd64.tar.gz
This created a directory called linux-amd64
for me. Yours will be different if you are using a different OS.
Now we need to move the helm exe to a location in my $PATH.
This is simply a case of typing:sudo mv linux-amd64/helm /usr/local/bin/helm
For Windows users, pick a location in your systems %PATH%, or add the path to the helm.exe to your PATH environment variable.
Confirm helm is working
Again, we should confirm everything is working before proceeding.
Type: which helm
(where helm
on Windows) to should return the location we moved the exe to in the last step. (/usr/local/bin/helm)
And then, to ensure there is nothing missing, get the helm version with:helm version
Mine shows v3.0.0.
Deploy the NGINX Ingress Controller
- Before we start deploying with helm, we need to add the NGINX ingress repo:
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
- Now we can deploy the ingress controller and service:
helm install nginx-ingress ingress-nginx/ingress-nginx --set rbac.create=true
Let’s break this one down a bit:helm install
is us calling the install method of the helm executable.nginx-ingress
is the name of the helm chart we want to install.ingress-nginx/ingress-nginx
is a tricky way of installing into a namespace. In this instance, we are installing the chart in the ingress-nginx
namespace and calling it ingress-nginx
.--set rbac.create=true
enable role based access control. Read more about it here: https://kubernetes.github.io/ingress-nginx/deploy/rbac/
- Verify that the ingress controller and service are both deployed with:
kubectl get deployment nginx-ingress-ingress-nginx-controller
kubectl get service nginx-ingress-ingress-nginx-controller
The output should look something like this:
- Take note of the
EXTERNAL-IP
provided in the service as we will need to use that later.
This will also be the IP that all DNS hostnames should point to for the various deployments of your applications.
We will be using 1.2.3.4 as the external IP from this point forward just in case the one I have used is now in use by another customer. :)
Deploy the hello-world app
As we did in the last tutorial, we need to have something to point the ingress resource at. For this we will use the same hello-world app Google provides as a sample.
To deploy the hello-world app, simple type:kubectl create deployment hello-world --image=gcr.io/google-samples/hello-app:1.0
Then expose the deployment as a service with:kubectl expose deployment hello-world --port=8080 --target-port=8080
Note here that we are no longer using port 80 on the public side!
Create an Ingress Resource
An Ingress Resource is a collection of Layer 7 rules for routing inbound traffic to services in Kubernetes.
Many rules can be defined in a single Ingress Resource or they can be split into multiple manifests. I generally keep a single Ingress Resource manifest per application to keep things simple.
Create the Ingress Resource YAML
Create a simple Ingress Resource YAML file to use the NGINX Ingress Controller with a single path since our hello-world app only has a single exposed port:
cat <<EOF > ingress-resource.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-resource
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- host: "1.2.3.4.nip.io"
http:
paths:
- pathType: Prefix
path: "/hello"
backend:
service:
name: hello-world
port:
number: 8080
EOF
There is a lot going on here, so let’s break it down.kind: Ingress
defines the object as an Ingress Resource.
The name
value here is what is set in GKE, so if you have many ingress resources, you have full license to get creative with the names. :)
The annotations here are important.kubernetes.io/ingress.class: "nginx"
defines that this is an NGINX Controller ingress.
If you wanted to use GCE instead, simply change it to: kubernetes.io/ingress.class: gce
The ssl-redirect
line tells nginx not to redirect all requests to the HTTPS equivilent. This will be important in a future part.
A full list of annotations is available here: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/
rules
defines the rules to be applied as follows:
host
sets the FQDN that should be matched to use this Ingress Resource.
In this instance, we use the nip.io service to return the IP we set in the hostname part.
i.e. 1.2.3.4.nip.io will return an IP of 1.2.3.4
path
is the path to the backend hello-world pod on port 8080.
Apply the configuration
To apply the configuration to kubernetes, simply run:kubectl apply -f ingress-resource.yaml
Note that you can update the ingress resource by simply editing the YAML and running the same command again.
Verify the Ingress Resource is created by typing:kubectl get ingress ingress-resource
Test our work
Now the moment of truth!
Open your favourite web browser and hit up the below url:http://1.2.3.4.nip.io/hello
If everything went well, you should see that same hello world page from part 1. If not, check to ensure you haven’t missed a step or that the ingress resource is up and running.
Join me in the next part as we install Let’s Encrypt certificate services to the cluster so you never have to pay for an SSL certificate again!