Skip to content

NGINX Ingress Controller Deployment Guide

orion.png

Overview

The NGINX Ingress Controller is Juno's recommended solution for managing all ingress traffic to your Kubernetes clusters. This controller provides a robust, scalable, and widely-supported method for routing external HTTP/HTTPS traffic to your services.

Ingress Architecture and Topology

Understanding the ingress topology is crucial for effective deployment and troubleshooting. The following example diagram illustrates how external traffic flows through the ingress controller to reach your applications.

┌─────────────────────────────────────────────────────────────────┐
│                        EXTERNAL TRAFFIC                         │
│                     (Internet/External LB)                      │
└─────────────────────────┬───────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│                    CLUSTER BOUNDARY                             │
│  ┌─────────────────────────────────────────────────────────────┐│
│  │                   INGRESS CONTROLLER                        ││
│  │                                                             ││
│  │      ┌─────────────────┐         ┌─────────────────┐        ││
│  │      │  nginx-ingress  │         │     [Other      │        ││
│  │      │   controller    │         │   controllers]  │        ││
│  │      │  Port: 80/443   │         │                 │        ││
│  │      └─────────────────┘         └─────────────────┘        ││
│  └─────────────────────────────────────────────────────────────┘│
│                            │                                    │
│                            ▼                                    │
│  ┌─────────────────────────────────────────────────────────────┐│
│  │                 INGRESS RESOURCES                           ││
│  │                                                             ││
│  │  apiVersion: networking.k8s.io/v1                           ││
│  │  kind: Ingress                                              ││
│  │  metadata:                                                  ││
│  │    name: app-ingress                                        ││
│  │  spec:                                                      ││
│  │    rules:                                                   ││
│  │    - host: app1.example.com                                 ││
│  │      http:                                                  ││
│  │        paths:                                               ││
│  │        - path: /                                            ││
│  │          backend:                                           ││
│  │            service: app1-service                            ││
│  │    - host: app2.example.com                                 ││
│  │      http:                                                  ││
│  │        paths:                                               ││
│  │        - path: /api                                         ││
│  │          backend:                                           ││
│  │            service: app2-service                            ││
│  └─────────────────────────────────────────────────────────────┘│
│                            │                                    │
│                      Routing Logic                              │
│                            ▼                                    │
│  ┌─────────────────────────────────────────────────────────────┐│
│  │                      SERVICES                               ││
│  │                                                             ││
│  │    ┌─────────────────┐         ┌─────────────────┐          ││
│  │    │  app1-service   │         │  app2-service   │          ││
│  │    │ Type: ClusterIP │         │ Type: ClusterIP │          ││
│  │    │   Port: 80      │         │   Port: 80      │          ││
│  │    └─────────┬───────┘         └─────────┬───────┘          ││
│  └─────────────┼─────────────────────────────┼─────────────────┘│
│                │                             │                 │
│                ▼                             ▼                 │
│  ┌─────────────────────────────────────────────────────────────┐│
│  │                        PODS                                 ││
│  │                                                             ││
│  │  ┌─────────────┐ ┌─────────────┐         ┌─────────────┐    ││
│  │  │   Pod 1     │ │   Pod 2     │         │   Pod 3     │    ││
│  │  │    app1     │ │    app1     │         │    app2     │    ││
│  │  │   :8080     │ │   :8080     │         │   :3000     │    ││
│  │  └─────────────┘ └─────────────┘         └─────────────┘    ││
│  └─────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────┘

Traffic Flow

The ingress architecture follows this traffic flow pattern:

  1. External Request - Traffic enters from the internet or external load balancer
  2. Ingress Controller - NGINX controller receives traffic on ports 80/443
  3. Ingress Resource - Routing rules are evaluated based on host/path matching
  4. Service - Traffic is load balanced across available endpoints
  5. Pod - Request reaches the application endpoint

Component Responsibilities

NGINX Ingress Controller: - SSL/TLS termination and certificate management - Load balancing across backend services - Path-based and host-based routing - Rate limiting and access control - WebSocket and gRPC support

Ingress Resources: - Define routing rules and policies - Specify backend services for different paths/hosts - Configure SSL/TLS settings - Set controller-specific annotations

Services & Pods: - Provide stable endpoints for application access - Handle application-specific load balancing - Maintain application state and business logic

Features

  • Industry-standard solution with extensive community support
  • Flexible deployment options for various environments (AWS, on-premises)
  • Customizable configurations to meet specific requirements
  • Seamless integration with ArgoCD for GitOps workflows

Deployment Options

All deployments are managed through ArgoCD for consistent GitOps workflows. Choose the deployment option that best suits your infrastructure environment.

Cloud Deployment (AWS)

This configuration deploys the NGINX Ingress Controller with a Network Load Balancer (NLB) in AWS environments.

Prerequisites

  • Ensure your Kubernetes cluster is running in AWS
  • Identify the subnet ID where the NLB should be deployed
  • Label your service nodes with juno-innovations.com/service: "true"

Be sure to replace the below subnet with your actual subnet ID.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: nginx-ingress-controller
  namespace: argocd
