Updated on 2024-12-11 GMT+08:00

Network Policies

Network policies are designed by Kubernetes to restrict pod access. It is equivalent to a firewall at the application layer to enhance network security. The capabilities of network policies are determined by the network add-ons available in the cluster.

By default, if a namespace does not have any policy, pods in the namespace accept traffic from any source and send traffic to any destination.

NetworkPolicy rules are classified into the following types:

  • namespaceSelector: This selects particular namespaces for which all pods should be allowed as ingress sources or egress destinations.
  • podSelector: This selects particular pods in the same namespace as the NetworkPolicy which should be allowed as ingress sources or egress destinations.
  • ipBlock: This selects particular IP CIDR ranges to allow as ingress sources or egress destinations. (Only egress support IP address blocks.)

Using Ingress Rules Through YAML

  • Scenario 1: Use a network policy to limit access to a pod to only pods with specific labels.
    Figure 1 podSelector

    The pod labeled with role=db only permits access to its port 6379 from pods labeled with role=frontend. To do so, perform the following operations:

    1. Create the access-demo1.yaml file.
      vim access-demo1.yaml

      File content:

      apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: access-demo1
        namespace: default
      spec:
        podSelector:                  # The rule takes effect for pods with the role=db label.
          matchLabels:
            role: db
        ingress:                      # This is an ingress rule.
        - from:
          - podSelector:              # Only allow the access of the pods labeled with role=frontend.
              matchLabels:
                role: frontend
          ports:                      # Only TCP can be used to access port 6379.
          - protocol: TCP
            port: 6379
    2. Run the following command to create the network policy based on the access-demo1.yaml file:
      kubectl apply -f access-demo1.yaml

      Expected output:

      networkpolicy.networking.k8s.io/access-demo1 created
  • Scenario 2: Use a network policy to limit access to a pod to only pods in a specific namespace.
    Figure 2 namespaceSelector

    The pod labeled with role=db only permits access to its port 6379 from pods in the namespace labeled with project=myproject. To do so, perform the following operations:

    1. Create the access-demo2.yaml file.
      vim access-demo2.yaml

      File content:

      apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: access-demo2
      spec:
        podSelector:                  # The rule takes effect for pods with the role=db label.
          matchLabels:
            role: db
        ingress:                      # This is an ingress rule.
        - from:
          - namespaceSelector:        # Only allow the access of the pods in the namespace labeled with project=myproject.
              matchLabels:
                project: myproject
          ports:                      # Only TCP can be used to access port 6379.
          - protocol: TCP
            port: 6379
    2. Run the following command to create the network policy based on the access-demo2.yaml file:
      kubectl apply -f access-demo2.yaml

      Expected output:

      networkpolicy.networking.k8s.io/access-demo2 created

Using Egress Rules Through YAML

Egress supports podSelector, namespaceSelector, and IPBlock.

Only clusters of v1.23 or later support egress rules.

  • Scenario 1: Use a network policy to limit a pod's access to specific addresses.
    Figure 3 IPBlock

    The pod labeled with role=db only permits access to the 172.16.0.16/16 CIDR block, excluding 172.16.0.40/32 within it. To do so, perform the following operations:

    1. Create the access-demo3.yaml file.
      vim access-demo2.yaml

      File content:

      apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: access-demo3
        namespace: default
      spec:
        policyTypes:                  # Must be specified for an egress rule.
          - Egress
        podSelector:                  # The rule takes effect for pods with the role=db label.
          matchLabels:
            role: db
        egress:                       # Egress rule
        - to:
          - ipBlock:
              cidr: 172.16.0.16/16    # Allow access to this CIDR block in the outbound direction.
              except:
              - 172.16.0.40/32        # Block access to this address in the CIDR block.
    2. Run the following command to create the network policy based on the access-demo3.yaml file:
      kubectl apply -f access-demo3.yaml

      Expected output:

      networkpolicy.networking.k8s.io/access-demo3 created
  • Scenario 2: Use a network policy to limit access to a pod to only pods with specific labels and this pod can only access specific pods.
    Figure 4 Using both ingress and egress

    The pod labeled with role=db only permits access to its port 6379 from pods labeled with role=frontend, and this pod can only access the pods labeled with role=web. You can use the same rule to configure both ingress and egress in a network policy. To do so, perform the following operations:

    1. Create the access-demo4.yaml file.
      vim access-demo2.yaml

      File content:

      apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: access-demo4
        namespace: default
      spec:
        policyTypes:
        - Ingress
        - Egress
        podSelector:                  # The rule takes effect for pods with the role=db label.
          matchLabels:
            role: db
        ingress:                      # This is an ingress rule.
        - from:
          - podSelector:              # Only allow the access of the pods labeled with role=frontend.
              matchLabels:
                role: frontend
          ports:                      # Only TCP can be used to access port 6379.
          - protocol: TCP
            port: 6379
        egress:                       # Egress rule
        - to:
          - podSelector:              # Only pods with the role=web label can be accessed.
              matchLabels:
                role: web
    2. Run the following command to create the network policy based on the access-demo4.yaml file:
      kubectl apply -f access-demo4.yaml

      Expected output:

      networkpolicy.networking.k8s.io/access-demo4 created