How do I restrict access to Kubernetes service?

7/13/2016

I am trying to create a service using following yaml. As you can see I am trying to restrict access to the service from 10.0.0.0/8 range.

apiVersion: v1
kind: Service
metadata: 
  name: nginx-service
spec: 
  ports:
    # the port that this service should serve on
    - port: 443
      targetPort: 443
  # label keys and values that must match in order to receive traffic for this service
  selector: 
    name: nginx
  type: LoadBalancer
  loadBalancerSourceRanges:
  - 10.0.0.0/8

There are a few Kubernetes documents (listed below) that discuss how to use loadBalancerSourceRanges annotation to control service access.

http://kubernetes.io/docs/user-guide/services-firewalls/

However when I try to create this service, I get an error as follows

error validating "sdp-cluster.yaml": error validating data: found invalid field loadBalancerSourceRanges for v1.ServiceSpec; if you choose to ignore these errors, turn validation off with --validate=false

I looked at the v1.ServiceSpec and could not find it there too.

Am I missing something? How can I restrict traffic to a service in Kubernetes?

-- Sanjeet
kubernetes

4 Answers

5/9/2017

This is now supported on GCE, GKE and AWS. If the provider does not support it, it'll be ignored.Kubernetes Doc

apiVersion: v1
kind: Service
metadata:
    name: myapp
spec:
    ports:
    - port: 8765
        targetPort: 9376
    selector:
    app: example
    type: LoadBalancer
    loadBalancerSourceRanges:
    - 10.0.0.0/8
-- Pouya Naghizadeh
Source: StackOverflow

7/13/2016

loadBalancerSourceRanges was only promoted to a field in 1.3. It has always been an annotation called https://github.com/kubernetes/kubernetes/blob/master/pkg/api/service/annotations.go#L27 (well, since the feature existed in 1.2), which is now deprecated since we've promoted it to a field.

Note that the annotation/field is a whilelist, but it only works on supported cloud providers. If you set it to 10.0/8, you can only access the endpoints from within your kube cluster (i.e the loadbalancer ip behaves like a clusterIP). Even a node outside your cluster within the same cloudprovider will have to NAT to hit the public ip, which means the source-ip on the packet won't be a 10-dot so it won't get past the firewall. You can set it to a public ip and only that client will be able to get to your Service.

-- Prashanth B
Source: StackOverflow

7/14/2016

Found the problem and fixed it. Version 1.2 does not support the field 'loadBalancerSourceRanges', however it does support it as an annotation. So fixed my yaml as follows and it worked well.

apiVersion: v1
kind: Service
metadata: 
  name: nginx-service
  annotations: 
    service.beta.kubernetes.io/load-balancer-source-ranges: "a.b.c.d/8, x.y.0.0/24"
spec: 
  ports:
    # the port that this service should serve on
    - port: 443
      targetPort: 443
  # label keys and values that must match in order to receive traffic for this service
  selector: 
    name: nginx
  type: LoadBalancer
-- Sanjeet
Source: StackOverflow

8/2/2016

Just a small addition I found in case anyone runs into the same issue. It seems that Google Container Engine has been upgraded to Kubernetes 1.3, meaning that it does not fail to validate the new loadBalancerSourceRanges syntax, but it doesn't seem to actually support the new syntax, meaning the field is ignored. For now, it's still necessary to set the annotation or the load balancer will end up publicly available.

-- Anuraag
Source: StackOverflow