nginxkubernetesweave

Kubernetes Egress Network Policy is not working on a pod selected


I'm facing a weird issue on setting up egress network policy on my kube cluster.

Basically I want my pod A to access only pod B.

I have two pods:

  1. hello-k8s-deploy
  2. nginx

The hello-k8s-deploy pod expose an API on port 8080 via NodePort. My nginx pod is simply an image to access the API.

So let's try logging in to the nginx pod and access that API exposed by the hello-k8s-deploy pod.

enter image description here

Above shows that the API responded back with message starts with Hello K8s!

Now let's apply the network policy on my nginx pod so it can access only this API, nothing else.

Network policy:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: app
spec:
  podSelector:
    matchLabels:
      run: nginx
  egress:
    - to:
      - podSelector:
          matchLabels:
            app: hello-k8s-deploy
  policyTypes:
   - Egress

Above policy will be applied to pod with label run: nginx

And the rule is allow traffic to pod with label app: hello-k8s-deploy

Let's validate it by looking at the definition of both of the pods nginx and hello-k8s-deploy

nginx:

enter image description here

hello-k8s-deploy

enter image description here

As we can see both labels are matching the Network policy.

After I applied the network policy and access the nginx again I expect to work the same and get a response from the API but I'm getting the below error.

enter image description here

Take note that:

  1. All of the resources are in the same namespace app
  2. My network addon is weave-net which has support for network policy as per documentation.
  3. I even tried to specify the namespace selector and add port 8080.

Solution

  • I finally resolved the issue, basically the problem I was getting is could not resolve host hello-k8s-svc. It means k8s is trying to connect using this host and resolving through dns name (service name).

    And since my pod is only allowing egress to hello-k8s-deploy, it's failing as it also needs to connect to kube-dns for resolving the dns. So before you apply an egress make sure the pod or all pods in your namespace are allowing to connect to kube-dns for dns resolution.

    The fix is simply creating an egress resource to all pods to connect to kube-dns on top of your pod specific egress configuration.

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: default-deny-all-egress
    spec:
      podSelector: {}
      egress:
      - to:
        - namespaceSelector:
            matchLabels:
              networking/namespace: kube-system
          podSelector:
            matchLabels:
              k8s-app: kube-dns
        ports:
        - protocol: TCP
          port: 53
        - protocol: UDP
          port: 53
      policyTypes:
      - Egress
    

    In my case I labeled the kube-system namespace:

     kubectl label namespace kube-system networking/namespace=kube-system