Load Balancer

GSK provisions a Load Balancer when you create a Kubernetes Service with type: LoadBalancer.

This exposes your application to external traffic.

  • For simple use cases (exposing a single service), a LoadBalancer Service is enough.
  • For advanced routing such as multiple domains, path-based routing, or TLS management, use Ingress or the Gateway API. These are typically exposed through a LoadBalancer Service.

Architecture Overview

Using Kubernetes Service Object

The simplest way to expose an application.

Client → GSK Load Balancer → Service → Pods

By using a LoadBalancer service type, GSK provisions a Load Balancer with an external IP that routes directly to your application.


Using Ingress

Ingress is widely used and stable for exposing multiple HTTP services behind a single external IP address.

Client → GSK Load Balancer → Ingress Controller → Services → Pods

Typical setup requires you to install an Ingress Controller. Here is the documentation and guide for installing the NGINX Ingress Controller


Using Gateway API

The Gateway API is the successor to Ingress and is the recommended approach for new deployments where supported. It provides more expressive routing, better role separation, and improved extensibility.

Client → GSK Load Balancer → Gateway Controller → Service → Pods

Typical setup requires you to install an Gateway API Controller. Here is the documentation and guide for installing the Envoy Gateway API Controller


How GSK Load Balancer Configuration Works

GSK Load Balancer is always configured through annotations on a Kubernetes Service object of type LoadBalancer.

This applies to:

  • A regular application Service
  • The Service exposing an Ingress controller
  • The Service exposing a Gateway API controller

The Cloud Controller Manager (CCM) reads annotations from the Service object and provisions or updates the Load Balancer accordingly.

Example:

apiVersion: v1
kind: Service
metadata:
  name: my-service
  annotations:
    service.beta.kubernetes.io/gs-loadbalancer-mode: http
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 8080

When using Ingress or Gateway API, you must annotate the controller’s Service, not the Ingress or Gateway resource itself.


Ingress-NGINX Retirement Notice

The Kubernetes community has announced the retirement of Ingress-NGINX.

Kubernetes Official Announcement of Ingress Nginx retirement

Ingress-NGINX will no longer receive new features and will eventually stop receiving maintenance and security updates.

New deployments should use the Gateway API instead.

See the Ingress to Gateway API Migration section below for guidance on transitioning.

Ingress to Gateway API Migration

The Gateway API is the modern successor to Ingress and is the recommended approach for new Kubernetes deployments.

For guidance on migrating from Ingress to Gateway API, refer to the official documentation:

Load Balancer Modes

The GSK Load Balancer supports two operating modes:

  • http (Layer 7)
  • tcp (Layer 4)

The mode is configured using annotations on the Service object.


HTTP Mode (Layer 7)

service.beta.kubernetes.io/gs-loadbalancer-mode: http

Characteristics:

  • Layer 7 load balancing
  • HTTPS termination at the Load Balancer
  • Client IP available in the X-Forwarded-For header
  • Automatic certificates via Let’s Encrypt
  • Support for custom uploaded certificates

Use HTTP mode for standard web applications.


TCP Mode (Layer 4)

service.beta.kubernetes.io/gs-loadbalancer-mode: tcp

Characteristics:

  • Layer 4 load balancing
  • No TLS termination
  • Suitable for non-HTTP protocols
  • Optional Proxy Protocol support for client IP preservation

Use TCP mode when TLS termination should happen inside the cluster or for non-HTTP services.


IP Address Forwarding

Preserving the original client IP depends on the selected Load Balancer mode.


HTTP Mode (Layer 7)

When using HTTP mode, the original client IP address is automatically forwarded via the:

X-Forwarded-For

Characteristics:

  • HTTPS termination happens at the Load Balancer
  • No additional configuration is required for client IP forwarding
  • Certificates can be:
    • Automatically issued via Let’s Encrypt
    • Uploaded manually and referenced via annotation

This mode is recommended for standard web applications.


TCP Mode (Layer 4) – Proxy Protocol

In TCP mode, the original client IP is not preserved by default.

