Understanding OpenShift Load Balancers

OpenShift Load Balancers Explained

In OpenShift, “load balancer” can refer to several different layers:

External client traffic
│
▼
External Load Balancer
│
▼
OpenShift Ingress Router
│
▼
Service
│
▼
Application Pods

There are also dedicated load balancers for the OpenShift API and machine configuration endpoints.


Main Load Balancers in OpenShift

A standard OpenShift cluster normally needs these external endpoints:

EndpointPortPurpose
api.<cluster>.<domain>6443Kubernetes and OpenShift API
api-int.<cluster>.<domain>6443Internal API communication
*.apps.<cluster>.<domain>80/443Application routes
Machine Config Server22623Node ignition and machine configuration

The most important distinction is:

API load balancer
≠
Application ingress load balancer

They serve different traffic and normally use different backend pools.


High-Level Architecture

                          Administrators
                               │
                               ▼
                    api.cluster.example.com
                               │
                     API Load Balancer
                               │
                 ┌─────────────┼─────────────┐
                 ▼             ▼             ▼
             master-0       master-1       master-2
               :6443          :6443          :6443


                         Application Users
                               │
                               ▼
                 app1.apps.cluster.example.com
                               │
                  Ingress Load Balancer
                               │
                 ┌─────────────┼─────────────┐
                 ▼             ▼             ▼
            router pod     router pod     router pod
                 │             │             │
                 └─────────────┼─────────────┘
                               ▼
                         OpenShift Service
                               │
                         Application Pods

1. API Load Balancer

The API load balancer provides highly available access to the OpenShift control plane.

Clients include:

  • oc
  • OpenShift web console
  • kubelets
  • Operators
  • Controllers
  • Automation pipelines
  • Monitoring systems

Traffic path:

oc command
│
▼
api.cluster.example.com:6443
│
▼
External load balancer
│
├── master-0:6443
├── master-1:6443
└── master-2:6443

The load balancer distributes requests across all healthy API servers.

Recommended behavior

Use:

  • Layer 4 TCP load balancing
  • TCP health checks or HTTPS health checks
  • No application-level rewriting
  • Source connection stability where required
  • All control-plane nodes as backends

Example HAProxy configuration:

frontend api-server
bind *:6443
mode tcp
default_backend api-server-backend
backend api-server-backend
mode tcp
balance roundrobin
option tcp-check
server master0 10.10.10.10:6443 check
server master1 10.10.10.11:6443 check
server master2 10.10.10.12:6443 check

2. Internal API Load Balancer

The internal API name is commonly:

api-int.<cluster>.<domain>

It is used by nodes and internal cluster components.

Worker kubelet
│
▼
api-int.cluster.example.com:6443
│
▼
Internal load balancer
│
▼
Control-plane nodes

In some designs, the same load balancer serves both public and internal API names. In more restricted environments, separate internal and external virtual IPs are used.


3. Machine Config Server Load Balancer

The Machine Config Server listens on port 22623.

It provides Ignition and machine configuration during installation and node provisioning.

New OpenShift node
│
▼
api-int.cluster.example.com:22623
│
▼
Load balancer
│
▼
Machine Config Server

Typical backend targets:

master-0:22623
master-1:22623
master-2:22623

Example HAProxy configuration:

frontend machine-config-server
bind *:22623
mode tcp
default_backend machine-config-backend
backend machine-config-backend
mode tcp
balance roundrobin
server master0 10.10.10.10:22623 check
server master1 10.10.10.11:22623 check
server master2 10.10.10.12:22623 check

4. Application Ingress Load Balancer

The application load balancer handles traffic for OpenShift Routes.

Example DNS:

payments.apps.cluster.example.com
mobile.apps.cluster.example.com
banking.apps.cluster.example.com

These normally resolve to the ingress load balancer.

Client
│
▼
payments.apps.cluster.example.com
│
▼
External load balancer
│
▼
OpenShift router pods
│
▼
Service
│
▼
Application pods

The router pods are usually HAProxy-based and managed by the Ingress Operator.


OpenShift Router

The OpenShift router is not the same as the external load balancer.

External Load Balancer
│
▼
Ingress Router Pods
│
▼
OpenShift Services
│
▼
Application Pods

The external load balancer only forwards traffic to the router nodes or router pods.

The router then:

  • Matches the hostname
  • Matches the route
  • Handles TLS
  • Selects the backend service
  • Load-balances traffic to pods

Route Traffic Flow

Suppose the application route is:

https://payments.apps.cluster.example.com

The request path is:

Browser
│
▼
DNS
│
▼
Ingress load balancer
│
▼
Router pod
│
▼
Route object
│
▼
Service
│
▼
Pod endpoint

OpenShift Route Example

apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: payments
namespace: banking
spec:
host: payments.apps.cluster.example.com
to:
kind: Service
name: payments-service
port:
targetPort: https
tls:
termination: edge

The router watches Route objects and dynamically updates its routing configuration.


Load Balancing Inside the Cluster

OpenShift Services provide internal load balancing.

Example:

