Reference

Overview

This page contains recommendations for creating and configuring Cilium network policies.


Best practices for network policies

1. Principle of least privilege

Allow only necessary traffic. Instead of “allow all”, explicitly indicate allowed directions, ports and selectors.

2. Start with allowing rules

First, determine what traffic the application needs (DNS, KubeAPI, backend services) and add allowing rules. Add prohibitive rules point by point.

3. Always allow DNS

If pods are accessed by name (FQDN, Service), resolve egress to Kubernetes DNS:

egress:
  - toEndpoints:
      - matchLabels:
          io.kubernetes.pod.namespace: kube-system
          k8s-app: kube-dns
    toPorts:
      - ports:
          - port: "53"
            protocol: UDP
          - port: "53"
            protocol: TCP

4. Allow access to KubeAPI when necessary

Pods that need access to the API server (operators, controllers) must have egress to kube-apiserver (toEntities).

5. Ingress and network policies

When policies are enabled, explicitly allow incoming traffic from the Ingress controller to the backend pods. Otherwise, requests from outside will not reach the application.

6. Use Pod Selectors

Limit policies to selectors (endpointSelector, fromEndpoints, toEndpoints) to avoid affecting unnecessary pods.

7. Test in the dev namespace

Before using in production, check the policies in the test namespace. Use kubectl run and curl to check connectivity.

8. Document policies

Add description to CiliumNetworkPolicy to make it clear why the rule was created.

9. Avoid deny-all conflicts

The deny-all policy blocks all traffic. Make sure that there are all necessary allowing rules in front of it or in other policies.

10. Cluster vs namespace policies

ClusterwideCiliumNetworkPolicy applies to the entire cluster. Use for general rules (eg DNS access). Namespace policies - to isolate specific applications.