This tutorial demonstrates how to use cluster network policies to control which Pods receive incoming network traffic, and which Pods can send outgoing traffic. For more information, see Creating a cluster network policy.
Network policies allow you to limit connections between Pods. Therefore, using network policies provide better security by reducing the compromise radius.
Note that the network policies determine whether a connection is allowed, and they do not offer higher level features like authorization or secure transport (like SSL/TLS).
Objectives
In this tutorial, you will learn:- How to create clusters with Network Policy enforcement
- How to restrict incoming traffic to Pods using labels
- How to restrict outgoing traffic from Pods using labels
Costs
In this document, you use the following billable components of Google Cloud:
To generate a cost estimate based on your projected usage,
use the pricing calculator.
When you finish the tasks that are described in this document, you can avoid continued billing by deleting the resources that you created. For more information, see Clean up.
Before you begin
Take the following steps to enable the Kubernetes Engine API:- Visit the Kubernetes Engine page in the Google Cloud console.
- Create or select a project.
- Wait for the API and related services to be enabled. This can take several minutes.
-
Make sure that billing is enabled for your Google Cloud project.
Install the following command-line tools used in this tutorial:
-
gcloud
is used to create and delete Kubernetes Engine clusters.gcloud
is included in thegcloud
CLI. -
kubectl
is used to manage Kubernetes, the cluster orchestration system used by Kubernetes Engine. You can installkubectl
usinggcloud
:gcloud components install kubectl
Clone the sample code from GitHub:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples cd kubernetes-engine-samples/networking/network-policies
Set defaults for the gcloud
command-line tool
To save time typing your project ID
and Compute Engine zone options in the gcloud
command-line tool, you can set the defaults:
gcloud config set project project-id gcloud config set compute/zone compute-zone
Creating a GKE cluster with network policy enforcement
To create a container cluster with network policy enforcement, run the following command:
gcloud container clusters create test --enable-network-policy
Restricting incoming traffic to Pods
Kubernetes NetworkPolicy
resources let you configure network access policies
for the Pods. NetworkPolicy
objects contain the following information:
Pods the network policies apply to, usually designated by a label selector
Type of traffic the network policy affects: Ingress for incoming traffic, Egress for outgoing traffic, or both
For Ingress policies, which Pods can connect to the specified Pods
For Egress policies, the Pods to which the specified Pods can connect
First, run a web server application with label app=hello
and expose it
internally in the cluster:
kubectl run hello-web --labels app=hello \ --image=us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0 --port 8080 --expose
Next, configure a NetworkPolicy
to allow traffic to the hello-web
Pods from only the app=foo
Pods. Other incoming traffic from Pods that do
not have this label, external traffic, and traffic from Pods in other namespaces
are blocked.
The following manifest selects Pods with label app=hello
and specifies an
Ingress policy to allow traffic only from Pods with the label app=foo
:
To apply this policy to the cluster, run the following command:
kubectl apply -f hello-allow-from-foo.yaml
Validate the Ingress policy
First, run a temporary Pod with the label app=foo
and get a shell in the
Pod:
kubectl run -l app=foo --image=alpine --restart=Never --rm -i -t test-1
Make a request to the hello-web:8080
endpoint to verify that the incoming
traffic is allowed:
/ # wget -qO- --timeout=2 http://hello-web:8080
Hello, world! Version: 1.0.0 Hostname: hello-web-2258067535-vbx6z / # exit
Traffic from Pod app=foo
to the app=hello
Pods is enabled.
Next, run a temporary Pod with a different label (app=other
) and get a shell
inside the Pod:
kubectl run -l app=other --image=alpine --restart=Never --rm -i -t test-1
Make the same request to observe that the traffic is not allowed and therefore the request times out, then exit from the Pod shell:
/ # wget -qO- --timeout=2 http://hello-web:8080
wget: download timed out / # exit
Restricting outgoing traffic from the Pods
You can restrict outgoing traffic as you would incoming traffic.
However, to be able to query internal hostnames such as hello-web
or external
hostnames such as www.example.com
, you must allow DNS (domain name system)
resolution in your egress network policies. DNS traffic occurs on port 53 using
TCP and UDP protocols.
To enable egress network policies, deploy a NetworkPolicy
controlling
outbound traffic from Pods with the label app=foo
while allowing traffic only
to Pods with the label app=hello
, as well as the DNS traffic.
The following manifest specifies a network policy controlling the egress traffic
from Pods with label app=foo
with two allowed destinations:
- Pods in the same namespace with the label
app=hello
. - Cluster Pods or external endpoints on port 53 (UDP and TCP).
To apply this policy to the cluster, run the following command:
kubectl apply -f foo-allow-to-hello.yaml
Validate the egress policy
First, deploy a new web application called hello-web-2
and expose it
internally in the cluster:
kubectl run hello-web-2 --labels app=hello-2 \ --image=us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0 --port 8080 --expose
Next, run a temporary Pod with the label app=foo
and open a shell inside
the container:
kubectl run -l app=foo --image=alpine --rm -i -t --restart=Never test-3
Validate that the Pod can establish connections to hello-web:8080
:
/ # wget -qO- --timeout=2 http://hello-web:8080
Hello, world!
Version: 1.0.0
Hostname: hello-web-2258067535-vbx6z
Validate that the Pod cannot establish connections to hello-web-2:8080
:
/ # wget -qO- --timeout=2 http://hello-web-2:8080
wget: download timed out
Validate that the Pod cannot establish connections to external websites such
as www.example.com
, and exit from the Pod shell.
/ # wget -qO- --timeout=2 http://www.example.com
wget: download timed out
/ # exit
Clean up
To avoid incurring charges to your Google Cloud account for the resources used in this tutorial, either delete the project that contains the resources, or keep the project and delete the individual resources.
Delete the container cluster: This step will delete the resources that make up the container cluster, such as the compute instances, disks and network resources.
gcloud container clusters delete test