Skip to main content
Version: Next 🚧

DNS-Aware Load Balancer Scaling

This guide shows a simple pattern to scale Kubernetes services while keeping DNS records in sync through ExternalDNS.

The idea is:

  • ExternalDNS manages public DNS records from Kubernetes resources.
  • GoKubeDownscaler controls when your gateway/service workloads are up or down.

Prerequisites

First you need to have ExternalDNS installed in your cluster and configured for your cloud provider.

Install ExternalDNS on AWS/EKS:

  • ExternalDNS with Service Controller: this guide shows how to set up ExternalDNS with AWS Route 53 and the default AWS Service Controller for EKS. This guide works only for Services.
  • ExternalDNS AWS LB Controller: this guide shows how to set up ExternalDNS with AWS Route 53 and the AWS Load Balancer Controller for EKS. This guide works for Services, Ingress, and (soon) Gateway resources.
info

This guide also works with other DNS providers supported by ExternalDNS, such as Cloudflare, DigitalOcean, and others. You can even build a custom webhook yourself if you are using a custom solution. Check the ExternalDNS documentation for provider-specific setup instructions.

General references:

Set ExternalDNS Annotations

ExternalDNS commonly watches a Service of type LoadBalancer and creates/updates DNS records from annotations. To set up DNS-aware scaling, you need to annotate your public service with the desired hostname and TTL. You can do this either by editing the service manifest or by using kubectl annotate.

Add ExternalDNS annotations with kubectl:

kubectl annotate svc public-gateway -n edge \
external-dns.alpha.kubernetes.io/hostname=api.example.com \
external-dns.alpha.kubernetes.io/ttl=60

Alternatively, if your setup allows it, you can annotate Ingress or Gateway resources instead of Service. The following example shows how to annotate an Ingress:

Add ExternalDNS annotations with kubectl:

kubectl annotate ingress echoserver -n edge \
external-dns.alpha.kubernetes.io/hostname=api.example.com \
external-dns.alpha.kubernetes.io/ttl=60

Apply Downtime

Finally, you can apply downtime clusterwide, to the service's namespace or the service itself using GoKubeDownscaler. Make sure to include services (or ingresses, gateways) in your targeted resources by using the --include-resources flag on the Downscaler deployment.

If you want to add a cluster-wide downtime with environment variables you can add them inside the values.yaml file.

There you have to add it to the configMap.extraConfig field:

values.yaml
# ...

configMap:
name: go-kube-downscaler
extraConfig: |
DEFAULT_DOWNTIME: "Mon-Fri 18:00-08:00 UTC, Sat-Sun 00:00-24:00 UTC"

# ...

You will now observe that:

  • When the downtime is active, the service will be scaled down to ClusterIP and ExternalDNS will remove the DNS record from your public DNS provider
  • When the downtime ends, the service will scale back up to LoadBalancer (or Ingress/Gateway) and ExternalDNS will recreate the DNS record.
tip
  • Keep TTL low (for example 60) for faster DNS convergence during scale events.
  • Explore ExternalDNS to fine tune your DNS management, including provider-specific configurations and advanced features.
  • Explore ExternalDNS annotations.
  • Validate behavior in a non-production namespace before applying cluster-wide schedules.