Network Policies #
Overview #
-
Each network policy applies only to the pods within the namespace where the policy is created
-
Ingress
Refers to incoming traffic to a pod -
Egress
Refers to outgoing traffic from a pod
Example Pods #
Deploy some pods to test the network policies:
# Run example pods
kubectl run pod1 --image nginx:latest -l app=pod1
kubectl run pod2 --image nginx:latest -l app=pod2
# List pods
kubectl get pods -o wide
# Shell output:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod1 1/1 Running 0 40s 10.42.0.20 ubuntu4 <none> <none>
pod2 1/1 Running 0 35s 10.42.0.21 ubuntu4 <none> <none>
Verify the communication between the pods:
# Verify communication from pod1 to pod2
kubectl exec -it pod1 -- curl 10.42.0.21 --max-time 1
# Shell output:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
Ex.1 Block All Pod Traffic #
Network Policy #
vi np-ex-pods.yaml
Specific pod:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: network-policy-ex-pods
namespace: default
spec:
podSelector:
matchLabels:
app: pod2 # Define pod label
policyTypes:
- Ingress
- Egress
All pods:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: network-policy-ex-pods
namespace: default
spec:
podSelector: {} # Define all pods in the "default" namespace
policyTypes:
- Ingress
- Egress
kubectl apply -f np-ex-pods.yaml
Network Policy Explanation:
-
The policy applies to the “default” namespace
-
The policy selects the “pod2” Pod by matching its label “app: pod2” using a podSelector
-
Since the ingress and egress policies are set but no further rules are added, the policy will block all network traffic to and from the Pod
List Network Policy #
# List network policy: Describe all NetworkPolicies in "default" namespace
kubectl describe networkpolicy
# List network policy: Describe specific "network-policy-ex-pods" np in "default" namespace
kubectl describe networkpolicy network-policy-ex-pods -n default
Delete Network Policy #
# Delete network policy
kubectl delete networkpolicy networkpolicy-name
Verify Network Policy #
# Verify communication from pod1 to pod2
kubectl exec -it pod1 -- curl 10.42.0.21 --max-time 1
# Shell output:
curl: (7) Failed to connect to 10.42.0.21 port 80 after 0 ms: Couldn't connect to server
command terminated with exit code 7
Ex.2 Allow All Traffic from / to Specific Pod #
Network Policy #
vi np-ex-pods.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: network-policy
namespace: default
spec:
podSelector:
matchLabels:
app: pod2
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: pod1
egress:
- to:
- podSelector:
matchLabels:
app: pod1
kubectl apply -f np-ex-pods.yaml
Network Policy Explanation:
-
The policy applies to the “default” namespace
-
The network policy selects the “pod2” Pod by matching its labels using a podSelector.
-
It accepts Ingress and Egress traffic when the other end of the connection is a pod with the label “app=pod1”
Verify Network Policy #
Test network policy from pod1:
# Verify communication from pod1 to pod2
kubectl exec -it pod1 -- curl 10.42.0.21 --max-time 1
# Shell output:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
Test network policy from busybox pod:
# Run "busybox" pod
kubectl run curl-pod --rm -it --image=busybox --restart=Never -- /bin/sh
# Verify communication to pod2 from busybox pod
wget -qO- 10.42.0.21
# Shell output:
wget: can't connect to remote host (10.42.0.21): Connection refused
Ex.3 Allow only Traffic to Specific Pod and Port #
Example Pods #
Deploy some pods to test the network policies:
# Run example pods
kubectl run pod1 --image nginx:latest -l app=pod1
kubectl run pod2 --image nginx:latest -l app=pod2
kubectl run pod3 --image nginx:latest -l app=pod3
# List pods
kubectl get pods -o wide
# Shell output:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod1 1/1 Running 0 11s 10.42.0.110 ubuntu4 <none> <none>
pod2 1/1 Running 0 7s 10.42.0.111 ubuntu4 <none> <none>
pod3 1/1 Running 0 4s 10.42.0.112 ubuntu4 <none> <none>
Network Policy #
vi np-ex-pods.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: network-policy
namespace: default
spec:
podSelector:
matchLabels:
app: pod2
policyTypes:
- Ingress
- Egress
ingress:
# Allow all traffic to pod2
- {}
egress:
# Allow traffic to pod1 on port "80"
- to:
- podSelector:
matchLabels:
app: pod1
ports:
- protocol: TCP
port: 80
# Allow DNS resolution via CoreDNS
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system # CoreDNS namespace
- podSelector:
matchLabels:
k8s-app: kube-dns # CoreDNS pod label
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
kubectl apply -f np-ex-pods.yaml
Network Policy Explanation:
-
The policy applies to the “default” namespace
-
The policy selects the “pod2” Pod by matching its label “app: pod2” using a podSelector
-
It allows all incoming network traffic to pods labeled “app: pod2”
-
The selected pods are only allowed to send outgoing traffic to pods with the label “app: pod1” on port “80” and the CoreDNS pods
Verify Network Policy #
# Verify communication from pod1 to pod2
kubectl exec -it pod1 -- curl 10.42.0.111 --max-time 1
# Shell output:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
# Verify communication from pod2 to pod1
kubectl exec -it pod2 -- curl 10.42.0.110 --max-time 1
# Shell output:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
# Verify communication from pod2 to pod3
kubectl exec -it pod2 -- curl 10.42.0.112 --max-time 1
# Shell output:
curl: (7) Failed to connect to 10.42.0.112 port 80 after 0 ms: Couldn't connect to server
command terminated with exit code 7
Ex.4 Allow only Traffic to Specific Namespace #
Create Namespaces #
vi example-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: example-namespace1
labels:
environment: example-namespace1
---
apiVersion: v1
kind: Namespace
metadata:
name: example-namespace2
labels:
environment: example-namespace2
# Create the namespace
kubectl create -f example-namespace.yaml
Example Pods #
Deploy some pods to test the network policies:
# Run example pods
kubectl run pod1 --image nginx:latest -l app=pod1
kubectl run pod2 --image nginx:latest -l app=pod2
kubectl run pod3 --image nginx:latest -l app=pod3 -n example-namespace1
kubectl run pod4 --image nginx:latest -l app=pod4 -n example-namespace2
# List pods: In "default" namespace
kubectl get pods -o wide
# Shell output:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod1 1/1 Running 0 17s 10.42.0.132 ubuntu4 <none> <none>
pod2 1/1 Running 0 12s 10.42.0.133 ubuntu4 <none> <none>
# List pods: In "example-namespace" namespace
kubectl get pods -o wide -n example-namespace1
# Shell output:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod3 1/1 Running 0 21s 10.42.0.134 ubuntu4 <none> <none>
# List pods: In "example-namespace" namespace
kubectl get pods -o wide -n example-namespace2
# Shell output:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod4 1/1 Running 0 29s 10.42.0.135 ubuntu4 <none> <none>
Network Policy #
vi np-ex-pods.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: network-policy
namespace: default
spec:
podSelector:
matchLabels:
app: pod2
policyTypes:
- Egress
egress:
# Allow traffic to pod1 in "default" namespace
- to:
- podSelector:
matchLabels:
app: pod1
# Allow traffic to all pods in the namespace with the label "environment=example-namespace1"
- to:
- namespaceSelector:
matchLabels:
environment: example-namespace1
kubectl apply -f np-ex-pods.yaml
Network Policy Explanation:
-
The policy applies to the “default” namespace
-
The policy selects the “pod2” Pod by matching its label “app: pod2” using a podSelector
-
The selected pods are only allowed to send outgoing traffic to pods with the label “app: pod1” and pods in the “example-namespace1” namespace
Verify Network Policy #
Verify pod2 can access pod1:
# Verify communication from pod2 to pod1
kubectl exec -it pod2 -- curl 10.42.0.132 --max-time 1
# Shell output:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
Verify pod2 can access pods in the “example-namespace1” namespace:
# Verify communication from pod2 to pod3 in "example-namespace1" namespace
kubectl exec -it pod2 -- curl 10.42.0.134 --max-time 1
# Shell output:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
Verify pod2 can’t access pods in the “example-namespace2” namespace:
# Verify communication from pod2 to pod4 in "example-namespace2" namespace
kubectl exec -it pod2 -- curl 10.42.0.135 --max-time 1
# Shell output:
curl: (7) Failed to connect to 10.42.0.135 port 80 after 0 ms: Couldn't connect to server
command terminated with exit code 7