This page demonstrates how to use cluster network policies to control whether a Pod can receive incoming (or Ingress) network traffic, and whether it can send outgoing (or Egress) traffic.
Network policies allow you to limit connections between Pod objects, so you can reduce exposure to attack.
Network policies act as a firewall on layer 3 or layer 4 of the OSI model. They do not offer additional features such as authorization or encryption.
Restricting incoming traffic to Pod objects
A NetworkPolicy
object
lets you configure network access policies for a Pod. NetworkPolicy
objects
contain the following information:
Pod objects the policy applies to. You define Pod objects and workloads with labels and selectors.
Type of traffic the network policy affects: Ingress for incoming traffic, Egress for outgoing traffic, or both.
For Ingress policies, which Pod objects can connect to the specified Pod objects.
For Egress policies, the Pod objects to which the specified Pod objects can connect.
Example incoming traffic restriction
This section demonstrates the creation of an incoming traffic restriction on a sample application. Modify this example to suit your own application environment.
Run a web server application with the 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
Configure a
NetworkPolicy
to allow traffic to thehello-web
Pod from only theapp=foo
Pod objects. GKE on AWS blocks incoming traffic from Pod objects that do not have this label, as well as external traffic, and traffic from Pod objects in a different Namespace.The following manifest selects Pod objects with the label
app=hello
and specifies an Ingress policy to allow traffic only from Pod objects with the labelapp=foo
:Apply this policy to the cluster:
kubectl apply -f hello-allow-from-foo.yaml
Verify the Ingress policy
Run a temporary Pod with the label
app=foo
. To verify that incoming traffic is allowed, make a request to thehello-web:8080
endpoint:kubectl run -l app=foo --image=alpine --restart=Never --rm -i -t foo-app \ -- wget -qO- --timeout=2 http://hello-web:8080
If traffic from Pod
app=foo
to theapp=hello
Pod objects is enabled, the output looks like the following:Hello, world! Version: 1.0.0 Hostname: hello-web-2258067535-vbx6z
Run a temporary Pod with a different label (
app=other
) and make the same request to observe that the traffic is not allowed:kubectl run -l app=other --image=alpine --restart=Never --rm -i -t other-app \ -- wget -qO- --timeout=2 http://hello-web:8080
The output confirms the connection doesn't receive a response:
wget: download timed out
Restrict outgoing traffic from Pod objects
You can restrict outgoing traffic just as you would incoming traffic.
However, to query internal hostnames such as hello-web
or external hostnames
such as www.example.com
, you must create an Egress policy that allows
DNS traffic on port 53 using TCP and UDP protocols.
To enable Egress network policies, deploy a NetworkPolicy
controlling outbound
traffic from Pod objects with the label app=foo
while allowing traffic only to
Pod objects with the label app=hello
, as well as the DNS traffic.
The following manifest specifies a NetworkPolicy
controlling Egress traffic
from Pod objects with label app=foo
with two allowed destinations:
- Pod objects in the same Namespace with the label
app=hello
- Internal or external endpoints on port 53 (UDP and TCP)
Apply this policy to the cluster:
kubectl apply -f foo-allow-to-hello.yaml
Validate the Egress policy
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
Run a temporary Pod with the label
app=foo
and validate that the Pod can establish connections tohello-web:8080
:kubectl run -l app=foo --image=alpine --rm -i -t --restart=Never foo-app \ -- wget -qO- --timeout=2 http://hello-web:8080
The Pod responds to the request:
Hello, world! Version: 1.0.0 Hostname: hello-web-2258067535-vbx6z
Validate that the Pod can't establish connections to
hello-web-2:8080
:kubectl run -l app=foo --image=alpine --rm -i -t --restart=Never foo-app \ -- wget -qO- --timeout=2 http://hello-web-2:8080
The output confirms the connection doesn't receive a response:
wget: download timed out
Validate that the Pod can't establish connections to external websites such as
www.example.com
.kubectl run -l app=foo --image=alpine --rm -i -t --restart=Never foo-app \ -- wget -qO- --timeout=2 http://www.example.com
The output confirms the connection doesn't receive a response:
wget: download timed out
Clean up
To remove the resources you created in this tutorial, run these commands:
kubectl delete pods --labels app=hello-2
kubectl delete pods --labels app=hello
kubectl delete -f foo-allow-to-hello.yaml
kubectl delete -f hello-allow-from-foo.yaml
What's next
- Kubernetes Network Policies documentation
- Use network policy logging to record when connections to Pod objects are allowed or denied by your cluster's network policies.