I have a simple working NetworkPolicy looking like this
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: monitoring-network-policy-prometheus-jbn
namespace: monitoring
spec:
podSelector:
matchLabels:
app: prometheus
policyTypes:
- Egress
egress:
- to:
ports:
- port: 61678
But now I want to restrict this a bit more. Instead of allowing egress to all destinations on port 61678 from all pods with label app: prometheus I want to allow only traffic to pods with label k8s-app: aws-node
So I change the policy to:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: monitoring-network-policy-prometheus-jbn
namespace: monitoring
spec:
podSelector:
matchLabels:
app: prometheus
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
k8s-app: aws-node
According to https://kubernetes.io/docs/concepts/services-networking/network-policies/ a policy that looks like this
...
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
- podSelector:
matchLabels:
role: client
...
is described as allows connections from Pods in the local Namespace with the label role=client, or from any Pod in any namespace with the label user=alice.
So I would think that this would match a pod with label k8s-app: aws node which is located in the kube-system namespace on any port. But when I try to connect to a pod with that label I get a timeout.
Here is the pod I am connecting to
kubectl get pods -n kube-system -l k8s-app=aws-node
NAME READY STATUS RESTARTS AGE
aws-node-ngmnd 1/1 Running 0 46h
I am using AWS EKS with Calio network plugin.
What am I missing here?
This is happening because you omit placing the namespaceSelector in your manifest and by default when namespaceSelector is not preset the system will select the Pods matching PodSelector in the policy's own namespace.
See here:
podSelector
This is a label selector which selects Pods. This field follows standard label selector semantics; if present but empty, it selects all pods. If NamespaceSelector is also set, then the NetworkPolicyPeer as a whole selects the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. Otherwise it selects the Pods matching PodSelector in the policy's own Namespace.
What can you do solve it? You could set empty namespace selector as per documents:
namespaceSelector
Selects Namespaces using cluster-scoped labels. This field follows standard label selector semantics; if present but empty, it selects all namespaces. If PodSelector is also set, then the NetworkPolicyPeer as a whole selects the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. Otherwise it selects all Pods in the Namespaces selected by NamespaceSelector.Reference NetworkPolicyPeer
I reproduce this issue and the documentation is correct but a bit misleading about place which should be in fact empty. So the parenthesis should be placed after the matchLabels:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: monitoring-network-policy-prometheus-jbn
namespace: monitoring
spec:
podSelector:
matchLabels:
app: prometheus
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
k8s-app: aws-node
namespaceSelector:
matchLabels: {}
To answer your concerns about whether calico might be causing some issues. Well in fact it is, but it is suppose to. For network policies to take effect you need to run network plugin that will enforce them.