apiVersion: v1
kind: Service
metadata:
name: payments-service
spec:
selector:
app: payments
ports:
- port: 443
targetPort: 8443

Traffic flow:

payments-service
│
├── payments-pod-1
├── payments-pod-2
└── payments-pod-3

The service exposes a stable virtual IP and distributes traffic to healthy pod endpoints.


Service Types

ClusterIP

Default service type.

Available only inside the cluster
spec:
type: ClusterIP

Use it for internal service-to-service communication.


NodePort

Exposes a port on every node.

Client
│
▼
NodeIP:NodePort
│
▼
Service
│
▼
Pods
spec:
type: NodePort

NodePort is usually not preferred as the primary application exposure method in enterprise OpenShift. Routes are more common.


LoadBalancer

Requests an external load balancer from the cloud provider or supported infrastructure integration.

spec:
type: LoadBalancer

Example flow in AWS:

Service type LoadBalancer
│
▼
Cloud Controller Manager
│
▼
AWS NLB or ELB created
│
▼
OpenShift nodes or pods

This is frequently used for non-HTTP protocols or applications that need their own external load balancer.


ExternalName

Maps a service to an external DNS name.

spec:
type: ExternalName
externalName: database.example.com

It does not create a real load balancer.


Ingress Controller Placement

By default, ingress router pods are scheduled according to the Ingress Controller configuration.

For enterprise environments, dedicated infrastructure nodes are recommended:

Worker nodes
├── Application workloads
└── Batch workloads
Infrastructure nodes
├── Ingress routers
├── Registry
├── Monitoring
└── Logging

Example node labels:

oc label node infra-0 node-role.kubernetes.io/infra=""
oc label node infra-1 node-role.kubernetes.io/infra=""
oc label node infra-2 node-role.kubernetes.io/infra=""

The Ingress Controller can then use a node placement policy.


Typical Bare-Metal Architecture

                         Corporate Network
                               │
                     F5 / HAProxy / NetScaler
                     ┌─────────┴──────────┐
                     │                    │
                  API VIP             Apps VIP
                     │                    │
          ┌──────────┼──────────┐    ┌────┼────┐
          ▼          ▼          ▼    ▼    ▼    ▼
       master-0   master-1   master-2  infra nodes
       :6443      :6443      :6443     :80/:443

Example VIPs:

API VIP: 10.10.20.10
Apps VIP: 10.10.20.20

DNS:

api.ocp.example.com → 10.10.20.10
api-int.ocp.example.com → 10.10.20.10
*.apps.ocp.example.com → 10.10.20.20

Typical Cloud Architecture

In AWS, Azure, or GCP, OpenShift can create and manage cloud load balancers.

Internet
│
▼
Cloud Load Balancer
│
▼
Ingress Router Service
│
▼
Router Pods
│
▼
Application Services

Possible cloud load balancers include:

  • AWS Network Load Balancer
  • Azure Load Balancer
  • Google Cloud Load Balancer

The exact implementation depends on:

  • Installation method
  • Platform integration
  • Ingress Controller configuration
  • Service annotations
  • Internal or external exposure

Internal vs External Ingress

A cluster can have multiple Ingress Controllers.

Example:

Public Ingress Controller
└── *.apps.ocp.example.com
Internal Ingress Controller
└── *.internal.apps.ocp.example.com

This is useful for banking environments:

Internet-facing applications
│
▼
WAF → Public LB → Public Router
Internal banking applications
│
▼
Internal LB → Private Router

You can separate them by:

  • DNS domain
  • Node placement
  • Route labels
  • Namespace selectors
  • Network zones
  • Load balancer scope

TLS Termination

OpenShift Routes support several TLS models.

Edge termination
Client ──HTTPS──> Router ──HTTP──> Pod

The router terminates TLS.


Re-encrypt termination
Client ──HTTPS──> Router ──HTTPS──> Pod

The router decrypts and creates a new TLS connection to the backend.

This is commonly preferred for sensitive applications.


Passthrough termination
Client ──HTTPS──> Router ──HTTPS──> Pod

The router does not decrypt the traffic. TLS terminates in the application pod.


Load Balancer Health Checks

API health check

A common check is:

TCP 6443

or an HTTPS readiness endpoint:

https://<master>:6443/readyz
Ingress health check

Common checks include:

TCP 80
TCP 443

or the router health endpoint, depending on platform configuration.

The load balancer should remove unhealthy endpoints automatically.


Session Persistence

Most OpenShift applications should be stateless.

However, if an application requires sticky sessions, Routes support session affinity through cookies.

Example annotation:

metadata:
annotations:
haproxy.router.openshift.io/balance: source

Other algorithms include:

roundrobin
leastconn
source

Avoid depending heavily on session persistence when applications can instead store session state externally.


Load Balancing Algorithms

External load balancer

Typical algorithms:

  • Round robin
  • Least connections
  • Source IP
  • Weighted round robin
OpenShift router

Common options:

  • Round robin
  • Least connections
  • Source-based persistence
Service load balancing

