Chuyển đến nội dung chính

LESSON 16: NETWORK POLICY

Secure your Kubernetes network with NetworkPolicy: Pod selectors, Ingress/Egress rules, default-deny pattern. Advanced Cilium Network Policies with L7 policies based on HTTP method, path, headers.

🔒 DevSecOps — Lesson 16 LESSON 16: NETWORK POLICY

KUBERNETES: FROM BASIC TO ADVANCED

Module 4: Networking

xdev.asia

🎯 Lesson Objective

Understand NetworkPolicy to control traffic in/out of Pods. Implement default-deny pattern, allow specific traffic, and use Cilium Network Policies for L7 control.

1. Why do we need NetworkPolicy?

By default, Kubernetes allows all traffic between all Pods in the cluster — every Pod can call every other Pod. This is a serious security risk.

NetworkPolicy allows you to define whitelist rules: only explicitly allowed traffic will pass.

Important: NetworkPolicy only works if CNI plugin supports it (Cilium, Calico, Weave). Flannel does not support NetworkPolicy.

2. NetworkPolicy Anatomy

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: my-policy
  namespace: production
spec:
  podSelector:          # áp dụng cho Pods nào?
    matchLabels:
      app: backend
  policyTypes:
  - Ingress             # kiểm soát traffic VÀO pods được chọn
  - Egress              # kiểm soát traffic RA KHỎI pods được chọn
  ingress:
  - from:               # allow traffic từ đâu?
    - podSelector:
        matchLabels:
          app: frontend # chỉ cho phép từ frontend pods
    ports:
    - protocol: TCP
      port: 8080
  egress:
  - to:                 # allow traffic đến đâu?
    - podSelector:
        matchLabels:
          app: database # chỉ cho phép đến database pods
    ports:
    - protocol: TCP
      port: 5432

3. Default-Deny Pattern — Best Practice

Start with "deny all", then open each necessary traffic stream.

3.1 Default Deny All Ingress

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: production
spec:
  podSelector: {}    # {} = apply to ALL pods in namespace
  policyTypes:
  - Ingress
  # ingress không được khai báo = deny all ingress

3.2 Default Deny All Egress

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-egress
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Egress
  # egress không được khai báo = deny all egress

3.3 Allow DNS (important if denying egress)

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system
    ports:
    - protocol: UDP
      port: 53
    - protocol: TCP
      port: 53

4. Allow Specific Traffic Patterns

Frontend → Backend

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080

Cross-namespace: Allow from other namespace__HTMLTAG_98___
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-monitoring
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  ingress:
  - from:
    # Chỉ cho phép từ namespace "monitoring"
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: monitoring
    ports:
    - protocol: TCP
      port: 9090  # Prometheus scrape

Combined: Pod selector AND namespace selector__HTMLTAG_100___
ingress:
- from:
  # Pod phải có label app=prometheus VÀ trong namespace monitoring
  - namespaceSelector:
      matchLabels:
        kubernetes.io/metadata.name: monitoring
    podSelector:     # LƯU Ý: cùng item (AND logic)
      matchLabels:
        app: prometheus

Khác với:

  • from:

    Pod trong namespace monitoring HOẶC pod có label app=prometheus (OR logic)

    • namespaceSelector: matchLabels: kubernetes.io/metadata.name: monitoring
    • podSelector: # LƯU Ý: item riêng biệt (OR logic) matchLabels: app: prometheus

5. Cilium Network Policies — L7

Standard Kubernetes NetworkPolicy only controls L3/L4 (IP, port). Cilium CiliumNetworkPolicy allows L7 control.

5.1 HTTP Method and Path

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: api-l7-policy
  namespace: production
spec:
  endpointSelector:
    matchLabels:
      app: api-server
  ingress:
  - fromEndpoints:
    - matchLabels:
        app: frontend
    toPorts:
    - ports:
      - port: "8080"
        protocol: TCP
      rules:
        http:
        # Chỉ cho phép GET /api/v1/users
        - method: GET
          path: "^/api/v1/users.*"
        # Chỉ cho phép POST /api/v1/orders
        - method: POST
          path: "^/api/v1/orders"
        # Không cho phép GET /admin/* (không match → deny)

5.2 DNS-based Policies

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-external-dns
spec:
  endpointSelector:
    matchLabels:
      app: backend
  egress:
  # Chỉ cho phép kết nối đến api.stripe.com
  - toFQDNs:
    - matchName: "api.stripe.com"
    toPorts:
    - ports:
      - port: "443"
        protocol: TCP
  # Chỉ cho phép *.amazonaws.com
  - toFQDNs:
    - matchPattern: "*.amazonaws.com"
    toPorts:
    - ports:
      - port: "443"
        protocol: TCP

6. Verify and Debug NetworkPolicy

# Test connectivity từ pod này đến pod khác
kubectl exec -n production frontend-pod -- curl http://backend-service:8080/api

Nếu bị block:

kubectl exec -n production frontend-pod -- curl --connect-timeout 5 http://backend-service:8080

curl: (28) Connection timed out

Cilium: xem dropped packets

cilium monitor --type drop

Hubble: theo dõi traffic

hubble observe --namespace production --verdict DROPPED hubble observe --pod frontend-pod --protocol tcp

7. Best Practices

  • Start with default-deny: applies to all production namespace
  • Least privilege: only open traffic that is absolutely necessary
  • Label consistent: NetworkPolicy depends on label selectors — set label consistently
  • Test before applying to production: use Hubble audit mode to see which traffic will be blocked
  • Document policies: explains why each policy was created

Summary

  • NetworkPolicy: whitelist rules for Pod traffic
  • Default-deny pattern: block all → allow specific
  • Selectors: podSelector, namespaceSelector (AND logic within items, OR logic between items)
  • Cilium CiliumNetworkPolicy: L7 HTTP, DNS-based policies
  • Need CNI support: Cilium, Calico (not Flannel)