In order to secure the traffic flowing through a Kubernetes cluster, administrators must configure appropriate pod network policies. This article provides an overview of pod network policies and how to configure them for a Kubernetes deployment. Pod network policies are used to control the traffic that flows between pods in a Kubernetes deployment. By default, all traffic between pods is unrestricted. However, this can be undesirable if the goal is to protect sensitive data or resources from being accessed by unauthorized users. Pod network policies can be used to restrict traffic between pods based on specific criteria, such as source or destination IP address, port number, or protocol type. There are several ways to configure pod network policies:
- Using the kubectl policy command: This approach is useful if administrators want to apply policy settings uniformly across all nodes in a Kubernetes deployment. The kubectl policy command supports several configuration options that allow administrators to restrict traffic in various ways. For example, the –from-port option can be used to restrict traffic from a specific port number on nodes in a cluster. The –to-port option can be used to restrict traffic from a specific port number on nodes outside of the cluster. The –protocol option can be used to restrict traffic based on protocol type (e.g., TCP or UDP). The –source and –destination options can be used together to restrict traffic based on source and destination IP addresses, respectively. The –include and –exclude options can be used together to specify lists of IP addresses or ports that should not be restricted by policy settings. Finally, the –permit-all option allows all traffic between pods in a deployment to pass through without restriction.
- Using custom controller code: Administrators may also want flexibility not available through kubectl policy commands alone (e.g., allowing certain types of traffic but not others). In this case, they may want ..
Kubernetes Pods can freely communicate with each other by default. This poses a security risk when your cluster’s used for multiple applications or teams. Errant behavior or malicious access in one Pod could direct traffic to the other Pods in your cluster.
This article will teach you how to avoid this scenario by setting up network policies. These rules let you control Pod-to-Pod traffic flows at the IP address level (OSI layer 3 or 4). You can precisely define the ingress and egress sources permitted for each Pod.
Creating a Network Policy
Network policies are created by adding NetworkPolicy objects to your cluster. Each policy defines the Pods it applies to and one or more ingress and egress rules. Here’s a basic policy manifest:
This network policy applies to any Pod with a component: database label in the app namespace. It states that ingress (incoming) and egress (outgoing) traffic is only allowed from and to Pods with a component: api label. Any requests originating from other Pods, such as component: web-frontend, will be blocked.
Network policies can be applied like any other object by using Kubectl. They’ll take effect immediately after they’re created. You can add the networking policy before you start the Pods it selects.
How Network Policies Work
Network policies are implemented by your cluster’s active networking plugin. Your policies won’t have any effect if your plugin doesn’t support the feature. Most popular options such as Calico and Cilium ship with network policy support enabled.
When a network policy applies to a Pod, the plugin will inspect its traffic to check it’s compliant with the policy’s requirements. Any connections that don’t meet the criteria will be disallowed. The Pod that tried to initiate the connection will find the remote host is unreachable, either because it was trying to access a resource blocked by an egress rule, or because a remote Pod denied the incoming connection using an ingress rule.
A successful connection between two Pods can only be established when the network policies on both of them permit it. The connection could be forbidden by an egress rule of the initiating Pod, or an ingress rule on the target.
Network policies are always additive in nature. When multiple policies select the same Pod, the list of permitted ingress and egress sources will be the combination of all the policies.
Example Network Policies
Network policies support many different options for customizing the Pods they target and the types of connection that are allowed. The following examples showcase several common use cases.
Apply a policy to every Pod in the namespace, only allowing Ingress traffic from a specific IP address block
The empty podSelector block means all the namespace’s Pods are targeted by the policy. The ipBlock rule restricts ingress traffic to Pods with an IP address in the specified range. Egress traffic is not blocked.
Allow Ingress traffic from an IP address block, but exclude some specific IPs
ipBlock rules support an except field to exclude traffic originating from, or being directed to, specific IPs.
Allow Ingress traffic from all Pods in the namespace, but only from a specific port
The ports field is available on ingress and egress rules. It defines the ports that traffic can be received from and sent to. You can optionally specify a range of ports, such as 3000 – 3500, by setting the endPort field (3500) in addition to port (3000).
Allow traffic from Pods with a specific label that exist in a different namespace
The policy states that any Pod labelled component: database can reach all the Pods in the database namespace, if its own namespace is labelled demo-app.
You can allow traffic from all the Pods in an external namespace by creating a rule that only includes a namespaceSelector field.
Explicitly allow all traffic
Sometimes you might want to explicitly allow all traffic of a particular type within a namespace. Include the type in your policy but supply an empty Pod selector and no rules:
All the Pods in the namespace can freely communicate, as if there was no policy. Creating the policy anyway lets you indicate your intentions to other cluster users. They might question the presence of a namespace with unrestricted networking in a cluster which has otherwise been secured.
When to Use Network Policies
Network policies should be created for each of the namespaces and Pods in your cluster. This better isolates your Pods and puts you in control of traffic flow.
Try to make your policies as granular as possible. Widening access too much, such as allowing access between all Pods in a namespace, leaves you exposed to risks if one of your containers is compromised. Consider using precise selectors to identify individual ingress and egress remotes for sensitive Pods such as authentication services, databases, and payment handlers.
Kubernetes doesn’t enable any network policies by default which can allow oversights to occur, even if you intend all Pods to be protected by a policy. You can mitigate against this risk by adding a catch-all policy to your namespaces. This policy selects every Pod in the namespace and applies a rule that forbids all network communication:
Network policies are always scoped to namespaces so you’ll need to create a separate catch-all for each one.
Summary
Kubernetes allows all the Pods in your cluster to communicate with each other. This is too permissive for real-world applications running in multi-purpose clusters. Network policies address this problem by providing a firewall-like system for managing the ingress sources and egress targets that each Pod accepts.
It’s good practice to configure a network policy on all of your Pods. This will secure your cluster so only legitimate traffic flows are permitted. Network policies are only one part of Kubernetes security, however: other protection mechanisms such as RBAC and Pod security contexts are also essential tools for hardening your environment.