To retain the client IP address, you must enable Proxy Protocol.

Without Proxy Protocol, backend services will only see the Load Balancer’s IP address.


Enabling Proxy Protocol (TCP Mode)

Proxy Protocol must be enabled both on the Load Balancer and on the receiving controller (Ingress or Gateway).


1. Enable Proxy Protocol on the Load Balancer

Edit the Service of type LoadBalancer:

kubectl edit service -n <namespace> <service-name>

Add the following annotations:

service.beta.kubernetes.io/gs-loadbalancer-mode: tcp
service.beta.kubernetes.io/gs-loadbalancer-proxy-protocol: v2

2. Enable Proxy Protocol in the Ingress or Gateway Controller

Proxy Protocol must also be enabled on the receiving controller.

The exact configuration depends on the controller implementation.

Refer to your controller’s official documentation:


Important

Proxy Protocol must be configured consistently on both sides.

If enabled on only one side, errors such as the following may occur:

broken header: "   " while reading PROXY protocol

This typically happens when:

  • Proxy Protocol is enabled in the controller but not on the Load Balancer.
  • Proxy Protocol is enabled on the Load Balancer but traffic bypasses it.

Restricting Traffic by IP or CIDR

You can restrict traffic to your services by allowing only certain IP ranges.
How this is implemented depends on the controller you use.


NGINX Ingress Controller

When using NGINX Ingress, IP-based access control can be configured using the whitelist-source-range annotation on the Ingress resource.

This allows you to restrict access to specific IP addresses or CIDR ranges.

For detailed configuration options, refer to the official NGINX Ingress documentation:


Envoy Gateway API Controller

Envoy Gateway provides IP-based access control through the SecurityPolicy resource.

Using SecurityPolicy, you can define IP allowlists or denylists to restrict traffic at the Gateway level.

For configuration details and usage instructions, see the official Envoy Gateway documentation:

Configuring the Load Balancer via Annotations

The Cloud Controller Manager (CCM) configures the Load Balancer (LBaaS) based on annotations set on the Kubernetes Service.

If an annotation is not defined, the default value is applied.


Available Annotations

AnnotationDefault value
service.beta.kubernetes.io/gs-loadbalancer-modetcp
service.beta.kubernetes.io/gs-loadbalancer-redirect-http-to-https“false”
service.beta.kubernetes.io/gs-loadbalancer-ssl-domainsnil
service.beta.kubernetes.io/gs-loadbalancer-algorithmleastconn
service.beta.kubernetes.io/gs-loadbalancer-https-ports443
service.beta.kubernetes.io/gs-loadbalancer-custom-certificate-uuidsnil
service.beta.kubernetes.io/gs-loadbalancer-proxy-protocolnil

Examples

HTTP Mode with Redirect and Multiple Domains

annotations:
  service.beta.kubernetes.io/gs-loadbalancer-mode: http
  service.beta.kubernetes.io/gs-loadbalancer-redirect-http-to-https: "true"
  service.beta.kubernetes.io/gs-loadbalancer-ssl-domains: demo1.test.com,demo2.test.com
  service.beta.kubernetes.io/gs-loadbalancer-algorithm: roundrobin

HTTP Mode with Custom Certificate and Custom Port

annotations:
  service.beta.kubernetes.io/gs-loadbalancer-mode: http
  service.beta.kubernetes.io/gs-loadbalancer-redirect-http-to-https: "true"
  service.beta.kubernetes.io/gs-loadbalancer-custom-certificate-uuids: c8b786e7-53ee-427b-8ff6-498f59f58b14
  service.beta.kubernetes.io/gs-loadbalancer-algorithm: roundrobin
  service.beta.kubernetes.io/gs-loadbalancer-https-ports: "4443"

Modifying an Existing Ingress or Gateway Service

To update annotations on an existing LoadBalancer service:

kubectl annotate --overwrite svc <SERVICE_NAME> \
"service.beta.kubernetes.io/gs-loadbalancer-mode=http" \
"service.beta.kubernetes.io/gs-loadbalancer-algorithm=roundrobin"
Top