Network policy understanding --> podSelector: {} vs namespaceSelector: for all pods from one ns

I came across this question in killercoda

my-app-deployment and cache-deployment deployed, and my-app-deployment deployment exposed through a service named my-app-service . Create a NetworkPolicy named my-app-network-policy to restrict incoming and outgoing traffic to my-app-deployment pods with the following specifications:

  • Allow incoming traffic only from pods within the same namespace.
  • Allow incoming traffic from a specific pod with the label app=trusted
  • Allow outgoing traffic to pods within the same namespace.
  • Deny all other incoming and outgoing traffic.

I used this netpol and it fails

apiVersion: networking.k8s.io/v1
		kind: NetworkPolicy
		metadata:
		  name: my-app-network-policy
		  namespace: default
		spec:
		  podSelector:
		    matchLabels:
		      app: my-app
		  policyTypes:
		  - Ingress
		  - Egress
		  ingress:
		  - from:
		    - namespaceSelector:
		        matchLabels:
		         kubernetes.io/metadata.name: default          
		    - podSelector:
		        matchLabels:
		          app: trusted
		  egress:
		  - to:
		    - namespaceSelector:
		        matchLabels:
         kubernetes.io/metadata.name: default

whereas the below works and I Don’t understand how, can someone pls explain?

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: my-app-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: my-app
  ingress:
    - from:
        - podSelector: {}
    - from:
        - podSelector:
            matchLabels:
              app: trusted
  egress:
    - to:
        - podSelector: {}

The first policy reads

  • Ingress
    • Allows pods in namespace default with labels app: my-app to receive traffic from all pods in namespaces with labels kubernetes.io/metadata.name: default on all ports
    • Allows pods in namespace default with labels app: my-app to receive traffic from pods in the same namespace with labels app: trusted on all ports
  • Egress
    • Allows pods in namespace default with labels app: my-app to connect to all pods in namespaces with labels kubernetes.io/metadata.name: default on all ports

The second policy reads

  • Ingress
    • Allows pods in namespace default with labels app: my-app to receive traffic from all pods in the same namespace on all ports (denies inbound traffic to pods in namespace default with labels app: my-app from other namespaces)
    • Allows pods in namespace default with labels app: my-app to receive traffic from pods in the same namespace with labels app: trusted on all ports
  • Egress
    • Allows pods in namespace default with labels app: my-app to connect to all pods in the same namespace on all ports (denies outbound traffic from pods in namespace default with labels app: my-app to other namespaces)

Compare these with the question requirements

So

  • podSelector: {} means “all pods in the same namespace”. You don’t need to know the name of the namespace, just that it means the same namespace where the netpol is deployed. This makes the policy portable to other namespaces.
  • If you use namespaceSelector to mean all pods, then you need to explicitly specify a selector for the namespace. You use this method when you want to say all pods in another known namespace.
1 Like

so can the first Ingress net pol mean the below?

  • Allows pods in namespace default with labels app: my-app to receive traffic from all pods from all namespaces with labels kubernetes.io/metadata.name: default on all ports

It could, BUT kubernetes.io/metadata.name is a system label applied when the namespace is created and its values are unique (they are the name given from kubectl create namespace), so you cannot have 2 namespaces with the same value for this label.

You could apply your own label with the same value to multiple namespaces and use that in a policy, then all the pods from all the namespaces with this label/value would be in scope.