Using network policies in Kubernetes

Network policies are used to control network traffic in a Kubernetes cluster. By default, all outbound and inbound connections are allowed for a pod. You can provide network isolation for your pods by using network policies.

A network policy applies to a pod or a group of pods and sets a list of allowed targets for its ingress and egress rules. These targets can be one of the following:

  • Specific pods (pods matching a label are allowed)
  • Specific namespaces (all pods in the namespace are allowed)
  • IP address blocks (endpoints with an IP address in the block are allowed)

If you want to isolate a pod for outbound connections, you need to create a network policy that selects this pod and has Egress in its policyTypes. Similarly, to isolate a pod for inbound connections, a network policy should select this pod and have Ingress in its policyTypes. In this case, the only allowed connections to and from the pod will be those allowed by the ingress and egress lists. Note that traffic to and from the node where a pod is running is always allowed, as well as reply traffic for allowed connections.

Network policies are additive, so you can have multiple policies for a pod. Allowed connections to and from the pod will be the sum of the allow rules in the applicable policies. If the allow rules are not specified, all of the connections will be blocked.

To allow a connection from one pod to another, both of these pods must have respective egress and ingress policies allowing each other. If either side does not allow the connection, it will not happen.

To ensure that your Kubernetes cluster is protected from accidental network exposure, you can create a default deny all policy, and then add specific allow policies for the required traffic flows.

Limitations

  • The Flannel network plugin, default for Kubernetes versions 1.27.x–1.29.x, does not allow using network policies. Starting with version 1.30.x, Kubernetes clusters are created with the Cilium network plugin, which supports network policies.

Prerequisites

  • A Kubernetes cluster is created with the Cilium network plugin. To use Kubernetes version 1.29.3 with network policy support, specify the network_driver=cilium label in the Labels section, as described in Creating and deleting Kubernetes clusters.

To create a default deny all network policy

Use the following default-deny-all.yaml file:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress

This manifest specifies the network policy default-deny-all that applies to all pods in the namespace and prevents all ingress and egress traffic.

To create a default allow all network policy for a pod

Use the following allow-all-demo.yaml file:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all-demo
spec:
  podSelector:
    matchLabels:
      app: demo
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - {}
  egress:
    - {}

This manifest specifies the network policy allow-all-demo that applies to all pods labeled app=demo and allows all ingress and egress traffic.

To create a pod-based network policy

Use the following pod-based-policy.yaml file that defines the NetworkPolicy object:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: pod-based-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: pod1
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
      - podSelector:
          matchLabels:
            app: pod2
  egress:
    - to:
      - podSelector:
          matchLabels:
            app: pod2

This manifest specifies the network policy pod-based-policy that applies to all pods labeled app=pod1 and allows ingress and egress traffic from all pods with the label app=pod2.

To create a namespace-based network policy

Use the following namespace-based-policy.yaml file that defines the NetworkPolicy object:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: namespace-based-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: pod1
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
      - namespaceSelector:
          matchLabels:
            kubernetes.io/metadata.name: demo-namespace
  egress:
    - to:
      - namespaceSelector:
          matchLabels:
            kubernetes.io/metadata.name: demo-namespace

This manifest specifies the network policy namespace-based-policy that applies to all pods labeled app=pod1 and allows ingress and egress traffic from all pods running in the namespace demo-namespace.

To create an IP-based network policy

Use the following ip-based-policy.yaml file that defines the NetworkPolicy object:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: ip-based-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: pod1
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
      - ipBlock:
          cidr: 10.10.10.0/24
  egress:
    - to:
      - ipBlock:
          cidr: 10.10.10.0/24

This manifest specifies the network policy ip-based-policy that applies to all pods labeled app=pod1 and allows ingress and egress traffic from the subnet 10.10.10.0/24.