Understanding Kubernetes Ingress Controllers: Working, Benefits and Configuration.
Understanding Kubernetes Ingress Controllers: Working, Benefits and Configuration.

Understanding Kubernetes Ingress Controllers: Working, Benefits and Configuration.

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:

  1. Deployment of Ingress Controller:

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.

  • Host-Based Routing: Routes traffic based on the host header in the HTTP request.
  • Path-Based Routing: Routes traffic based on the request path.


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:

  • Save the above content to a file named tls-secret.yaml.
  • Apply the file to your Kubernetes cluster:

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:

  1. Ingress Resource: An Ingress resource is a Kubernetes object that defines the rules for routing external traffic to services within the cluster. It specifies the hostname, path, and backend service to which the traffic should be forwarded.
  2. Ingress Controller: The Ingress Controller is a daemon process that continuously monitors the Ingress resources in the cluster and updates the configuration of the load balancer or reverse proxy accordingly. It is responsible for translating the Ingress rules into the appropriate configuration for the underlying load balancer or reverse proxy.
  3. Load Balancer or Reverse Proxy: This is the underlying software that receives incoming traffic and routes it based on the configuration provided by the Ingress Controller. Popular examples include NGINX, HAProxy, Traefik, and Envoy.
  4. Endpoints: Endpoints are the actual backend services to which the Ingress Controller routes the traffic. These can be individual Pods, Services, or a combination of both.
  5. Default Backend: The default backend is a service that handles requests that do not match any of the defined Ingress rules. It typically serves a default or error response.
  6. Annotations: Annotations are key-value pairs that can be added to Ingress resources to provide additional configuration options or metadata specific to the Ingress Controller in use.
  7. TLS/SSL Configuration: Many Ingress Controllers support configuring TLS/SSL termination, allowing secure connections (HTTPS) to services within the cluster.
  8. Path-based Routing: Ingress Controllers can route traffic based on the URL path, allowing different services to handle different paths within the same domain or hostname.
  9. Health Checks and Load Balancing: Ingress Controllers often provide features for performing health checks on backend services and load balancing traffic across multiple replicas or instances of a service.
  10. Metrics and Monitoring: Ingress Controllers typically expose metrics and monitoring capabilities, allowing you to track and analyze incoming traffic and performance.

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

  1. Kubernetes Cluster: Ensure you have a Kubernetes cluster running. We will use Minikube for this demonstration.
  2. Tools:

  • kubectl: Command-line tool for interacting with Kubernetes clusters.
  • minikube: Tool to run a Kubernetes cluster locally.


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:

  • Name: aws
  • Type: A
  • Value: 15.207.247.23


2. A Record for aws1.digitxel.com:

  • Name: aws1
  • Type: A
  • Value: 15.207.247.23


? Step 10: IP address and the corresponding hostnames:

  1. Edit the /etc/hosts File:

Use a text editor with administrative privileges (like sudo) to edit the /etc/hosts file.

sudo vi /etc/hosts        

  • You can use any text editor you prefer (vi, nano, gedit, etc.). Just replace vi with your preferred editor.


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:

  • aws.digitxel.com points to my custom Docker image.
  • aws1.digitxel.com points to the default Apache image.

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:

  • The core concepts of Ingress and Ingress controllers.
  • How Ingress controllers route traffic based on defined rules.
  • The steps involved in deploying an Ingress controller and configuring Ingress resources.
  • Practical examples of serving different content based on hostnames using Apache deployments.

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


Uzair Ahmad

DevOps Engineer | Infrastructure as Code Enthusiast | Container Orchestration Specialist | CI/CD Pipeline Guru | AWS | Azure

5 个月

Informative?

回复
Ali Bashir

Senior DevOps Architect | Multi-Cloud Solutions Expert (AWS, Azure, GCP) | Infrastructure Automation & CI/CD Specialist | Kubernetes & Microservices | DevSecOps Practitioner

5 个月
回复
Ali Bashir

Senior DevOps Architect | Multi-Cloud Solutions Expert (AWS, Azure, GCP) | Infrastructure Automation & CI/CD Specialist | Kubernetes & Microservices | DevSecOps Practitioner

5 个月

Very helpful!

回复

要查看或添加评论,请登录

社区洞察

其他会员也浏览了