NetworkPolicy Kubernetes

This time i will create a deployment which will have an nginx as an image and i will run two alpine pods and use their shell to access the website (one pods won’t be able to curl the page since we will use a network policy to deny it)

For clarification:

The entities that a Pod can communicate with are identified through a combination of the following 3 identifiers:

  1. Other pods that are allowed (exception: a pod cannot block access to itself)

  2. Namespaces that are allowed

  3. IP blocks (exception: traffic to and from the node where a Pod is running is always allowed, regardless of the IP address of the Pod or the node)

When defining a pod- or namespace- based NetworkPolicy, you use a selector to specify what traffic is allowed to and from the Pod(s) that match the selector.

Meanwhile, when IP based NetworkPolicies are created, we define policies based on IP blocks (CIDR ranges).

Deployment.yml file content

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: nginx
        ports:  
        - containerPort: 80
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  type: NodePort
  selector:
    app: myapp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30009

Now i will define my network policy :

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-traffic-to-myappdeployment
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: myapp
  policyTypes:
  - Ingress 
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: curlpod
    ports:
      - protocol: TCP
        port: 80

Run two alpine pods

kubectl run curlpod --image=alpine -- /bin/sh -c "sleep 3600”

Add the label (Necessary for the network policy):

Since i will allow only pods with ‘app=curlpod’ label to hit the webpage i will add it to the first pod

kubectl label pods curlpod app=curlpod

Second pod:

kubectl run curlpod2 --image=alpine -- /bin/sh -c "sleep 3600”

Add the label for this pod:

kubectl label pods curlpod2 app=myapp2

Now this pod wont be able to access the web page since it’s label is not listed in the netwrok policy ‘matchLabels’ section

kubectl exec -it curlpod -- /bin/sh

/ # curl myapp-service
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

kubectl exec -it curlpod2 -- /bin/sh

/ # curl myapp-service
curl: (28) Failed to connect to myapp-service port 80 after 129201 ms: Couldn't connect to server