Tuesday, July 11, 2023

ALB Ingress - ALB Context Path Routing #Section 12

ALB Context Path Routing

ALB Context Path Routing can be used to achieve more granular routing of incoming requests to different Kubernetes services based on the URL path. This can be particularly useful when you want to host multiple services under a single domain name or IP address and route traffic based on specific paths.

Here's how ALB Context Path Routing works:

  1. Ingress Configuration: In your Kubernetes Ingress resource, you specify rules that define different context paths and associate them with different backend services (target groups) using annotations.

  2. ALB Configuration: The AWS ALB Ingress Controller translates the Ingress resource's context path rules and annotations into corresponding rules on the AWS ALB.

  3. Request Routing: When a client sends an HTTP request, the AWS ALB examines the URL's path. Based on the path, the ALB routes the request to the appropriate target group, which corresponds to a specific Kubernetes service.

  4. Backend Processing: The Kubernetes service associated with the selected context path processes the request and generates a response, which is then sent back through the ALB to the client.

For example, suppose you have two Kubernetes services: ServiceA and ServiceB, and you want to route requests based on context paths:

 

 



Step-01: Introduction

  • Discuss about the Architecture we are going to build as part of this Section
  • We are going to deploy all these 3 apps in kubernetes with context path based routing enabled in Ingress Controller
    • /app1/* - should go to app1-nginx-nodeport-service
    • /app2/* - should go to app1-nginx-nodeport-service
    • /* - should go to app3-nginx-nodeport-service
  • As part of this process, this respective annotation alb.ingress.kubernetes.io/healthcheck-path: will be moved to respective application NodePort Service.
  • Only generic settings will be present in Ingress manifest annotations area 04-ALB-Ingress-ContextPath-Based-Routing.yml
  •  

Step-02: Review Nginx App1, App2 & App3 Deployment & Service

  • Differences for all 3 apps will be only two fields from kubernetes manifests perspective and their naming conventions
    • Kubernetes Deployment: Container Image name
    • Kubernetes Node Port Service: Health check URL path
  • App1 Nginx: 01-Nginx-App1-Deployment-and-NodePortService.yml
    • image: stacksimplify/kube-nginxapp1:1.0.0
    • Annotation: alb.ingress.kubernetes.io/healthcheck-path: /app1/index.html
  • App2 Nginx: 02-Nginx-App2-Deployment-and-NodePortService.yml
    • image: stacksimplify/kube-nginxapp2:1.0.0
    • Annotation: alb.ingress.kubernetes.io/healthcheck-path: /app2/index.html
  • App3 Nginx: 03-Nginx-App3-Deployment-and-NodePortService.yml
    • image: stacksimplify/kubenginx:1.0.0
    • Annotation: alb.ingress.kubernetes.io/healthcheck-path: /index.html

Step-03: Create ALB Ingress Context path based Routing Kubernetes manifest

  • 04-ALB-Ingress-ContextPath-Based-Routing.yml
# Annotations Reference: https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/ingress/annotations/
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-cpr-demo
  annotations:
    # Load Balancer Name
    alb.ingress.kubernetes.io/load-balancer-name: cpr-ingress
    # Ingress Core Settings
    #kubernetes.io/ingress.class: "alb" (OLD INGRESS CLASS NOTATION - STILL WORKS BUT RECOMMENDED TO USE IngressClass Resource)
    alb.ingress.kubernetes.io/scheme: internet-facing
    # Health Check Settings
    alb.ingress.kubernetes.io/healthcheck-protocol: HTTP 
    alb.ingress.kubernetes.io/healthcheck-port: traffic-port
    #Important Note:  Need to add health check path annotations in service level if we are planning to use multiple targets in a load balancer    
    alb.ingress.kubernetes.io/healthcheck-interval-seconds: '15'
    alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '5'
    alb.ingress.kubernetes.io/success-codes: '200'
    alb.ingress.kubernetes.io/healthy-threshold-count: '2'
    alb.ingress.kubernetes.io/unhealthy-threshold-count: '2'   
spec:
  ingressClassName: my-aws-ingress-class   # Ingress Class                  
  rules:
    - http:
        paths:      
          - path: /app1
            pathType: Prefix
            backend:
              service:
                name: app1-nginx-nodeport-service
                port: 
                  number: 80
          - path: /app2
            pathType: Prefix
            backend:
              service:
                name: app2-nginx-nodeport-service
                port: 
                  number: 80
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app3-nginx-nodeport-service
                port: 
                  number: 80              

# Important Note-1: In path based routing order is very important, if we are going to use  "/*", try to use it at the end of all rules.                                        
                        
# 1. If  "spec.ingressClassName: my-aws-ingress-class" not specified, will reference default ingress class on this kubernetes cluster
# 2. Default Ingress class is nothing but for which ingress class we have the annotation `ingressclass.kubernetes.io/is-default-class: "true"`                      

Step-04: Deploy all manifests and test

# Deploy Kubernetes manifests
kubectl apply -f kube-manifests/

# List Pods
kubectl get pods

# List Services
kubectl get svc

# List Ingress Load Balancers
kubectl get ingress

# Describe Ingress and view Rules
kubectl describe ingress ingress-cpr-demo

# Verify AWS Load Balancer Controller logs
kubectl -n kube-system  get pods 
kubectl -n kube-system logs -f aws-load-balancer-controller-794b7844dd-8hk7n 

Step-05: Verify Application Load Balancer on AWS Management Console**

  • Verify Load Balancer
    • In Listeners Tab, click on View/Edit Rules under Rules
  • Verify Target Groups
    • GroupD Details
    • Targets: Ensure they are healthy
    • Verify Health check path
    • Verify all 3 targets are healthy)
# Access Application
http://<ALB-DNS-URL>/app1/index.html
http://<ALB-DNS-URL>/app2/index.html
http://<ALB-DNS-URL>/

Step-06: Test Order in Context path based routing

Step-0-01: Move Root Context Path to top

  • File: 04-ALB-Ingress-ContextPath-Based-Routing.yml
  ingressClassName: my-aws-ingress-class   # Ingress Class                  
  rules:
    - http:
        paths:      
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app3-nginx-nodeport-service
                port: 
                  number: 80           
          - path: /app1
            pathType: Prefix
            backend:
              service:
                name: app1-nginx-nodeport-service
                port: 
                  number: 80
          - path: /app2
            pathType: Prefix
            backend:
              service:
                name: app2-nginx-nodeport-service
                port: 
                  number: 80

Step-06-02: Deploy Changes and Verify

# Deploy Changes
kubectl apply -f kube-manifests/

# Access Application (Open in new incognito window)
http://<ALB-DNS-URL>/app1/index.html  -- SHOULD FAIL
http://<ALB-DNS-URL>/app2/index.html  -- SHOULD FAIL
http://<ALB-DNS-URL>/  - SHOULD PASS

Step-07: Roll back changes in 04-ALB-Ingress-ContextPath-Based-Routing.yml

spec:
  ingressClassName: my-aws-ingress-class   # Ingress Class                  
  rules:
    - http:
        paths:      
          - path: /app1
            pathType: Prefix
            backend:
              service:
                name: app1-nginx-nodeport-service
                port: 
                  number: 80
          - path: /app2
            pathType: Prefix
            backend:
              service:
                name: app2-nginx-nodeport-service
                port: 
                  number: 80
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app3-nginx-nodeport-service
                port: 
                  number: 80              

Step-08: Clean Up

# Clean-Up
kubectl delete -f kube-manifests/
 

 

 

 

 




No comments:

Post a Comment