Kubernetes network policy doesn't work as expected

4/14/2021

I'm new to the Kubernetes and try to set up a network policy to protect my api.

Here is my network NetworkPolicy

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-network-policy
  namespace: api
spec:
  podSelector: {}

  policyTypes:
    - Ingress
  ingress:
    - from:
      - namespaceSelector:
          matchLabels:
            name: api
      - namespaceSelector:
          matchLabels:
            name: backend
      - podSelector:
          matchLabels:
            rule: database
        

In my design, all pods in the namespace "api" allows ingress only from namespace:api, namespace:backend and pods with rule of database. However, when I add a test namespace and send request to the pods in the namespace:api, it doesn't deny that request.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-deployment
  namespace: test
spec:
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      containers:
      - name: test
        image: test
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"
        ports:
        - containerPort: 5000


---

apiVersion: v1
kind: Service
metadata:
  name: test-service
  namespace: test
spec:
  type: NodePort
  selector:
    app: test
  ports:
  - port: 5000
    targetPort: 5000
    nodePort: 32100

my ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-backend-service
  namespace: backend
  labels:
    rule: ingress
  annotations:
    kubernetes.io/ingress.class: 'nginx'
    nginx.ingress.kubernetes.io/use-regex: 'true'
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - http:
        paths:
          - path: /api/?(.*)
            pathType: Prefix
            backend:
              service:
                name: chatbot-server
                port:
                  number: 5000

one of my api:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-worker-deployment
  namespace: api
spec:
  replicas: 1
  selector:
    matchLabels:
      api: redis-worker
  template:
    metadata:
      labels:
        api: redis-worker
    spec:
      containers:
      - name: redis-worker
        image: redis-worker
        env:
          - name: REDIS_HOST
            value: redis
          - name: REDIS_PORT
            value: "6379"
        resources:
          requests:
            memory: "32Mi"
            cpu: "100m"
          limits:
            memory: "128Mi"
            cpu: "500m"
        ports:
        - containerPort: 5000

---

apiVersion: v1
kind: Service
metadata:
  name: redis-worker-service
  namespace: api
  labels:
    rule: api
spec:
  selector:
    api: redis-worker 
  ports:
  - port: 5000
    targetPort: 5000

my namespace:

apiVersion: v1
kind: Namespace
metadata:
  name: test

--- 

apiVersion: v1
kind: Namespace
metadata:
  name: backend

---

apiVersion: v1
kind: Namespace
metadata:
  name: api

my code in the test pod

from flask import Flask, url_for, request, jsonify
import requests
import config
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def hello():
    x = requests.get("http://redis-worker-service.api:5000").json()
    print(x)
    return x
if __name__ == '__main__':
    app.run(host=config.HOST, port=config.PORT, debug=config.DEBUG)

when I go to http://myminikubeip:32100, the request should be denied but it doesn't work

-- Abbott
flask
kubernetes
kubernetes-networkpolicy
networking
python

1 Answer

4/14/2021

Hi all I make stupid mistakes. I forget to set up a network plugin for Minikube as Use Cilium for NetworkPolicy

Also, I don't set any egress so all egress will be denied.

fixed one:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-network-policy
  namespace: api
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
      - namespaceSelector:
          matchLabels:
            purpose: api
      - namespaceSelector:
          matchLabels:
            purpose: backend
      - podSelector:
          matchLabels:
            rule: database
  egress:
    - {}

also, set labels for namespace as following

apiVersion: v1
kind: Namespace
metadata:
  name: test

--- 

apiVersion: v1
kind: Namespace
metadata:
  name: backend
  labels:
    purpose: backend

---

apiVersion: v1
kind: Namespace
metadata:
  name: api
  labels:
    purpose: api

I'm sorry I post such a stupid question and I hope others can learn something from my mistakes.. I'm so sorry

helpful link for network-policy

-- Abbott
Source: StackOverflow