Since Kubernetes v1.11, it is possible to combine podSelector
and namespaceSelector
with an AND
(intersection) operation.
Start a web
application:
kubectl run web --image=nginx --labels="app=web" --expose --port=80
Create a other
namespace and label it:
kubectl create namespace other
kubectl label namespace/other team=operations
The following manifest restricts traffic to only pods with label type=monitoring
in namespaces labelled team=operations
. Save it to web-allow-all-ns-monitoring.yaml
and apply to the cluster:
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: web-allow-all-ns-monitoring
namespace: default
spec:
podSelector:
matchLabels:
app: web
ingress:
- from:
- namespaceSelector: # chooses all pods in namespaces labelled with team=operations
matchLabels:
team: operations
podSelector: # chooses pods with type=monitoring
matchLabels:
type: monitoring
$ kubectl apply -f web-allow-all-ns-monitoring.yaml
networkpolicy.networking.k8s.io/web-allow-all-ns-monitoring created
Query this web server from default
namespace, without labelling the application type=monitoring
, observe it is blocked:
$ kubectl run test-$RANDOM --rm -i -t --image=alpine -- sh
If you don't see a command prompt, try pressing enter.
/ # wget -qO- --timeout=2 http://web.default
wget: download timed out
(traffic blocked)
Query this web server from default
namespace, labelling the application type=monitoring
, observe it is blocked:
kubectl run test-$RANDOM --labels="type=monitoring" --rm -i -t --image=alpine -- sh
If you don't see a command prompt, try pressing enter.
/ # wget -qO- --timeout=2 http://web.default
wget: download timed out
(traffic blocked)
Query this web server from other
namespace, without labelling the application type=monitoring
, observe it is blocked:
$ kubectl run test-$RANDOM --namespace=other --rm -i -t --image=alpine -- sh
If you don't see a command prompt, try pressing enter.
/ # wget -qO- --timeout=2 http://web.default
wget: download timed out
(traffic blocked)
Note: see remark below how to use OR in the network policy , so this example will work as well
Query this web server from other
namespace, labelling the application type=monitoring
, observe it is allowed:
kubectl run test-$RANDOM --namespace=other --labels="type=monitoring" --rm -i -t --image=alpine -- sh
If you don't see a command prompt, try pressing enter.
/ # wget -qO- --timeout=2 http://web.default
<!DOCTYPE html>
<html>
<head>
...
(traffic allowed)
Please note that that example below is OR condition
ingress:
- from:
- namespaceSelector: # chooses all pods in namespaces labelled with team=opera
matchLabels:
team: operations
- podSelector: # chooses pods with type=monitoring
matchLabels:
type: monitoring
while this example is AND condition
ingress:
- from:
- namespaceSelector: # chooses all pods in namespaces labelled with team=opera
matchLabels:
team: operations
podSelector: # chooses pods with type=monitoring
matchLabels:
type: monitoring
kubectl delete networkpolicy web-allow-all-ns-monitoring
kubectl delete namespace other
kubectl delete pod web
kubectl delete service web