Ingress NGINX Controller on EKS
This is the known good design for deploying the Ingress NGINX Controller on Amazon EKS.
Overview
Ingress NGINX Overview
The Ingress NGINX Controller is a Kubernetes-native load balancer that manages external access to services in a cluster. On EKS, it works seamlessly with Amazon Elastic Load Balancers (ELBs) to provide robust HTTP(S) ingress capabilities.
Key Features
- Supports HTTP and HTTPS: Handles secure and non-secure traffic.
- Rule-Based Routing: Route traffic based on host, path, or headers.
- Custom Annotations: Allows fine-grained control over NGINX configurations.
- Integration with ACM: Automates TLS certificate provisioning via AWS Certificate Manager.
For more details, refer to the AWS Documentation.
AWS Load Balancer Behavior
How AWS Deploys a Load Balancer
When a service is configured with type: LoadBalancer
in an EKS cluster, AWS automatically creates an Elastic Load Balancer (ELB) outside the cluster. This load balancer forwards external traffic to the node ports associated with the service.
- The Load Balancer maps to the cluster nodes and routes traffic to the relevant pods via node ports.
- By default, an Application Load Balancer (ALB) is used for HTTP/HTTPS traffic, while a Network Load Balancer (NLB) is preferred for TCP traffic.
Example:
- Service with ports 80 and 443.
- ELB forwards traffic to random node ports, such as
31567
(HTTP) and31568
(HTTPS), on each node.
For more information, see the AWS Load Balancers Documentation.
Helm Deployment Example
Step 1: Install the Ingress NGINX Controller with Helm
Add the Helm Repository:
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update
Install the Ingress NGINX Controller: Use Helm to install the controller in the
ingress-nginx
namespace:helm install ingress-nginx ingress-nginx/ingress-nginx \ --namespace ingress-nginx \ --create-namespace \ --set controller.service.type=LoadBalancer
Verify the Installation: Check the pods and services in the
ingress-nginx
namespace:kubectl get pods -n ingress-nginx kubectl get svc -n ingress-nginx
Expected output for the service:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.245.89.53 123.45.67.89 80:31567/TCP,443:31568/TCP 2m
ArgoCD Deployment Example
Deploying the Ingress NGINX Controller with ArgoCD
The following is an example of deploying the Ingress NGINX Controller using ArgoCD:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: ingress-nginx
namespace: argocd
spec:
destination:
namespace: ingress-nginx
server: https://kubernetes.default.svc
project: cluster-services
source:
chart: ingress-nginx
helm:
values: |
controller:
service:
type: LoadBalancer
publishService:
enabled: true
metrics:
enabled: true
prometheus:
enabled: true
allowSnippetAnnotations: true
config:
ssl-ciphers: "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:AES128-SHA256"
ssl-protocols: "TLSv1.2 TLSv1.3"
proxy-connect-timeout: '15'
proxy-read-timeout: '600'
proxy-send-timeout: '600'
hsts-include-subdomains: 'false'
body-size: 64m
server-name-hash-bucket-size: '256'
client-max-body-size: 50m
replicaCount: 3
podAnnotations:
"prometheus.io/scrape": "true"
"prometheus.io/port": "10254"
repoURL: https://kubernetes.github.io/ingress-nginx
targetRevision: 4.10.1
syncPolicy:
automated:
prune: true
selfHeal: true
retry:
backoff:
duration: 30m
factor: 2
maxDuration: 5m
limit: 3
syncOptions:
- CreateNamespace=true
Key Features in the Configuration
- Load Balancer: Configures the service type as
LoadBalancer
for external access. - Prometheus Metrics: Enables metrics collection for monitoring with Prometheus.
- Timeouts and Limits: Configures proxy and client body limits to handle large requests.
- Replicas: Deploys three replicas of the Ingress NGINX controller for high availability.
- Automated Sync: Ensures that the deployment self-heals and prunes unused resources automatically.
- Namespace Creation: Automatically creates the
ingress-nginx
namespace if it doesn’t exist.
Using Annotations to Customize the Load Balancer
AWS Load Balancers can be customized using annotations on the Kubernetes service resource. The following example demonstrates commonly used annotations:
Example Service with Annotations
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
annotations:
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "arn:aws:acm:region:account-id:certificate/certificate-id"
service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
service.beta.kubernetes.io/aws-load-balancer-access-log-enabled: "true"
service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-name: "my-bucket"
service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-prefix: "nginx-logs"
spec:
type: LoadBalancer
selector:
app.kubernetes.io/name: ingress-nginx
ports:
- port: 80
targetPort: http
- port: 443
targetPort: https
Annotation Details
service.beta.kubernetes.io/aws-load-balancer-backend-protocol
: Specifies the protocol for the backend (http
ortcp
).service.beta.kubernetes.io/aws-load-balancer-ssl-cert
: Associates an ACM certificate for HTTPS traffic.service.beta.kubernetes.io/aws-load-balancer-ssl-ports
: Defines which ports should use SSL.service.beta.kubernetes.io/aws-load-balancer-access-log-enabled
: Enables access logs for the load balancer.service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-name
: Specifies the S3 bucket for storing access logs.service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-prefix
: Defines the log prefix within the S3 bucket.
For a complete list of available annotations, see the AWS Load Balancers Documentation.