Whitelist "kube-system" namespace using NetworkPolicy Whitelist "kube-system" namespace using NetworkPolicy kubernetes kubernetes

Whitelist "kube-system" namespace using NetworkPolicy


apiVersion: networking.k8s.io/v1

The namespaceSelector is designed to match namespaces by labels only. There is no way to select namespace by name.

The podSelector can only select pods in the same namespace with NetworkPolicy object. For objects located in different namespaces, only selection of the whole namespace is possible.

Here is an example of Kubernetes Network Policy implementation:

apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:  name: test-network-policy  namespace: defaultspec:  podSelector:    matchLabels:      role: db  policyTypes:  - Ingress  - Egress  ingress:  - from:    - ipBlock:        cidr: 172.17.0.0/16        except:        - 172.17.1.0/24    - namespaceSelector:        matchLabels:          project: myproject    - podSelector:        matchLabels:          role: frontend    ports:    - protocol: TCP      port: 6379  egress:  - to:    - ipBlock:        cidr: 10.0.0.0/24    ports:    - protocol: TCP      port: 5978

Follow this link to read a good explanation of the whole concept of Network policy, or this link to watch the lecture.

apiVersion: projectcalico.org/v3

Calico API gives you more options for writing NetworkPolicy rules, so, at some point, you can achieve your goal with less efforts and mind-breaking.

For example, using Calico implementation of Network Policy you can:

  • set action for the rule (Allow, Deny, Log, Pass),
  • use negative matching (protocol, notProtocol, selector, notSelector),
  • apply more complex label selectors(has(k), k not in { ‘v1’, ‘v2’ }),
  • combine selectors with operator &&,
  • use port range (ports: [8080, "1234:5678", "named-port"]),
  • match pods in other namespaces.

But still, you can match namespaces only by labels.

Consider reading Calico documentation for the details.

Here is an example of Calico Network Policy implementation:

apiVersion: projectcalico.org/v3kind: NetworkPolicymetadata:  name: allow-tcp-6379  namespace: productionspec:  selector: role == 'database'  types:  - Ingress  - Egress  ingress:  - action: Allow    protocol: TCP    source:      selector: role == 'frontend'    destination:      ports:      - 6379  egress:  - action: Allow


Indeed, tenant1 pods will need access to kube-dns in the kube-system namespace specifically.

One approach without requiring kube-system namespace to be labelled is the following policy. Although kube-dns could be in any namespace with this approach so it may not be suitable for you.

---                                                                                                                                                                                                           # Default deny all ingress & egress policy, except allow kube-dns                                                                                                                                             # All traffic except this must be explicity allowed.                                                                                                                                                          kind: NetworkPolicy                                                                                                                                                                                           apiVersion: networking.k8s.io/v1                                                                                                                                                                              metadata:                                                                                                                                                                                                       name: default-deny-all-except-kube-dns                                                                                                                                                                        namespace: tenant1                                                                                                                                                                                        spec:                                                                                                                                                                                                           podSelector: {}                                                                                                                                                                                               egress:                                                                                                                                                                                                       - to:                                                                                                                                                                                                           - podSelector:                                                                                                                                                                                                    matchLabels:                                                                                                                                                                                                    k8s-app: kube-dns                                                                                                                                                                                    - ports:                - protocol: TCP                                                                                                                                                                                              port: 53                                                                                                                                                                                                                                                                                        - protocol: UDP                                                                                                                                                                                                port: 53                                                                                                                                                                                                 policyTypes:                                                                                                                                                                                                 - Ingress                                                                                                                                                                                                    - Egress   

Then, you would need also need an 'allow all within namespace policy' as follows:

---                                                                                                                                                                                                           # Allow intra namespace traffic for development purposes only.                                                                                                                                                kind: NetworkPolicy                                                                                                                                                                                           apiVersion: networking.k8s.io/v1                                                                                                                                                                              metadata:                                                                                                                                                                                                       name: allow-intra-namespace                                                                                                                                                                                   namespace: tenant1                                                                                                                                                                                        spec:                                                                                                                                                                                                           podSelector:                                                                                                                                                                                                    matchLabels:                                                                                                                                                                                                ingress:                                                                                                                                                                                                      - from:                                                                                                                                                                                                         - podSelector: {}                                                                                                                                                                                           egress:                                                                                                                                                                                                       - to:                                                                                                                                                                                                           - podSelector: {}                                                                                                                                                                                           policyTypes:                                                                                                                                                                                                  - Ingress                                                                                                                                                                                                     - Egress

Lastly, you will want to add specific policies such as an ingress rule. It would be better to replace the allow-intra-namespace policy with specific rules to suit individual pods, which your tenant1 could do.

These have been adapted from this website: https://github.com/ahmetb/kubernetes-network-policy-recipes


If i understood correctly you are using calico. Just use their example on how to implement default-deny without breaking kube-dns communication.Found here

apiVersion: projectcalico.org/v3kind: GlobalNetworkPolicymetadata:  name: deny-app-policyspec:  namespaceSelector: has(projectcalico.org/name) && projectcalico.org/name not in {"kube-system", "calico-system"}  types:  - Ingress  - Egress  egress:  # allow all namespaces to communicate to DNS pods  - action: Allow    protocol: UDP    destination:      selector: 'k8s-app == "kube-dns"'      ports:      - 53