Introduction
You need proper CNI to use Network Policy. Cilium will be used for CNI in the scenario. Network Policy can be tested by following scenario.
Prerequisite
- K8s with proper CNI
Network Policy
The Prevention PlanWe have a plan to block all incoming traffic in a namespace prod
and open incoming traffic the specific pod in the prod
namespace with named target
pod from all traffic on port 80
with secure
namespace and allow incoming traffic from all Pods with the label app=allow.
- A default deny network policy is a policy that blocks all traffic in a namespace by default.
- Create a network policy that allows certain traffic on port
80
to reach the Pod with app=secure label in the all namespace. - The policy should allow incoming traffic from all Pods in the
secure
namespace.
1. Create a namespace which named prod
1
$ kubectl create namespace prod
namespace/prod created
2. Create a namespace which named secure
with label ns=client
1
$ kubectl create namespace secure
namespace/secure created
$ kubectl label namespace secure ns=secure
namespace/secure labeled
3. Create a network policy to deny all ingress for the prod
namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: prod-deny-network-policy
namespace: prod
spec:
podSelector: {}
policyTypes:
- Ingress
$ kubectl apply -f prod-deny.yaml
networkpolicy.networking.k8s.io/prod-deny-network-policy created
4. Create a pod named target
in prod
namespace and secure in secure namespace.
$ kubectl run target --image=nginx -n prod
$ kubectl run secure --image=nginx -n secure
$ kubectl run client-one --image=nginx
$ kubectl run client-two --image=nginx
$ kubectl get pods -n prod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
target 1/1 Running 0 72m 10.0.0.193 minikube <none> <none>
Private target ip address is 10.0.0.193
5. Make a http call to target pod from secure pod in secure pod
Inside to secure containerExit with
$ kubectl exec -it secure -n secure -- bash
root@secure:/# curl 10.0.0.193
curl: (28) Failed to connect to 10.0.0.193 port 80: Connection timed out
- Deny Network Policy is working
6. Obtain the pod’s label and namespace label of prod and secure
$ kubectl get pod target -n prod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
target 1/1 Running 0 6m47s run=target
$ kubectl get namespace secure --show-labels
NAME STATUS AGE LABELS
secure Active 28m kubernetes.io/metadata.name=secure,ns=secure
7. Create a network policy to allow all pods ingress traffic in prod
namespace from pods and the pod in all namespace with label app=secure.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-traffics
namespace: prod
spec:
podSelector:
matchLabels:
run: target
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
ns: secure
- namespaceSelector:
matchLabels: {}
podSelector:
matchLabels:
app: secure
ports:
- protocol: TCP
port: 80
$ kubectl apply -f allow-traffics.yaml
networkpolicy.networking.k8s.io/allow-traffics created
8. Test Connection by cases
Case 1: The pod in the secure
namespace can connect pods int prod
namespace.1
$ kubectl exec -it secure -n secure -- bash
root@secure:/# curl 10.0.0.193
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
Case 2: The pod with label app=secure
in the any namespaces can connect pods int prod
namespace.Add the label with app=secure
$ kubectl label pod client-one app=secure
pod/client-one labeled
$ kubectl exec -it client-one -- bash
root@client-one:/# curl 10.0.0.193
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
Case 3: The pod without label app=secure
in the any namespaces can not connect pods int prod
namespace.
$ kubectl exec -it client-two -- bash
root@client-two:/# curl 10.0.0.193
curl: (28) Failed to connect to 10.0.0.193 port 80: Connection timed out
- All cases is working properly.