Install NGINX Ingress Controller in AWS EKS

Ravindra Singh - Sep 14 - - Dev Community

This lesson covers the steps to install and configure an NGINX Ingress Controller in your EKS cluster, enabling you to manage external access to your Kubernetes services.

What is an Ingress Controller?
An Ingress is an API object that defines rules for routing external HTTP and HTTPS traffic to services within your cluster. An Ingress Controller is a software component that implements those rules, acting as a reverse proxy and load balancer for your applications.

GIT LINK: https://github.com/ravindrasinghh/Kubernetes-Playlist

Image description

How nginx ingress controller works ?

  1. Ingress Resource Creation: You create an Ingress resource in your Kubernetes cluster, specifying how you want to expose your applications to external traffic. This includes details like the hostnames to match, paths to route, and the services to direct traffic to.

  2. Controller Monitoring: The Nginx Ingress Controller continuously monitors the Kubernetes API server for changes to Ingress resources.

  3. Configuration Generation: When it detects new or updated Ingress resources, the controller generates an Nginx configuration file based on the specified rules.

  4. Configuration Update: The controller updates the running Nginx pods with the new configuration file.
    Traffic Routing: Nginx acts as a reverse proxy, receiving incoming traffic and routing it to the appropriate backend services based on the Ingress rules.

  5. Load Balancing: Nginx load balances traffic across multiple pods of the same service, ensuring efficient resource utilization and high availability.

Key points about the Nginx Ingress Controller's operation:

  • Constant Monitoring: The controller continuously monitors the Kubernetes API server for changes to Ingress resources, ensuring Nginx's configuration stays up-to-date with your desired state.

  • Dynamic Configuration: Nginx configuration is generated dynamically based on Ingress rules, allowing for flexible traffic routing and load balancing

Use an ALB when:

  • You need advanced HTTP/HTTPS routing: ALBs operate at Layer 7 (Application Layer), allowing you to route traffic based on various HTTP/HTTPS attributes like host headers, path patterns, query parameters, and even HTTP methods. This makes them ideal for microservices architectures where different services may need to be exposed on the same IP address but with distinct paths or hostnames.

  • You need features like WebSockets, HTTP/2, or gRPC: ALBs fully support these protocols, making them suitable for applications requiring these advanced features.

Use an NLB when:

  • You need high-performance TCP/UDP load balancing: They are a great fit for applications requiring extreme throughput and responsiveness, like gaming servers, streaming services, or real-time communication platforms.

  • You need to preserve client source IP addresses: NLBs preserve the original client IP address, which can be crucial for applications that need to identify and track individual clients.

Let's Begin😎

🚀** Prerequisites :**

  1. Terraform: Install Terraform by following the official installation guide.

  2. AWS CLI: Install and configure the AWS CLI by following the AWS CLI installation guide.

  3. kubectl: Install kubectl for interacting with your EKS cluster by following the kubectl installation guide.

  4. A running Kubernetes cluster: This can be a self-managed cluster or a managed service like Amazon EKS.

Refer below video to create the EKS Cluster in AWS

Step1: Clone the Repository

🧑🏻‍💻git clone https://github.com/ravindrasinghh/Kubernetes-Playlist.git
👨🏻‍💻cd Kubernetes-Playlist/Lesson1/

Step 2: Please add the below file to NGINX Ingress Controller 

👉🏻 nginx.tf



resource "helm_release" "ingress-nginx" {
  name             = "ingress-nginx"
  repository       = "https://kubernetes.github.io/ingress-nginx"
  chart            = "ingress-nginx"
  namespace        = "ingress-nginx"
  create_namespace = true
  version          = "4.10.0"
  values           = [file("./nginx.yaml")]
  set {
    name  = "controller.service.annotations.service\\.beta\\.kubernetes\\.io/aws-load-balancer-ssl-cert"
    value = module.acm_backend.acm_certificate_arn
    type  = "string"
  }
}


Enter fullscreen mode Exit fullscreen mode

👉🏻 nginx.yaml



