LoadBalancer Services still waiting for an external address after 10 minutes
What does ZopNight detect here?
ZopNight flags a Kubernetes Service of `type: LoadBalancer` on EKS, GKE or AKS that is still pending, with no external address in `status.loadBalancer`, once the Service is 10 minutes old. Load balancers are created asynchronously by the cloud integration, so an address that never arrives means provisioning failed or nothing is handling the request.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-1764 · RC-1864 · RC-1964 |
| Category | reliability |
| Severity | medium |
| Metric | status.loadBalancer.ingress |
| Threshold | type LoadBalancer, no address, Service older than 10 minutes |
| Evaluation window | 10m |
| Source | ZopNight |
| Permissions used | list services · list events |
Where it applies
What pending means for a LoadBalancer Service
Setting type: LoadBalancer asks the cloud to build a load balancer for the Service. The
Service documentation notes
that the actual creation happens asynchronously, and that details of the provisioned balancer are
published in .status.loadBalancer. Until then, that status holds no address.
A few minutes of pending is normal. Much longer means the request is stuck, and ZopNight’s finding
points at the usual suspects on the cloud side: the cloud controller lacking permissions, quota or
subnet capacity. There is also
a Kubernetes-side trap: if .spec.loadBalancerClass is set, the default cloud implementation
ignores the Service and a controller matching that class is assumed to be watching. If no such
controller exists, the Service waits forever.
Listing stuck LoadBalancer Services
kubectl get services -A -o json | jq -r ' .items[] | select(.spec.type == "LoadBalancer" and ((.status.loadBalancer.ingress // []) | length == 0)) | "\(.metadata.namespace)/\(.metadata.name) class=\(.spec.loadBalancerClass // "default") created=\(.metadata.creationTimestamp)"'Provisioning errors appear as events on the Service:
kubectl events --for service/<name> -n <namespace>Three conditions, all required
ZopNight fires only when the Service type is LoadBalancer, the Service reads as pending with no
external address, and the Service is at least 10 minutes old by its creation timestamp. Services
of other types are never considered, and a Service whose creation time is unknown is left alone.
The check has no longer window; an address appearing clears it at the next evaluation.
Outside its scope
The rule does not diagnose why provisioning failed or look at the cloud account. Services that did get an address are covered for exposure risk by Service type LoadBalancer, and Ingresses with the equivalent symptom by Ingress has no address.
Unreachable service, no saving
This medium-severity reliability finding has no dollar figure. Clients outside the cluster cannot reach the Service until an address is assigned.
Unsticking the load balancer
- Read the Service events for the error the cloud controller reported.
- If
loadBalancerClassis set, confirm a controller for that class is installed and running; otherwise remove the field so the default implementation handles it. - On EKS, check the subnets carry the tags in the
EKS load balancing guide,
kubernetes.io/role/elbfor internet-facing andkubernetes.io/role/internal-elbfor internal load balancers. - Check the account’s load balancer quotas in the cloud console.
- If the Service no longer needs to be external, change it to
ClusterIPor delete it.