Kubernetes and OVN-Kubernetes distribute service traffic across available endpoints.


Failure Scenarios

One API server fails
master-1 fails
│
▼
LB health check fails
│
▼
master-1 removed from pool
│
▼
Traffic continues to master-0 and master-2

One router pod fails
router pod fails
│
▼
Load balancer or Service removes endpoint
│
▼
Traffic continues through remaining router pods

One application pod fails
Application pod fails
│
▼
Readiness probe fails
│
▼
Endpoint removed from Service
│
▼
Traffic goes to healthy pods

This shows the three load-balancing layers:

External LB health
│
Router readiness
│
Application pod readiness

Troubleshooting API Load Balancer

Test DNS:

dig api.cluster.example.com

Test the API:

curl -k https://api.cluster.example.com:6443/readyz

Test individual control-plane nodes:

curl -k https://master-0.example.com:6443/readyz
curl -k https://master-1.example.com:6443/readyz
curl -k https://master-2.example.com:6443/readyz

Check API pods:

oc get pods -n openshift-kube-apiserver -o wide

Look for:

  • Incorrect backend ports
  • Failed health checks
  • Missing master node
  • TLS inspection
  • Idle timeout too low
  • Load balancer SNAT exhaustion
  • DNS pointing to the wrong VIP
  • Firewall blocking port 6443

Troubleshooting Application Load Balancer

Check DNS:

dig payments.apps.cluster.example.com

Test the route:

curl -vk https://payments.apps.cluster.example.com

Check route:

oc get route -n banking
oc describe route payments -n banking

Check router pods:

oc get pods -n openshift-ingress -o wide

Check Ingress Controller:

oc get ingresscontroller -n openshift-ingress-operator
oc describe ingresscontroller default \
-n openshift-ingress-operator

Check the application service and endpoints:

oc get svc -n banking
oc get endpoints -n banking
oc get endpointslices -n banking

Check pod readiness:

oc get pods -n banking
oc describe pod <pod-name> -n banking

The full troubleshooting path is:

DNS
↓
External load balancer
↓
Router
↓
Route
↓
Service
↓
EndpointSlice
↓
Pod readiness
↓
Application

Common Problems

Route returns 503

Usually means the router cannot find a healthy backend.

Check:

oc get endpointslices -n <namespace>
oc get pods -n <namespace>
oc describe route <route> -n <namespace>

Common causes:

  • No ready pods
  • Wrong Service selector
  • Wrong target port
  • Failed readiness probe
  • Application not listening

API intermittently unavailable

Possible causes:

  • Load balancer sending traffic to unhealthy master
  • Incorrect health check
  • Too-short timeout
  • Control-plane API latency
  • Network packet loss
  • etcd latency
  • TLS inspection device interference

Route works internally but not externally

Check:

  • Wildcard DNS
  • Firewall
  • External VIP
  • Load balancer pool
  • Router node placement
  • Port 80/443
  • Public versus private ingress configuration

Banking Best Practices

For a regulated banking environment, I would use:

API traffic:
Admin network → Private API LB → Control-plane nodes
Public traffic:
Internet → DDoS protection → WAF → Public LB → Public routers
Internal traffic:
Corporate network → Internal LB → Internal routers

Additional controls:

  • Separate API and application VIPs
  • Private API endpoint
  • Dedicated infra nodes for routers
  • Multiple router replicas across failure domains
  • Re-encrypt or passthrough TLS for sensitive applications
  • WAF in front of public ingress
  • Mutual TLS for partner applications
  • Centralized load balancer and router access logs
  • NetworkPolicies behind the router
  • Health checks based on readiness
  • Avoid TLS interception on OpenShift API traffic
  • Monitor connection count, latency and backend health

Important Interview Distinction

An OpenShift architect should distinguish these three layers:

LayerComponentPurpose
ExternalF5, HAProxy, cloud LBSends traffic into the cluster
IngressOpenShift routerMatches Routes and sends traffic to Services
InternalKubernetes ServiceDistributes traffic to application pods
External Load Balancer
│
▼
OpenShift Router
│
▼
Kubernetes Service
│
▼
Pods

Interview Answer

OpenShift uses load balancing at multiple layers. The API load balancer exposes port 6443 and distributes administrative and internal Kubernetes API traffic across the control-plane nodes. Port 22623 is used for the Machine Config Server during node provisioning. Application traffic is normally sent through a separate ingress load balancer on ports 80 and 443 to OpenShift router pods. The routers evaluate Route objects, terminate or pass through TLS, and forward requests to Kubernetes Services, which then distribute traffic to healthy pod endpoints.

On bare metal, the external load balancer might be F5, HAProxy or NetScaler. In cloud environments, OpenShift integrates with the cloud provider’s load-balancing services. For production, I would use separate API and application VIPs, redundant router replicas across failure domains, proper health checks, dedicated infrastructure nodes and separate public and internal Ingress Controllers. When troubleshooting, I follow the traffic path from DNS to the external load balancer, router, Route, Service, EndpointSlice, pod readiness and finally the application.

Leave a Reply