deny-egress-traffic-from-an-application
# DENY egress traffic from an application
Use Cases:
- You want to prevent an application from establishing any connections to outside of the Pod.
- Useful for restricting outbound traffic of single-instance databases and datastores.
NOTE: If you are using Google Kubernetes Engine (GKE), make sure you have at least
1.8.4-gke.0
master and nodes version to be able to use egress policies.
# Example
Run a web application with app=web
label:
kubectl run web --image=nginx --labels="app=web" --expose --port=80
Save the following to foo-deny-egress.yaml
and apply to the cluster:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: foo-deny-egress
spec:
podSelector:
matchLabels:
app: foo
policyTypes:
- Egress
egress: []
2
3
4
5
6
7
8
9
10
11
Remarks about this manifest file:
podSelector
matches toapp=foo
podspolicyTypes: ["egress"]
indicates that this policy enforces policies for the egress (outbound) traffic.egress: []
empty rule set does not whitelist any traffic, therefore all egress (outbound) traffic is blocked.- You can drop this field altogether and have the same effect.
kubectl apply -f foo-deny-egress.yaml
networkpolicy "foo-deny-egress" created
2
# Try it out
Run a pod with label app=foo
, and try to connect to the web
service:
$ kubectl run --rm --restart=Never --image=alpine -i -t --labels="app=foo" test -- ash
/ # wget -qO- --timeout 1 http://web:80/
wget: bad address 'web:80'
/ # wget -qO- --timeout 1 http://www.example.com/
wget: bad address 'www.example.com'
2
3
4
5
6
7
What's failing is not establishing connection to the web
hostname: The pod is
failing to resolve the the address, because the network policy is not
allowing it to establish connections to the kube-dns
Pods.
# Allowing DNS traffic
So we slightly modify the YAML file to allow all outbound traffic on DNS ports
(53/udp
and 53/tcp
), but only to pods which match the label k8s-app: kube-dns
and are running in the kube-system namespace:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: foo-deny-egress
spec:
podSelector:
matchLabels:
app: foo
policyTypes:
- Egress
egress:
# allow DNS resolution
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- port: 53
protocol: UDP
- port: 53
protocol: TCP
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Now when we try again, we actually see the IP addresses are resolved, but the traffic is blocked:
/ # wget --timeout 1 -O- http://web
Connecting to web (10.59.245.232:80)
wget: download timed out
/ # wget --timeout 1 -O- http://www.example.com
Connecting to www.example.com (93.184.216.34:80)
wget: download timed out
/ # ping google.com
PING google.com (74.125.129.101): 56 data bytes
(...)
(ping does not work, hit ctrl+C to terminate)
/ # exit
2
3
4
5
6
7
8
9
10
11
12
13
14
# Cleanup
kubectl delete pod,service web
kubectl delete networkpolicy foo-deny-egress
2