Skip to content

Load balancers

Services in a project are private: reachable from workloads on the cluster and from nowhere else. A load balancer is what publishes one.

For the same steps in the console, see the console walkthrough.

L7 or L4

The choice is not cosmetic, and it decides which object you create.

L7 - reverse proxy L4 - load balancer
Object Route Service of type LoadBalancer
You get A hostname A public IP address
Traffic HTTP, terminated and forwarded TCP or UDP, forwarded untouched
Certificate Issued for you Your application's problem
Use for Websites, APIs Databases, game servers, anything not HTTP

Pick L7 if your service speaks HTTP. Pick L4 if it does not.

Create an L7 endpoint

route.yaml
apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: <name>
  namespace: <project>
spec:
  host: <name>.apps.grn.cloud
  to:
    kind: Service
    name: <service>
  port:
    targetPort: <port>
  tls:
    termination: edge
    insecureEdgeTerminationPolicy: Redirect
oc apply -f route.yaml

edge termination means TLS ends at the platform ingress and traffic reaches your pods as plain HTTP inside the cluster. Redirect sends anyone arriving on HTTP to HTTPS.

For a domain of your own, set spec.host to it and point a DNS record at the platform ingress yourself. Nothing arrives until that record exists.

Create an L4 endpoint

Change the service's type rather than creating a second object:

oc patch svc <service> -n <project> --type=merge \
  -p '{"spec":{"type":"LoadBalancer"}}'

An address is allocated from the platform pool. To read it:

oc get svc <service> -n <project> \
  -o jsonpath='{.status.loadBalancer.ingress[0].ip}{"\n"}'

To request a particular address, add spec.loadBalancerIP: <address> - only for cases where the address is already published somewhere you cannot change.

List

oc get routes -n <project>
oc get svc -n <project> --field-selector spec.type=LoadBalancer

A route is live once admitted:

oc get route <name> -n <project> \
  -o jsonpath='{.status.ingress[0].conditions[0].status}{"\n"}'

True means the ingress accepted it. A route that is not admitted usually collides with a hostname already claimed elsewhere on the cluster.

Change

For a route, the target service and port can be changed in place:

oc patch route <name> -n <project> --type=merge \
  -p '{"spec":{"to":{"name":"<service>"}}}'

The hostname can be changed too, but treat it as creating a new endpoint: the old name stops working the moment it is applied, and anything pointing at it breaks.

For an L4 service, changing the ports changes what is forwarded. Changing spec.loadBalancerIP releases the old address, which may then be handed to someone else - do not do it to an address in use.

Delete

oc delete route <name> -n <project>

For L4, put the service back to private rather than deleting it:

oc patch svc <service> -n <project> --type=merge \
  -p '{"spec":{"type":"ClusterIP"}}'

That releases the public address and leaves the service working for workloads inside the cluster. Deleting the service instead would break those too.

If it does not answer

A published endpoint that does not respond is usually one of:

  • A firewall in the project. A rule set to Only this project or Anywhere in the cluster drops traffic arriving from outside, whatever the load balancer does. See Firewalls.
  • DNS, for a custom domain that does not point at the platform ingress.
  • The target port, pointing at a port the pods do not listen on.

Test from outside the cluster, not from a workload on it - a service can look published and still be unreachable.

  • Networking - what the networking offering covers
  • Firewalls - the most common reason a published service stays silent
  • Subnets - giving a project its own routable address range