Understanding Kubernetes Ingress Controllers: Working, Benefits and Configuration.
Muhammad Abdullah
DevOps Engineer | AWS Architect | Automation Expert | Container Maestro (Docker, Kubernetes) | Infrastructure as?Code?Maestro | Azure DevOps
Before talking about the ingress controller, let me first explain:
? What is ingress?
Ingress exposes HTTP and HTTPS routes from outside the cluster to services within the cluster. Traffic routing is controlled by rules defined on the Ingress resource.
Ingress is not a type of service. Instead, it is an entry point in front of multiple services in the cluster. It is a collection of routing rules governing how external users access services running inside a Kubernetes cluster.
The above image is a simple example where an Ingress sends all its traffic to one Service.
? What is an Ingress controller?
An Ingress controller acts as a reverse proxy and load balancer, implementing a Kubernetes Ingress. It adds a layer of abstraction to traffic routing, accepting traffic from outside the Kubernetes platform and distributing it to Pods running inside the platform. The Ingress controller translates configurations from Ingress resources into routing rules that reverse proxies can recognize and implement. Essentially, an Ingress controller is an intelligent Layer-7 load balancer that allows simple host or URL-based HTTP routing. It is always implemented using a third-party proxy and is responsible for fulfilling the Ingress, typically with a load balancer, but it can also configure your edge router or additional frontends to manage the traffic.
? How an Ingress Controller Works in Kubernetes?
An Ingress Controller in Kubernetes is responsible for managing the routing of external HTTP(S) traffic to services within the cluster based on rules defined in Ingress resources. Here's a step-by-step explanation of how an Ingress Controller works:
Before an Ingress resource can route traffic, an Ingress Controller must be deployed in the Kubernetes cluster. This can be done using a variety of Ingress Controllers such as NGINX etc.
Example: Deploying NGINX Ingress Controller
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml
This command deploys the NGINX Ingress Controller which includes necessary components like deployments, services, and config maps.
2. Creation of Ingress Resource:
We create Ingress resources to define routing rules, including host-based and path-based routing.
Example Ingress resource YAML:
# apache-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: apache-ingress
namespace: ingress-nginx
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: aws.digitxel.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: apache-service
port:
number: 80
- host: aws1.digitxel.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: custom-apache-service
port:
number: 80
3. Ingress Controller Monitors API Server:
The Ingress Controller monitors the Kubernetes API server for new or updated Ingress resources.
4. Configuration Update:
When an Ingress resource is created or updated, the Ingress Controller reads the Ingress rules and updates its internal configuration. This usually involves configuring a load balancer or reverse proxy to handle the traffic as specified by the Ingress rules.
For instance, in the case of the NGINX Ingress Controller, it updates the NGINX configuration file to route traffic according to the new rules.
5. Routing Traffic:
Once the Ingress Controller has updated its configuration, it starts routing incoming traffic to the appropriate backend services based on the defined rules.
6. Handling SSL/TLS Termination:
If the Ingress resource includes TLS configuration, the Ingress Controller manages SSL/TLS termination. This means it terminates the SSL connection and forwards the decrypted traffic to the backend services.
Example TLS Configuration in Ingress Resource:
# apache-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: apache-ingress
namespace: ingress-nginx
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- hosts:
- app.example.com
secretName: tls-secret
rules:
- host: aws.digitxel.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: apache-service
port:
number: 80
7. Service Interaction:
The Ingress Controller routes the traffic to the appropriate service based on the Ingress rules. The services then handle the requests, usually directing them to the appropriate pods.
? Create the TLS Secret:
I have created the Ingress rule for TLS/SSL in step 7, but now I want to add a step to create the SSL/TLS certificates. Here are the YAML files to create a Kubernetes Secret for storing the TLS/SSL certificates:
1. Create a file named tls-secret.yaml:
apiVersion: v1
kind: Secret
metadata:
name: tls-secret
namespace: default # Replace with your namespace if different
type: kubernetes.io/tls
data:
tls.crt: <base64-encoded-tls-cert> # Replace with your base64-encoded certificate
tls.key: <base64-encoded-tls-key> # Replace with your base64-encoded key
? Example of Base64 Encoding:
If you need to encode your certificate and key, you can use the following commands. Assuming you have your certificate file named tls.crt and your key file named tls.key:
base64 -w 0 tls.crt > tls.crt.base64
base64 -w 0 tls.key > tls.key.base64
The contents of tls.crt.base64 and tls.key.base64 will be the base64 encoded versions of your certificate and key.
? Example with Encoded Values
Replace <base64-encoded-tls-cert> and <base64-encoded-tls-key> with the actual base64-encoded content from the files tls.crt.base64 and tls.key.base64.
apiVersion: v1
kind: Secret
metadata:
name: tls-secret
namespace: default
type: kubernetes.io/tls
data:
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk... # Base64 encoded certificate
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0t... # Base64 encoded key
? Applying the YAML File:
kubectl apply -f tls-secret.yaml
This will create a Secret in your Kubernetes cluster that stores the TLS/SSL certificate and key. You can then reference this Secret in your Ingress resources to enable HTTPS.
? Components of an Ingress Controller:
An Ingress Controller is a critical component in Kubernetes that manages external access to services within a cluster. It acts as a reverse proxy, routing incoming traffic from outside the cluster to the appropriate services based on predefined rules. Here are the main components of an Ingress Controller:
It's important to note that while the Ingress Controller itself is a core Kubernetes component, the specific implementation and features may vary depending on the Ingress Controller solution you choose (e.g., NGINX Ingress Controller, Traefik Ingress Controller, etc.).
? Deploying Apache Web Server with Different Content for Different Hostnames on Kubernetes
In this article, we'll walk through how to deploy an Apache web server on Kubernetes, and configure it to serve different content based on different hostnames (i have used these subdomains: aws.digitxel.com and aws1.digitxel.com).
Prerequisites
I use minikube:
? Step 1: Enable Ingress Addon:
$ minikube addons enable ingress
? Step 2: Create Namespace (Optional but recommended):
#ingress-nginx-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx
Apply namespace:
领英推荐
$ kubectl apply -f ingress-nginx-namespace.yaml
? Step 3: Deploy Apache (Custom image):
Save the following YAML as "custom-apache-deployment.yaml" and apply it :
#custom-apache-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: custom-apache-deployment
namespace: ingress-nginx
labels:
app: custom-apache
spec:
replicas: 1
selector:
matchLabels:
app: custom-apache
template:
metadata:
labels:
app: custom-apache
spec:
containers:
- name: custom-apache
image: httpd:2.4
ports:
- containerPort: 80
Deploy your custom Apache server:
$ kubectl apply -f custom-apache-deployment.yaml
? Step 4: Deploy Apache (Standard image):
Save the following YAML as "apache-deployment.yaml" and apply it :
#apache-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: apache-deployment
namespace: ingress-nginx
labels:
app: apache
spec:
replicas: 1
selector:
matchLabels:
app: apache
template:
metadata:
labels:
app: apache
spec:
containers:
- name: apache
image: theabdullahchaudhary/my-apache-server-with-love-message:latest
ports:
- containerPort: 80
Deploy the standard Apache server:
$ kubectl apply -f apache-deployment.yaml
? Step 5: Create Apache Service (Custom):
Save the following YAML as "custom-apache-service.yaml" and apply it (this is for aws.digitxel.com ):
#custom-apache-service.yaml
apiVersion: v1
kind: Service
metadata:
name: custom-apache-service
namespace: ingress-nginx
labels:
app: custom-apache
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
selector:
app: custom-apache
Deploy the service for standard Apache server:
$ kubectl apply -f custom-apache-service.yaml
? Step 6: Create Apache Service (Standard):
Save the following YAML as "apache-service.yaml" and apply it (this is for aws1.digitxel.com):
#apache-service.yaml
apiVersion: v1
kind: Service
metadata:
name: apache-service
namespace: ingress-nginx
labels:
app: apache
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
selector:
app: apache
type: ClusterIP
Deploy the service for the standard Apache server:
$ kubectl apply -f apache-service.yaml
? Step 7: Create Ingress Resource for Both Domains:
Save the following YAML as "apache-ingress.yaml" and apply it:
# apache-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: apache-ingress
namespace: ingress-nginx
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: aws.digitxel.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: apache-service
port:
number: 80
- host: aws1.digitxel.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: custom-apache-service
port:
number: 80
Apply the ingress resource:
$ kubectl apply -f apache-ingress.yaml
? Step 8: Check all resources:
Following command retrieves information about all resources within a specific namespace in Kubernetes.
$ kubectl get all -n ingress-nginx
? Step 9: Set the DNS/Records against the domain:
To expose your Kubernetes services (aws.digitxel.com and aws1.digitxel.com) to the public internet using your public IP address (15.207.247.23), I need to create DNS records that point to this IP address. Here are the DNS records you would need to create:
DNS Records
1. A Record for aws.digitxel.com:
2. A Record for aws1.digitxel.com:
? Step 10: IP address and the corresponding hostnames:
Use a text editor with administrative privileges (like sudo) to edit the /etc/hosts file.
sudo vi /etc/hosts
2. Add the Entry:
In the /etc/hosts file, add the IP address and the corresponding hostnames. For example ( <Public IP> aws.digitxel.com aws1.digitxel.com):
13.233.216.5 aws.digitxel.com aws1.digitxel.com
? Step 11: Granting Public Access to Your EC2 Instance:
Opening Ports 80 (HTTP) and 443 (HTTPS).
**************Now, Let's Test:*****************
After applying the Ingress controller, I configured two domains:
This clarifies that you've set up your Ingress controller to route traffic based on the domain name (aws.digitxel.com or aws1.digitxel.com) to the corresponding web application (your custom Docker image or the default Apache image).
1: aws.digitxel.com:
2: aws1.digitxel.com:
Conclusion: Demystifying Ingress and Routing Traffic in Your Kubernetes Cluster
This comprehensive guide has delved into the world of Ingress controllers and their role in managing external access to services within a Kubernetes cluster. We've explored:
By understanding and implementing Ingress controllers, you can effectively expose your Kubernetes services to the public internet while maintaining control over routing and security.
Ready to take your Kubernetes deployments to the next level? Utilize Ingress controllers to streamline traffic management and ensure a seamless user experience for your applications!
Hashtags: #Kubernetes #Ingress #IngressController #TrafficManagement #ContainerOrchestration #DevOps
DevOps Engineer | Infrastructure as Code Enthusiast | Container Orchestration Specialist | CI/CD Pipeline Guru | AWS | Azure
5 个月Informative?
Senior DevOps Architect | Multi-Cloud Solutions Expert (AWS, Azure, GCP) | Infrastructure Automation & CI/CD Specialist | Kubernetes & Microservices | DevSecOps Practitioner
5 个月Bilal Amjad
Senior DevOps Architect | Multi-Cloud Solutions Expert (AWS, Azure, GCP) | Infrastructure Automation & CI/CD Specialist | Kubernetes & Microservices | DevSecOps Practitioner
5 个月Very helpful!