Network policy and micro segmentation

In Kubernetes, the network policy resource Opens in a new tab is a set of network traffic rules that are applied to a group of pods in a Kubernetes cluster.

The network policy specifies how a pod is allowed to communicate with others. Network policy controllers (running as pods in the Kubernetes cluster) convert the requirements and restrictions of the network policies that are retrieved from the Kubernetes API into the network infrastructure.

NetworkPolicy can be applied to running pods in Kubernetes. Ingress and egress rules can contain a pod selector and layer 3 subnets in one namespace at a time.

The declarative nature of NetworkPolicy as a yaml document that can be committed to source control makes it an ideal part of DevSecOps deployment pipelines. Since the policy document is abstracted from the actual network implementation, the yaml declares just the intents while it allows the CNI to implement the rules in the network fabric.

To set your network policy, see Creating a NetworkPolicy.

The following policies are common defaults to apply in practice.

Common NetworkPolicy: Deny all ingress

A good practice is to define and apply a default NetworkPolicy to deny all ingress traffic to all pods in all application namespaces, then whitelist pods and subnets based on application needs. The following NetworkPolicy selects all pods in prod namespace, and contains no ingress rules, indicating that all ingress traffic is dropped.

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: default-deny-all-ingress
  namespace: prod
spec:
  podSelector: {}
  ingress: []

Common NetworkPolicy: Deny external egress

Another good practice is to define and apply a default NetworkPolicy to deny egress traffic outside of the cluster for application namespaces, then whitelist any external subnets for pods as needed. The following network policy selects all pods in the prod namespace, and allows egress to pods within the cluster (all namespaces). All other traffic is dropped.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-external-egress
  namespace: prod
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector: {}

Common NetworkPolicy: Whitelist pod ingress traffic

As application developers write microservices, as part of the development cycle they can declaratively define NetworkPolicy resources in yaml as a deployment resource. These resources define any ingress rules that are required, for example, any dependencies on the microservice, expressed by using pod selectors. For example, the following NetworkPolicy allows traffic to the customer pods from the web pods on port 80 in the prod namespace:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: customer-api-allow-web
  namespace: prod
spec:
  podSelector:
    matchLabels:
      app: customer
  ingress:
    - ports:
      - port: 80
      from:
      - podSelector:
          matchLabels:
            app: web

Common NetworkPolicy: Allow all external ingress traffic

On a web tier, ingress controller, or API gateway, all traffic from outside of the cluster is allowed. For example, create a NetworkPolicy in prod namespace that selects the web pods and allows ingress from all sources:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: web-allow-external
  namespace: prod
spec:
  podSelector:
    matchLabels:
      app: web
  ingress:
  - ports:
    - port: 80
    from: []

If an external load balancer is used, instead of allowing ingress from all sources, the ingress must be limited to just the external load balancer.

Common NetworkPolicy: Whitelist pod egress to external subnets

For services that require egress to resources outside of the cluster, for example, a database, external API, or user directory, whitelist the subnet that the network resource is on. For example, to allow the orders service to talk to the orders database in 172.16.32.0/27 on port 3306, use the following commands:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: customer-api-allow-web
  namespace: prod
spec:
  podSelector:
    matchLabels:
      app: orders
  policyTypes:
  - Egress
  egress:
  - ports:
    - port: 3306
    to:
    - ipBlock:
        cidr: 172.16.32.0/27

For more examples of NetworkPolicy, see Kubernetes network policy recipes Opens in a new tab.

Separation of duties

It is important to enforce separation of duties. Use the IBM® Cloud Private provided roles and Kubernetes RBAC to restrict who is allowed to deploy resources to each namespace. Loose permissions can make it easy to circumvent the network policy by deploying containers that match the pod label selector.

Create a service account for a CI/CD deployment tool with permissions to deploy containers, and do not allow any other users to create these deployments. Enforce controls on what triggers a deployment, that is, who can commit source that triggers a deployment to the application cluster.

The network administrator is responsible for applying and auditing the network policies across the cluster for compliance. Since NetworkPolicy is defined declaratively and reviewed before deployment, any existing network policies must be automated and match what is deployed in the cluster at any time.