Skip to main content

Kubernetes Network Policies: Ingress and Egress Policy Examples

1309 words·
Kubernetes Kubectl
Kubernetes-Components - This article is part of a series.
Part 12: This Article

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

Kubernetes-Components - This article is part of a series.
Part 12: This Article