Skip to content

AWS Load Balancer Controller

Using the AWS Load Balancer Controller

The AWS Load Balancer Controller is a popular control-loop to install in Kubernetes Clusters running on AWS—be they managed (EKS) or not. It provides automatic provisioning of Elastic Load Balancers (ELBs) for annotated K8s Service & Ingress objects.

To install the controller, follow this guide which will show you how to ensure your Kubernetes cluster is configured to allow it to work, as well as how to setup permissions for the controller to create ELBs, and how to install the controller itself.

Elastic Load Balancers

Using an ELB allows for Comet to be accessed from outside of the Kubernetes cluster on AWS. They come in three types:

  • CLB (Classic Load Balancer): Deprecated by AWS; AKA a v1 ELB
  • NLB (Network Load Balancer): OSI Layer 4 (TCP/UDP/TLS) Load Balancer
  • ALB (Application Load Balancer): OSI Layer 7 (HTTP/HTTPS) Load Balancer

Comet requires the use of an ALB to support its functionality.

Should you not want to use the AWS Load Balancer Controller you will still need to create, or use an existing, ALB to expose Comet outside the cluster.

Ingress Objects

In order to expose any application outside of your cluster, Kubernetes offers you the choice between using either certain kinds of Service objects or Ingress objects. While Comet can work with both of these options, the AWS Load Balancer Controller will only create ALBs for Ingress objects (and NLBs for Service objects). Thus we recommend the creation of an Ingress object instead of exposing the frontend Service object outside of the cluster.

Creating an Ingress for Comet using our Helm Chart

The Comet Helm Chart supports the automatic creation of an Ingress for the application frontend. Simply enable it through the values file like so:

# ...
frontend:
# ...
  ingress:
    enabled: true
    annotations:
      # ...
    hosts:
      - host: my-comet.my-company.com
        paths:
          - path: /
            pathType: ImplementationSpecific
# ...

Annotating the Ingress for the Controller

Since the AWS Load Balancer Controller watches for annotated objects to know when and how to create ELBs, we next need to ensure that the Ingress object receives the proper annotations. This is also done directly in the values file.

# ...
frontend:
# ...
  ingress:
    # ...
    annotations:
      alb.ingress.kubernetes.io/scheme: 'internet-facing' # Use 'internal' to place ELB on private subnets.
      alb.ingress.kubernetes.io/target-type: ip
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
      alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"]]]'
      # When not using HTTPS replace the above two annotations with simply:
      # alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}]'
      # ...
# ...

Attaching SSL Certificates to the ELB

The AWS Load Balancer Controller can also setup SSL termination on the ELB for you by attaching an SSL Certificate to it. This must be a certificate available through the AWS Certificate Manager (ACM). A certificate not issued by AWS through ACM (including self-signed certificates) can be uploaded to it via the AWS Console.

Ensure that the certificate has host you speficied in the Ingress spec defined as the CN or one of its SANs, or if the certificate is a wildcard that it will match the speficied host.

It's possible you will need to create a DNS record stub of this hostname to be able to generate the certificate. See here for more information.

In order to tell the AWS Load Balancer Controller to attach the certificate you can use one of three methods:

Specifying the ARN of the Certificate:

# ...
frontend:
# ...
  ingress:
    # ...
    annotations:
      alb.ingress.kubernetes.io/certificate-arn: <CERTIFICATE ARN>
      # ...
# ...

Auto-Discovery via Ingress Rule Host:

# ...
frontend:
# ...
  ingress:
    # ...
    annotations:
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
      # ...
    hosts:
      - host: my-comet.my-company.com
        # ...
# ...

Auto-Discovery via TLS Hosts:

Not Supported by our Helm Chart

The auto-discovery methods are particularly useful if you are using the External DNS Controller to create the DNS record prior to generating the certificate. They cannot, however, be used with a wildcard certificate.

Accessing Comet Through the ELB

Once you've updated the Helm release to create the annotated Ingress object, the AWS Load Balancer Controller should automatically detect the Ingress and create the needed ELB. You should see its DNS name when you inspect the Ingress object:

$ kubectl get ingress -l app.kubernetes.io/name=cometml
NAME               HOSTS   ADDRESS                PORTS   AGE
comet-ml-ingress   *       DNS-Name-Of-Your-ALB   80      3m

Custom DNS Record

Since the DNS name of the created ELB is auto-generated, you will need to create a CNAME record (or possibly an Alias record in AWS Route53) pointing to the ELB which matches the host (if any) specified in your Ingress object and the CN or SANs of the certificate you attached (if you did).

If you created this DNS record as a stub to allow you to generate the certificate ensure that it now is set to point to the ELB.

External DNS Controller

A possible way to automate the management of this custom DNS record is through installing the External DNS Controller in your cluster, and adding the following annotations:

# ...
frontend:
# ...
  ingress:
    # ...
    annotations:
      external-dns.alpha.kubernetes.io/controller: dns-controller
      external-dns.alpha.kubernetes.io/hostname: my-comet.my-company.com
      # ...
# ...

However, keep in mind that having the DNS record created by a controller may require that you attach the certificate on a subsequent update.

Dec. 19, 2023