controller:
  replicaCount: 2
  minAvailable: 1
  resources:
    limits:
      cpu: 500m
      memory: 512Mi
    requests:
      cpu: 100m
      memory: 256Mi
  autoscaling:
    enabled: true
    annotations: {}
    minReplicas: 2
    maxReplicas: 6
    targetCPUUtilizationPercentage: 70
    targetMemoryUtilizationPercentage: 80
    behavior:
     scaleDown:
       stabilizationWindowSeconds: 60
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  service:
    annotations:
      service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
      service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: 'true'
      service.beta.kubernetes.io/aws-load-balancer-type: nlb
      service.beta.kubernetes.io/aws-load-balancer-ssl-ports: https
      service.beta.kubernetes.io/aws-load-balancer-ssl-negotiation-policy: 'ELBSecurityPolicy-TLS13-1-2-2021-06'
      service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
    targetPorts:
      http: http
      https: http


Enter fullscreen mode Exit fullscreen mode

Step 3: Initialize Terraform

  • terraform init
  • terraform plan

Image description

  • terraform apply

Image description

Step 4: Verifying the Installation

After installation, verify that the Nginx Ingress Controller is running correctly. 

  • kubectl get pods -n ingress-nginx:

Image description

  • kubectl logs ingress-nginx-controller-74fb489d8f-jpvgs -n ingress-nginx:

Image description

  • kubectl get svc -n ingress-nginx:

Image description

  • Access the Load Balancer IP, and if you receive a '404 Not Found' message, that's the expected outcome. Image description

Step5: Creating an Ingress YAML File

Let's create a basic Ingress resource to expose a service named photoap on the hostname photoapp.codedevops.cloud:



apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  selector:
    matchLabels:
      app: myapp
  replicas: 1
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - image: ravindrasingh6969/nodeapp:latest
        name: myapp
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  ports:
  - port: 80 #service port  #kubeproxy will open port on worker node to which can route traffic to alb
    targetPort: 8080 #container port
    protocol: TCP
  type: ClusterIP
  selector:
    app: myapp
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp
  annotations:
    # Ingress class to use the NGINX Ingress Controlle
    # AWS-specific annotations for SSL and the load balancer
    alb.ingress.kubernetes.io/scheme: "internet-facing"
    alb.ingress.kubernetes.io/target-type: "ip"
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:ap-south-1:434605749312:certificate/0245c0a5-0867-4372-8206-4a5e4ceda0bd"
    alb.ingress.kubernetes.io/ssl-redirect: '443'
spec:
  ingressClassName: nginx
  rules:
    - host: myapp.codedevops.cloud
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: myapp
                port:
                  number: 80


Enter fullscreen mode Exit fullscreen mode
  • Additional Paths: I added /health, /status, and /api/v1 as additional paths to route traffic to the myapp service on port 80.

  • Single Host: The configuration uses a single host
    (myapp.ravindra.tech) to handle multiple paths.

  • Uniform Backend Service: All paths are routed to the same backend service (myapp), which listens on port 80.

This setup will handle requests for the specified paths (/, /ping, /metrics, /health, /status, /api/v1) and route them to the myapp service on port 80, providing flexibility for different endpoints within your application.

Creating Records in Route 53

To make your application accessible via the hostname specified in the Ingress, you'll need to create a DNS record in Route 53, Amazon's managed DNS service.

  1. Create a Hosted Zone: If you don't have one already, create a hosted zone for your domain (e.g., codedevops.cloud) in Route 53.

  2. Create an A Record: Create an A record within your hosted zone, pointing the hostname (myapp.codedevops.cloud) to the external IP address of the Nginx Ingress Controller's Service. You can obtain this IP/ARN using kubectl get service -n ingress-nginx.

Image description

Hit Public Domain for the verification

Image description

Image description

Image description

Troubleshooting

If you encounter any issues, refer to the Nginx ingress documentation or raise an issue in this repository.

🏴‍☠️ source link: https://github.com/ravindrasinghh/Kubernetes-Playlist/tree/master

If you prefer a video tutorial to help guide you Install NGINX Ingress Controller in AWS EKS

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .