Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kubernetes NetworkPolicy allow loadbalancer

I have a Kubernetes cluster running on Google Kubernetes Engine (GKE) with network policy support enabled. I created an nginx deployment and load balancer for it:

kubectl run nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=LoadBalancer

Then I created this network policy to make sure other pods in the cluster won't be able to connect to it anymore:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: access-nginx
spec:
  podSelector:
    matchLabels:
      run: nginx
  ingress:
  - from:
      - namespaceSelector:
          matchLabels:
            name: kube-system
    ports:
    - protocol: TCP
      port: 80

Now other pods in my cluster can't reach it (as intended):

kubectl run busybox --rm -ti --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget --spider --timeout=1 nginx
Connecting to nginx (10.63.254.50:80)
wget: download timed out

However, it surprised me that using my external browser I also can't connect anymore to it through the load balancer:

open http://$(kubectl get svc nginx --output=jsonpath={.status.loadBalancer.ingress[0].ip})

If I delete the policy it starts to work again.

So, my question is: how do I block other pods from reaching nginx, but keep access through the load balancer open?

like image 397
Christiaan Avatar asked Nov 16 '17 10:11

Christiaan


2 Answers

I talked about this in my Network Policy recipes repository.

"Allowing EXTERNAL load balancers while DENYING local traffic" is not a use case that makes sense, therefore it's not possible to using network policy.

For Service type=LoadBalancer and Ingress resources to work, you must allow ALL traffic to the pods selected by these resources.

If you REALLY want you can use the from.ipBlock.cidr and from.ipBlock.cidr.except resources to allow traffic from 0.0.0.0/0 (all IPv4) and then excluding 10.0.0.0/8 (or whatever private IP range GKE uses).

like image 51
ahmet alp balkan Avatar answered Oct 13 '22 00:10

ahmet alp balkan


I recently had to do something similar. I needed a policy that didn't allow pods from other namespaces to talk to prod, but did allow the LoadBalancer services to reach pods in prod. Here's what worked (based on Ahmet's post):

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: isolate-prod
  namespace: prod
spec:
  podSelector: {}
  ingress:
  - from:
    - podSelector: {}
  - from:
    - ipBlock:
        cidr: '0.0.0.0/0'
        except: ['10.0.0.0/8']
like image 42
Tammer Saleh Avatar answered Oct 12 '22 23:10

Tammer Saleh