Why does Kubernetes try to create a load balancer for a service type ClusterIP?

11/14/2017

I'm using an Ingress to expose my services from outside the Kubernetes cluster, so I don't need Kubernetes to provision a loadbalancer. Therefore, I created a ClusterIP service:

apiVersion: v1
kind: Service
metadata:
  name: myapp
  namespace: default
spec:
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: myapp
  type: ClusterIP

This works - I have a separate Ingress and Deployment set up and I can access the app just fine.

However, Kubernetes insists on trying to create a loadbalancer anyway. Since it doesn't have permission in my AWS account do so, every service I create logs errors like this:

FirstSeen   LastSeen    Count   From            SubObjectPath   Type        Reason              Message
  --------- --------    -----   ----            -------------   --------    ------              -------
  22s       22s     1   service-controller          Warning     CreatingLoadBalancerFailed  Error creating load balancer (will retry): Error getting LB for service default/myapp: AccessDenied: User: -redacted- is not authorized to perform: elasticloadbalancing:DescribeLoadBalancers with an explicit deny
        status code: 403, request id: -redacted-

I assume that it's trying to DescribeLoadBalancers because it intends to create one. The docs claim that loadbalancers should only be created when you specify service type "LoadBalancer". How can I stop Kubernetes from trying anyway?

-- Michael K
amazon-web-services
kubernetes

1 Answer

11/15/2017

It is not trying to create one. You are receiving the error message from service_controller.go:287:

func (s *ServiceController) createLoadBalancerIfNeeded(key string, service *v1.Service) (error, bool) {
    [...]
    if !wantsLoadBalancer(service) {
        _, exists, err := s.balancer.GetLoadBalancer(s.clusterName, service)
        if err != nil {
            return fmt.Errorf("Error getting LB for service %s: %v", key, err), retryable
        }
        [...]

In turn GetLoadBalancer is calling the cloudprovider to describe (check if one exists). I suggest you authorize the aws service account for this particular action.

-- Janos Lenart
Source: StackOverflow