spec:
  project: default
  destination:
    server: https://kubernetes.default.svc
    namespace: ingress-nginx
  sources:
    - repoURL: https://kubernetes.github.io/ingress-nginx
      chart: ingress-nginx
      targetRevision: 4.12.1
      helm:
        values: |-
          controller:
            kind: DaemonSet
            nodeSelector:
              juno-innovations.com/service: "true"
            service:
              annotations:
                service.beta.kubernetes.io/aws-load-balancer-name: "k8s-nlb"
                # ============================================
                # IMPORTANT: Replace the below <subnet> with your actual subnet ID
                # ============================================
                service.beta.kubernetes.io/aws-load-balancer-subnets: "<subnet>"  
                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-target-node-labels: "juno-innovations.com/service=true"
                service.beta.kubernetes.io/aws-load-balancer-healthcheck-interval: "10"
                service.beta.kubernetes.io/aws-load-balancer-healthcheck-timeout: "10"
                service.beta.kubernetes.io/aws-load-balancer-healthcheck-unhealthy-threshold: "2"
                service.beta.kubernetes.io/aws-load-balancer-healthcheck-healthy-threshold: "2"
                service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"
                service.beta.kubernetes.io/aws-load-balancer-target-group-attributes: proxy_protocol_v2.enabled=true
        releaseName: nginx-ingress-controller
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
      allowEmpty: true
    syncOptions:
      - CreateNamespace=true

On-Premises Deployment Options

Option 1: HostPort Configuration

Best for direct node access scenarios or when you need to bypass additional load balancers.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: nginx-ingress-controller
  namespace: argocd
spec:
  project: default
  destination:
    server: https://kubernetes.default.svc
    namespace: ingress-nginx
  sources:
    - repoURL: https://kubernetes.github.io/ingress-nginx
      chart: ingress-nginx
      targetRevision: 4.12.1
      helm:
        values: |-
          controller:
            hostPort:
              enabled: true
            service:
              enabled: false
            kind: DaemonSet
            nodeSelector:
              juno-innovations.com/service: "true"
        releaseName: nginx-ingress-controller
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
      allowEmpty: true
    syncOptions:
      - CreateNamespace=true

Option 2: NodePort Configuration

Ideal when working with external load balancers or when HostPort access is restricted.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: nginx-ingress-controller
  namespace: argocd
spec:
  project: default
  destination:
    server: https://kubernetes.default.svc
    namespace: ingress-nginx
  sources:
    - repoURL: https://kubernetes.github.io/ingress-nginx
      chart: ingress-nginx
      targetRevision: 4.12.1
      helm:
        values: |-
          controller:
            service:
              enabled: true
              type: NodePort
            kind: DaemonSet
            nodeSelector:
              juno-innovations.com/service: "true"
        releaseName: nginx-ingress-controller
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
      allowEmpty: true
    syncOptions:
      - CreateNamespace=true

Ingress Resource Examples

After deploying the NGINX Ingress Controller, you'll need to create Ingress resources to define routing rules for your applications.

Basic HTTP Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: basic-ingress
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: myapp.juno-innovations.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: myapp-service
            port:
              number: 80

Advanced Ingress with TLS and Multiple Paths

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: advanced-ingress
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - secure.juno-innovations.com
    secretName: tls-secret
  rules:
  - host: secure.juno-innovations.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 8080
      - path: /web
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

Advanced Configuration

Configuring Default SSL Certificate

For enhanced security and simplified TLS management, you can configure a default SSL certificate. This is particularly useful for wildcard certificates covering your domain.

Be sure to replace the below certificate-name with your actual certification details.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: nginx-ingress-controller
  namespace: argocd
spec:
  project: default
  destination:
    server: https://kubernetes.default.svc
    namespace: ingress-nginx
  sources:
    - repoURL: https://kubernetes.github.io/ingress-nginx
      chart: ingress-nginx
      targetRevision: 4.12.1
      helm:
        values: |-
          controller:
            extraArgs:
                # ============================================
                # IMPORTANT: Replace the below <certificate-name> with your actual certification details
                # ============================================
              default-ssl-certificate: <namespace>/<certificate-name>
            hostPort:
              enabled: true
            service:
              enabled: false
            kind: DaemonSet
            nodeSelector:
              juno-innovations.com/service: "true"
        releaseName: nginx-ingress-controller
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
      allowEmpty: true
    syncOptions:
      - CreateNamespace=true

Verification

After deployment, verify the controller is working:

# Check controller pods
kubectl get pods -n ingress-nginx

# Check controller service
kubectl get svc -n ingress-nginx

# Check ingress resources
kubectl get ingress -A

# View controller logs
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx

For AWS deployments, also check that the NLB has been created in the AWS console.

Testing Ingress Functionality

# Test HTTP connectivity
curl -H "Host: myapp.juno-innovations.com" http://<INGRESS_IP>

# Test HTTPS connectivity
curl -H "Host: secure.juno-innovations.com" https://<INGRESS_IP>

# Check ingress controller metrics
kubectl port-forward -n ingress-nginx svc/ingress-nginx-controller-metrics 10254:10254
curl http://localhost:10254/metrics

For further assistance, contact Juno Support.