2 min read | by Jordi Prats
If we try to create a LoadBalancer on an AWS EKS cluster without any public subnet it will get stuck on the pending state and we won't get any external IP/DNS name for it. By using kubectl describe we will be able to get the actual error:
$ kubectl get svc -n pet2cattle
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demo-lb LoadBalancer 172.20.235.213 <pending> 80:30525/TCP 7d
$ kubectl describe svc demo-lb -n pet2cattle
Name: demo-lb
Namespace: pet2cattle
Labels: <none>
Annotations: <none>
Selector: run=demo-lb
Type: LoadBalancer
IP Families: <none>
IP: 172.20.166.181
IPs: <none>
Port: <unset> 80/TCP
TargetPort: 80/TCP
NodePort: <unset> 30088/TCP
Endpoints: 10.236.124.69:80,10.236.126.253:80
Session Affinity: None
External Traffic Policy: Cluster
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal EnsuringLoadBalancer 12s (x3 over 27s) service-controller Ensuring load balancer
Warning SyncLoadBalancerFailed 12s (x3 over 27s) service-controller Error syncing load balancer: failed to ensure load balancer: could not find any suitable subnets for creating the ELB
It tries to find a public subnet to expose the service, if we just don't have any it will never provision a LoadBalancer. Since we might want to expose it to the internal subnet we can force to provision the LoadBalancer on the private subnet by adding an annotation to the Service:
service.beta.kubernetes.io/aws-load-balancer-internal: "true"
We can either set it using kubectl annotate:
$ kubectl annotate svc demo-lb -n pet2cattle "service.beta.kubernetes.io/aws-load-balancer-internal"="true"
service/demo-lb annotated
Or by editing the yaml:
apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/aws-load-balancer-internal: "true"
name: demo-lb
namespace: pet2cattle
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: demo-lb
type: LoadBalancer
After setting the annotation, it will take a while to get the external IP, but eventually it will show up on kube get svc:
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demo-lb LoadBalancer 172.20.134.203 internal-1a1bc15f63068a05e16dc10d31bfc8d4-628860359.eu-west-1.elb.amazonaws.com 80:31066/TCP 3d8h
Posted on 17/02/2021