Configuring Network Policies for Applications

This tutorial demonstrates how to use cluster Network Policies to control which Pods receive incoming network traffic, and which Pods can send outgoing traffic.

Network Policies allow you to limit connections between Pods. Therefore, using Network Policies provide better security by reducing the compromise radius.

This page explains how to configure network policies in GKE.

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

Before you begin

Take the following steps to enable the Kubernetes Engine API:
  1. Visit the Kubernetes Engine page in the Google Cloud Platform Console.
  2. Create or select a project.
  3. Wait for the API and related services to be enabled. This can take several minutes.
  4. Make sure that billing is enabled for your project.

    Learn how to enable billing

Install the following command-line tools used in this tutorial:

  • gcloud is used to create and delete Kubernetes Engine clusters. gcloud is included in the Google Cloud SDK.
  • kubectl is used to manage Kubernetes, the cluster orchestration system used by Kubernetes Engine. You can install kubectl using gcloud:
    gcloud components install kubectl

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 us-central1-b

Step 1: Create a GKE

To create a container cluster with Network Policy enforcement, run the following command:

gcloud container clusters create test --enable-network-policy

Step 2: Restrict incoming traffic to Pods

Kubernetes NetworkPolicy resources let you configure network access policies for the Pods. NetworkPolicy objects contains with the following information:

  • Pods to which the network policies apply, usually designated by a label selector

  • Type of Internet 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 simple web server application with label app=hello and expose it internally in the cluster:

kubectl run hello-web --labels app=hello \
  --image=gcr.io/google-samples/hello-app:1.0 --port 8080 --expose

Next, you need to 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.

Save the following configuration to hello-allow-from-foo.yaml:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: hello-allow-from-foo
spec:
  policyTypes:
  - Ingress
  podSelector:
    matchLabels:
      app: hello
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: foo

This policy 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

Step 3: Restrict outgoing traffic from the Pods

You can restrict outgoing (egress) 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 exercise 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.

Save the following configuration to foo-allow-to-hello.yaml and apply it to the cluster:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: foo-allow-to-hello
spec:
  policyTypes:
  - Egress
  podSelector:
    matchLabels:
      app: foo
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: hello
  - ports:
    - port: 53
      protocol: TCP
    - port: 53
      protocol: UDP
kubectl apply -f foo-allow-to-hello.yaml

This manifest specifies a network policy controlling the egress traffic from Pods with label app=foo with two allowed destinations:

  1. Pods in the same namespace with the label app=hello.
  2. Cluster Pods or external endpoints on port 53 (UDP and TCP)

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=gcr.io/google-samples/hello-app:1.0 --port 8080 --expose

Next, run a temporary Pod with app=foo label and get a shell prompt 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

Cleaning up

To avoid incurring charges to your Google Cloud Platform account for the resources used in this tutorial:

  1. 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

What's next

Was this page helpful? Let us know how we did:

Send feedback about...

Kubernetes Engine Tutorials