Kubernetes Network Policy stops all traffic to Pod

2/20/2020

Scenario:

  1. I have Four(4) Pods, Payroll,internal,external,mysql.
  2. I want internal pod to only access:
    • a. Internal > Payroll on port 8080
    • b. Internal > mysql on port 3306

Kindly suggest what is missing part? I made the below network policy. But my pod is unable to communicate with 'any' pod. Hence it has achieved the given target, but practically unable to access other pods. Below are my network policy details.

master $ k describe netpol/internal-policy
Name:         internal-policy
Namespace:    default
Created on:   2020-02-20 02:15:06 +0000 UTC
Labels:       <none>
Annotations:  <none>
Spec:
  PodSelector:     name=internal
  Allowing ingress traffic:
    <none> (Selected pods are isolated for ingress connectivity)
  Allowing egress traffic:
    To Port: 8080/TCP
    To:
      PodSelector: name=payroll
    ----------
    To Port: 3306/TCP
    To:
      PodSelector: name=mysql
  Policy Types: Egress

Policy YAML

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: internal-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      name: internal
  policyTypes:
  - Egress
  egress:
  - to:
    - podSelector:
        matchLabels:
          name: payroll
    ports:
      - protocol: TCP
        port: 8080
  - to:
    - podSelector:
        matchLabels:
          name: mysql
    ports:
      - protocol: TCP
        port: 3306 (edited) 
-- Zeeshan Zia
kubernetes
networking
policy

1 Answer

2/20/2020

Hence it has achieved the given target, but practically unable to access other pods.

If I understand you correctly you achieved the goal defined in your network policy and all your Pods wearing label name: internal are currently able to communicate both with payroll (on port 8080) and mysql (on port 3306) Pods, right ?

Please correct me if I'm wrong but I see some contradiction in your statement. On the one hand you want your internal Pods to be able to communicate only with very specific set of Pods and connect with them using specified ports:

I want internal pod to only access:

a. Internal > Payroll on port 8080

b. Internal > mysql on port 3306

and on the other, you seem surprised that they can't access any other Pods:

Hence it has achieved the given target, but practically unable to access other pods.

Keep in mind that when you apply some NetworkPolicy rule on specific set of Pods, at the same time the dafault deny all rule is implicitly applied on selected Pods (unless you decide to reconfigure the default policy to make it work the way you want).

As you can read here:

Pods become isolated by having a NetworkPolicy that selects them. Once there is any NetworkPolicy in a namespace selecting a particular pod, that pod will reject any connections that are not allowed by any NetworkPolicy. (Other pods in the namespace that are not selected by any NetworkPolicy will continue to accept all traffic.)

The above applies also to egress rules.

If currently your internal Pods have access only to payroll and mysql Pod on specified ports, everything works as it is supposed to work.

If you are interested in denying all other traffic to your payroll and mysql Pods, you should apply an ingress rule on those Pods rather than defining egress on Pods which are supposed to communicate with them, but at the same time they should not be deprived of the ability to communicate with other Pods.

Please let me know if it helped. If something is not clear or my assumption was wrong, also please let me know and don't hesitate to ask additional questions.

-- mario
Source: StackOverflow