Ingress in Kubernetes
Published in
4 min readApr 23, 2022
What happens w/o Ingress in an On-Premise Cluster
Initial Requirement:
- Build and Deploy an apparel store
- Should be available at www.my-apparelstore.com
Steps:
- Build application docker image
- Deploy it in K8s cluster (app1)
- Deploy a DB pod (MySQL)
- Create a cluster-ip service to make DB pod accessible.
- Create a NodePort service to make app1 accessible to outside world.
- The NodePort service as per diagram is ‘app1-service’ which listens at 38080 port.
- App is now accessible at http://node-ip:38080.
- Create a DNS with a domain ‘my-apparel-store’ that maps to the node-ip.
- So now the URL is www.my-apparelstore:30080.com
- In order to get rid of the port, create a proxy server that exposes port 80 and redirects to Node’s 38080.
- Change DNS mapping to proxy-server-ip instead on Node-IP.
- So now the URL is www.my-apparelstore.com
What happens w/o Ingress in a Managed Cloud
Everything remains as it is, except a few:
- Replace the NodePort service with a LoadBalancer service.
- This will provide the same functionality as a NodePort but will also ask the Managed Cloud Platform to provision an NLB.
- So now creating a ProxyServer is not required.
- The DNS points to the NLB ip instead of previous proxy server.
What happens w/o Ingress if another app is introduced
Changes if you wish to support another app:
- Deploy app2 with similar setting: a Deployment, a LoadBalancer service, if required a separate DB pod, etc.
- Additionally another load balancer needs to be introduced apart from existing app1’s NLB and upcoming app2’s NLB2.
- That additional load balancer will redirect traffic to downstream NLBs based on route.
Challenges
- To introduce a new service or app, you have to reconfigure the top level load balancer.
- If SSL needs to enabled, the confusion where to do that as it can be done on various levels.
- Difficult to manage various configurations as the apps scale.
Would be great to have:
- If all configurations can be managed within the cluster.
- As a K8s definition file like done in other K8s objects.
Ingress to the rescue.
How the above configuration gets simplified with Ingress
What is Ingress
It has two parts:
- Ingress controller: An abstraction over nginx/HAPROXY/trafik/Istio which are basically load balancing solutions. This is not created by default though when cluster is created.
- Ingress resource: A set of configurations like defining URL routes, SSL certificates, etc.
How Ingress works
- Lets say, the Ingress controller in your cluster is built over nginx.
- The Ingress controller has additional intelligence to detect any new Ingress resource, pick their configurations and apply on the nginx .conf file.
- Similarly, as and when the resource is removed, the Ingress controller makes changes to the underlying nginx conf file as well.
Ingress Controller Configuration
It is combination of four K8s objects:
- Deployment: An abstraction over nginx image.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress-controller
spec:
replicas: 1
selector:
matchLabels:
name: nginx-ingress
template:
metadata:
labels:
name: nginx-ingress
spec:
containers:
- name: nginx-ingress-controller
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.21.0
args:
- /nginx-ingress-controller
- --configmap=$(POD_NAMESPACE)/nginx-configuration
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
- Service: To expose the deployment.
apiVersion: v1
kind: Service
metadata:
name: nginx-ingress
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
- port: 443
targetPort: 443
protocol: TCP
name: https
selector:
name: nginx-ingress
- ConfigMap: to feed nginx configuration data like sslprotocol, logpath, etc.
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-configuration
- ServiceAccount: To apply Ingress resource configurations. The service accounts must have right set of roles, clusterroles and rolebindings configured.
apiVersion: v1
kind: ServiceAccount
metadata:
name: nginx-ingress-serviceaccount
Ingress Resource Configuration
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-service
spec:
rules:
- host: my-apparelstore.com
http:
paths:
- path: /app1
backend:
serviceName: app1
servicePort: 8080
- host: my-apparelstore.com
http:
paths:
- path: /app2
backend:
serviceName: app2
servicePort: 8080