Network Policies
Overview
Network Policies are used to regulate connectivity between Kubernetes namespaces. Every namespace in the cluster has network policies which only allow inbound traffic from the ingress controllers namespace (so that incoming requests can be routed to your web applications).
A network policy allows connection based on PodSelector
and/or NamespaceSelector
. The policy will then filter requests based on namespace or pod labels.
Namespace Label
This example demonstrates using a namespaceSelector
to route traffic based on a namespace label.
Any namespace label can be used in the network policy.
For clarity, and to avoid overlap with other namespaces, let’s make our label key:
cloud-platform.justice.gov.uk/namespace
# 00-namepace.yaml
---
apiVersion: v1
kind: Namespace
metadata:
name: source-namespace
labels:
cloud-platform.justice.gov.uk/namespace: "source-namespace" # this is the label
cloud-platform.justice.gov.uk/is-production: "false"
cloud-platform.justice.gov.uk/environment-name: "dev"
annotations:
cloud-platform.justice.gov.uk/business-unit: "HMPPS"
cloud-platform.justice.gov.uk/application: "court-probation"
cloud-platform.justice.gov.uk/owner: "andy.marke@digital.justice.gov.uk: andy.marke@digital.justice.gov.uk"
cloud-platform.justice.gov.uk/source-code: "https://github.com/ministryofjustice/court-probation-service"
Network Policy
Once the relevant label has been added to the namespace, the policy can be created.
The policy below allows all traffic from namespaces which have a label called cloud-platform.justice.gov.uk/namespace
with the the value source-namespace
to route to the namespace called target-namespace
.
# 04-networkpolicy.yaml
# allow-source-namespace.yaml
---
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: allow-source-namespace
namespace: target-namespace
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
cloud-platform.justice.gov.uk/namespace: "source-namespace'
Note: For more complex use-cases, or if the policy is going to be specific to a Pod, see here
Accessing the service
To access a service in the target namespace from the source namespace we need to add the target namespace name to the domain name of the service, e.g:
curl myservice.target-namespace
Cross Namespace Network Access
The following user guide demostrates how cross namespace network access works. The advised option is to use a service and network policy to communicate within the cluster.
Using a service and specifying a NetworkPolicy that allows Ingress from the source namespace, this allows a connection directly on an internal IP, without going via the Nginx reverse proxy in front. This increases throughput and reduces latency, with the caveat that logs will not be visible in the ingress Kibana index, only in the cluster (pod) logs.
To do this by adding a NetworkPolicy to 04-networkpolicy.yaml
in the source namespace
Example:
---
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: allow-token-verification-api-dev
namespace: example-dev
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
component: token-verification-api-dev // This should match the namespace label
To also allow this change to work within the 00-namespace.yaml
, a label will need to be added for component. This needs to match what is in the component in the matchLabels section on the NetworkPolicy
Example:
apiVersion: v1
kind: Namespace
metadata:
labels:
component: token-verification-api-dev // This should match the component in the NetworkPolicy