Skip to content

rajeshwrn/alb-nginx-controller

Repository files navigation

Single ALB for multiple ingress in AWS EKS fargate

Documentation/Steps to create an alb in EKS fargate for multiple ingress/service running different namespace. Option to reuse an existing ALB instead of creating a new ALB per Ingress.

Requirement

  • Need to deploy multiple service in kubernetes with single alb.
  • Service/Ingress running on different fargate profile should communicate each other

What is an Application Load Balancer?

An Application Load Balancer or ALB is a bridge between inbound traffic and several targets (for example several pods for one application). The objective is to have applications with high availability.

Limitations

  • Each service/ingress running in kubernetes with different namespaces/ fargate profile will create new alb
  • More cost and more public IP needed

Solution

We will now going to achieve this with 2 ingress controllers: the ALB ingress controller and the Nginx Ingress controller.

Why do we have to use 2 ingress controllers?

Because if we use the nginx ingress controller, we can not connect it directly to an ALB and if we only use the ALB ingress controller, you will have an ALB instance for every ingress resource in the cluster.

But the requirement is one load balancer all services running in cluster. In the case in which we have both: it is important to know the nginx ingress controller will manage all ingresses resources of your applications in your EKS cluster and the ALB ingress controller will manage the life cycle of the Application Load Balancer instance.

alt text

To create alb ingress in aws eks fargate use the below aws doc, https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html

creating second ingress controller - nginx Before that, understand currently the eks fargate will not support nginx official helm chart. so we need to do small tweak on the helm values.

  • Port type should be NodePort
  • allowPrivilegeEscalation should be false to enable the node creation in fargate profile
  • Override defalut container ports 80 to 8080 and 443 to 8443
  • Traffic policy should be local

Installation

Use the below helm command to deploy nginx controller in your cluster.

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install nginx-ingress ingress-nginx/ingress-nginx --set-string controller.service.externalTrafficPolicy=Local --set-string controller.service.type=NodePort --set controller.publishService.enabled=true --set serviceAccount.create=true --set rbac.create=true --set-string controller.config.server-tokens=false --set-string controller.config.use-proxy-protocol=false --set-string controller.config.compute-full-forwarded-for=true --set-string controller.config.use-forwarded-headers=true --set controller.metrics.enabled=true --set controller.autoscaling.maxReplicas=1 --set controller.autoscaling.minReplicas=1 --set controller.autoscaling.enabled=true --namespace kube-system -f nginx-values.yaml 

For more customization on ingress-nginx helm chart https://artifacthub.io/packages/helm/ingress-nginx/ingress-nginx

Use below value file for helm deployment

nginx-values.yaml

controller: 
  extraArgs: 
    http-port: 8080 
    https-port: 8443 
  containerPort: 
    http: 8080 
    https: 8443 
  service: 
    ports: 
      http: 80 
      https: 443 
    targetPorts: 
      http: 8080 
      https: 8443 
  image: 
    allowPrivilegeEscalation: false

Connect the ALB to the Nginx Ingress controller

To connect the ALB to the nginx ingress controller, we need to create a kubernetes ingress resource in the namespace kube-system with the following configuration:

kubectl apply -f alb-ingress-connect-nginx.yaml

apiVersion: extensions/v1beta1 
kind: Ingress 
metadata: 
  annotations: 
    #alb.ingress.kubernetes.io/certificate-arn: <CERTIFICATE_ARN> 
    alb.ingress.kubernetes.io/healthcheck-path: /healthz 
    alb.ingress.kubernetes.io/scheme: internet-facing 
    alb.ingress.kubernetes.io/target-type: ip 
    alb.ingress.kubernetes.io/subnets: <subnets> 
    kubernetes.io/ingress.class: alb  
  name: alb-ingress-connect-nginx 
  namespace: kube-system 
spec: 
  rules: 
    - http: 
        paths: 
          - backend: 
              serviceName: nginx-ingress-controller 
              servicePort: 8080 
            path: /* 

Now we are ready with alb it will communicate to the nginx ingress controller.

Validate the changes by accessing the ingress address, it will be the public facing dns address and we can access the services running in cluster this dns.

kubectl get ingress -n kube-system

Deploy your application with following ingress annonation and service port should be 'ClusterIP'

annotations:
   kubernetes.io/ingress.class: "nginx"