Setup Kubernetes Ingress on GKE

We have seen in my previous blog how we can access the application externally using Service object. We have two options to get traffic outside the cluster

  • NodePort
  • LoadBalancer

Mostly the load balancer option is preferred in the public cloud providers.

Limitations:

  1. The problem is that one LoadBalancer can only point towards a single Kubernetes service object.

So now if you have 100 microservices -> you need 100 load balancers -> very expensive

2. Let’s suppose that you have a web service running at test.com and you want test.com/users to go to one microservice and test.com/notifications to go to another completely separate microservice. Before the arrival of Ingress, you would need to set up your own Kubernetes Service and do the internal path resolution to your app.

The above issue is resolved using Kubernetes Ingress resource.

Image for post

What is Ingress ?

An API object that manages external access to the services in a cluster, typically HTTP.

It also provides

  • load balancing
  • SSL termination
  • name-based virtual hosting

Simple example where ingress sending all traffic to one service

Image for post

Ingress Controller is responsible for fulfilling the ingress

What is Ingress Controller

In order for the Ingress resource to work, the cluster must have an ingress controller running. There are lot of ingress controllers available, you can find those details from their official documentation.

Here, we will be using nginx ingress controller and do the deployment on GKE as per their document

Prerequisite:

  1. Functional Kubernetes Cluster configured
  2. Clone this git repo

Create an ingress controller

On GKE, we will run the below command which will create an ingress controller on our cluster

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.43.0/deploy/static/provider/cloud/deploy.yaml
Image for post
kubectl get pods -n ingress-nginx
Image for post
kubectl get svc -n ingress-nginx

We can see two services are running for the nginx-controller

Image for post

Basic Example of using Kubernetes Ingress Resource

Now we will run a sample application configured in this yaml file and expose it externally using Kubernetes Ingress Resource

apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: default
spec:
selector:
matchLabels:
run: web
template:
metadata:
labels:
run: web
spec:
containers:
- image: gcr.io/google-samples/hello-app:1.0
imagePullPolicy: IfNotPresent
name: web
ports:
- containerPort: 8080
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: web
namespace: default
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
run: web
type: NodePort

Run the below command

cd ingress/basic-example
kubectl apply -f web.yaml
Image for post

Now we will deploy an ingress resource

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: basic-ingress
spec:
backend:
serviceName: web
servicePort: 8080

Run the below command

kubectl apply -f basic-ingress.yaml
Image for post
kubectl get ingress
Image for post

Run the command again if IP didn’t come

Note: It might take a few minutes for GKE to allocate an external IP address and set up forwarding rules before the load balancer is ready to serve your application. You might get errors such as HTTP 404 or HTTP 500 until the load balancer configuration is propagated across the globe.

You will see in your google account that one load balancer is getting created

Image for post

Now you can open this IP on the browser

Image for post

In this example, no host is specified, so the rule applies to all inbound HTTP traffic through the IP address specified. If a host is provided (for example, test.com), the rules apply to that host.

Simple Fanout

A fanout configuration routes traffic from a single IP address to more than one Service, based on the HTTP URI being requested.

This yaml file will deploy 2 deployments( web and web1) and 2 services ( web and web1)

apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: default
spec:
selector:
matchLabels:
run: web
template:
metadata:
labels:
run: web
spec:
containers:
- image: gcr.io/google-samples/hello-app:1.0
imagePullPolicy: IfNotPresent
name: web
ports:
- containerPort: 8080
protocol: TCP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web2
namespace: default
spec:
selector:
matchLabels:
run: web2
template:
metadata:
labels:
run: web2
spec:
containers:
- image: gcr.io/google-samples/hello-app:2.0
imagePullPolicy: IfNotPresent
name: web2
ports:
- containerPort: 8080
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: web
namespace: default
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
run: web
type: NodePort
---
apiVersion: v1
kind: Service
metadata:
name: web2
namespace: default
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
run: web2
type: NodePort

Run the below command

cd ingress/fanout-example
kubectl apply -f web.yaml

Now we will create an fanout ingress configuration


apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: fanout-ingress
spec:
rules:
- http:
paths:
- path: /v1/*
backend:
serviceName: web
servicePort: 8080
- path: /v2/*
backend:
serviceName: web2
servicePort: 8080

Run the command

kubectl apply -f fanout-ingress.yaml

Name-Based hosting

For name based hosting will be providing the hostname configuration in our yaml file

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: host-ingress
spec:
rules:
- host: "test.com"
http:
paths:
- path: /test
backend:
serviceName: web
servicePort: 8080
- host: "abc.com"
http:
paths:
- path: /abc
backend:
serviceName: web2
servicePort: 8080

Run the below command

cd ingress/name-host
kubectl apply -f web.yaml
kubectl apply -f host-ingress.yaml

To access this url, edit /etc/hosts file on Mac

Add a line

IP of ingress   test.com
Image for post

Now try to access the browser as shown below:

Image for post
Image for post

References

  1. https://cloud.google.com/kubernetes-engine/docs/tutorials/http-balancer
  2. https://kubernetes.io/docs/concepts/services-networking/ingress/

example

Written by

Devops Automation Enginneer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store