GlobalNetworkPolicy exclude default namespace

Recently started with Calico network policies on a AKS cluster. The plan is to block all traffic for new namespaces with the exception of traffic destined for the coredeDNS pod labeled “kube-dns”.

I’ve applied the policy below and noticed that it is also blocking traffic in the default namespace. The plan to exclude the default namespace from this policy. But i’m not sure how to do it? Do i need to apply this policy and apply another default kubernetes network policy to allow traffic? Or can i add exceptions to the globalnetworkpolicy?

According to the policy it should not be applied for namespaces with the value set to default, but apparently it does. According to the documentation:

  • has(projectcalico.org/name) --> Matches resources with label projectcalico.org/name, independent of value
  • && projectcalico.org/name not in {“kube-system”, “calico-system”, “default”} --> Matches resources without label projectcalico.org/name or with label projectcalico.org/name and value not in the given set {“kube-system”, “calico-system”}

Meaning (?): it will pretty much apply to any namespace, except for the namespaces with a label with the value set to kube-system or calico-system. But if that’s the case, why doesn’t it work? I’ve added a label to the default namespace: name=default

apiVersion: project.calico/v3
kind: GlobalNetworkPolicy
metadata:
name: deny-traffic-default
spec:
namespaceSelector: has(projectcalico.org/name) && projectcalico.org/name not in {“kube-system”, “calico-system”, “default”}
types:
- Ingress
- Egress
egress:
# allow all namespaces to communicate to DNS pods
- action: Allow
protocol: UDP
destination:
selector: ‘k8s-app == “kube-dns”’
ports:
- 53

Please can you format your YAML as a code block, the indentation has been lost so I can’t tell if it’s correct or not

It’s a copy of the code posted on this link (only added the default namespace to not {}): https://docs.projectcalico.org/security/kubernetes-default-deny

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

That policy looks correct to me, are you using a recent version of Calico? namespaceSelector was added to GlobalNetworkPolicy in v3.11 and your calicoctl and calico/node both need to be up-to-date to use new fields.

Hmm… that seems to be the problem, the azure kubernetes service is running v.3.8.9… It seems that Microsoft is lagging behind, unless i’m checking the wrong setting?

containers:
- name: calico-node
image: ‘mcr.microsoft.com/oss/calico/node:v3.8.9
env:

Yes, that’s pretty old; are you sure you’re on the latest version that they offer?

FWIW, we’ve added CRD schemas in recent versions of Calico that prevent this kind of issue; the API server will reject the unknown field.

Just deployed the latest AKS version 1.19.3 and it’s still running calico/node:v3.8.9.

containers:
- name: calico-node
image: ‘mcr.microsoft.com/oss/calico/node:v3.8.9

So this means a no go for the policy i wanted to use.