15

I am trying to expose a service to the outside world using the loadBalancer type service.

For that, i have followed this doc

https://aws.amazon.com/premiumsupport/knowledge-center/eks-kubernetes-services-cluster/

My loadbalancer.yaml looks like this

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: LoadBalancer
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

But the load balancer is not creating as expected I am getting the following error

Warning  SyncLoadBalancerFailed  8s (x3 over 23s)  service-controller  Error syncing load balancer: failed to ensure load balancer: could not find any suitable subnets for creating the ELB

Seems like its because of some issues in the subnet tags to solve,but i have the required tags in my subnets

kubernetes.io/cluster/<cluster-name>. owned  
kubernetes.io/role/elb   1

But still, I am getting the error could not find any suitable subnets for creating the ELB

shamon shamsudeen
  • 5,466
  • 17
  • 64
  • 129

6 Answers6

24

By default AWS EKS only attaches load balancers to public subnets. In order to launch it in a private subnet you need to not only label your subnets (which it looks like you did) but also annotate your load balancer-

service.beta.kubernetes.io/aws-load-balancer-internal: "true"

You can find more information here.

Robert Hafner
  • 3,364
  • 18
  • 23
  • 1
    Thanks. saved my day! – saranya elumalai Sep 22 '20 at 20:15
  • 1
    Thanks @tedivm, saved my day too. Somehow this annotation went missing from our service yaml and the external ip would go in pending state. – Gauraang Khurana Jan 20 '21 at 23:45
  • Robert Hafner, With EKS upgrade to 1.19, I started getting error internal-*********-1640942194.us-east-1.elb.amazonaws.com didn’t send any data. ERR_EMPTY_RESPONSE for an internal load balancer s kubectl get svc argo-server -n argo NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE argo-server LoadBalancer 172.20.200.167 internal-******-1640942194.us-east-1.elb.amazonaws.com 2746:32212/TCP 30m. Have you faced this error with EKS upgrade? – saranya elumalai May 24 '21 at 22:58
  • making `shared` cluster tag instead of owned and using service template from document above helpede me – Dzmitry Lahoda Jul 15 '21 at 17:10
7

For people that may reach this question, I have faced the same error, but the problem was really simple.

The tag with key kubernetes.io/cluster/<cluster-name> had the wrong cluster name as the automation that deployed it was wrong.

froblesmartin
  • 1,527
  • 18
  • 25
2

In EKS 1.16, I need internet-facing NLB.

The root cause in EKS is that you haven't selected a public subnet while creating the cluster.

After creating the cluster EKS will not allow to update subnets as of now here

To resolve the issue, I have performed the below steps

  1. created a public subnet in the same vpc of EKS
  2. Attached IGW in route tables in new created public subnets
  3. Added below tags in public subnets
  4. kubernetes.io/cluster/<EKSClusterName> : shared

Note: In a 4th step, Replace your EKS cluster name in placeholder EKSClusterName

NIrav Modi
  • 6,038
  • 8
  • 32
  • 47
2

Additional to Robert' answer, you can use the following kubectl command for annotating a service;

kubectl annotate svc <service-name> service.beta.kubernetes.io/aws-load-balancer-internal="true"
hbceylan
  • 968
  • 10
  • 10
2

Resolution This has resolved my issue.

To identify a cluster's subnets, the Kubernetes Cloud Controller Manager (cloud-controller-manager) and AWS Load Balancer Controller (aws-load-balancer-controller) query that cluster's subnets by using the following tag as a filter:

Choose the appropriate option for tagging your subnets:

For public and private subnets used by load balancer resources Tag all public and private subnets that your cluster uses for load balancer resources with the following key-value pair:

Key: kubernetes.io/cluster/cluster-name Value: shared

The cluster-name value is for your Amazon EKS cluster. The shared value allows more than one cluster to use the subnet.

For private subnets used by internal load balancers To allow Kubernetes to use your private subnets for internal load balancers, tag all private subnets in your VPC with the following key-value pair:

Key: kubernetes.io/role/internal-elb Value: 1

For public subnets used by external load balancers To allow Kubernetes to use only tagged subnets for external load balancers, tag all public subnets in your VPC with the following key-value pair:

Key: kubernetes.io/role/elb Value: 1

Note: Use the preceding tag instead of using a public subnet in each Availability Zone.

reference: https://aws.amazon.com/premiumsupport/knowledge-center/eks-vpc-subnet-discovery/

1

Possibly your subnet is not a public one, i.e. accessible from the internet. This will be required for your Loadbalancer to accept traffic from the outside world. In order to make it public, you need to attach an Internet Gateway to your VPC. Check here for more documentation.

Fritz Duchardt
  • 11,026
  • 4
  • 41
  • 60