Network Policies SetUp with VPC CNI on AWS EKS
Imagine we have three pods in our Kubernetes cluster: Pod A, Pod B, and Pod C. We want to make sure that Pod B can only be accessed through Pod A, and not through Pod C.
How can we do this? Kubernetes has a fantastic feature called Network Policy! This tool allows us to control and manage traffic between pods, deciding who can talk to whom.
Here’s a simple example to achieve our goal:
- Create a Network Policy in AWS EKS: Define the rules for how pods can communicate.
- Apply the Policy: Implement these rules in your cluster.
By using Network Policies, you can ensure that Pod B is only accessible via Pod A. It’s like setting up a secret communication channel!
Understanding Network Policies
Network Policies in Kubernetes help manage how pods communicate with each other and with other network endpoints. They use labels to choose which pods the rules apply to and set rules for incoming and outgoing traffic.
Key Concepts:
- Pod Selector: Chooses the group of pods the policy will apply to.
- Ingress Rules: Define allowed incoming traffic.
- Egress Rules: Define allowed outgoing traffic.
- Policy Types: It can be for incoming traffic (Ingress), outgoing traffic (Egress), or both (Ingress and Egress).
Enable Network Policies in AWS EKS
In AWS EKS, the “VPC CNI” plugin doesn’t support Network Policies by default, so you need to enable it manually.
Here are the steps to do so:
- Go to the AWS EKS cluster
- Click on “Add-On” tab
- Install the “Amazon VPC CNI” in AWS EKS plugin if it’s not already installed and update the “Advanced configuration” by adding the below line,
{"enableNetworkPolicy": "true"}
Hands-on
In this example, we create three pods: A, B, and C. Pod A should only be accessible through Pod B, not Pod C.
Step 1: Create all 3 pods (POD A, B & C) in AWS EKS
- pod-a.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-a
namespace: dhruv
labels:
app: pod-a
spec:
containers:
- name: pod-a
image: httpd
ports:
- containerPort: 80
- pod-b.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-b
namespace: dhruv
labels:
app: pod-b
spec:
containers:
- name: pod-b
image: nginx
ports:
- containerPort: 80
- pod-c.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-c
namespace: dhruv
labels:
app: pod-c
spec:
containers:
- name: pod-c
image: httpd
ports:
- containerPort: 80
k get all -n <namespacename>
Step 2: Create network policy for pod A
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: pod-a-network-policy
namespace: dhruv
spec:
podSelector:
matchLabels:
app: pod-a
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: pod-b
Check whether our network is created or not,
k get networkpolicy -n <name-space>
Step 3: Verification
- Login inside Pod and install curl
kubectl exec -it pod-b -n dhruv -- /bin/bash
apt update
apt install curl
kubectl exec -it pod-c -n dhruv -- /bin/bash
apt update
apt install curl
Get the IP of all pod
kubectl get pod -n <namespace> -o wide
- Now access Pod A from POD B
- You will receive HTML data like the below mention,
kubectl exec -it pod-b -n dhruv -- curl <ip-of-pod>
- Now access POD A from POD C
- You can’t get any data from POD A,
kubectl exec -it pod-c -n dhruv -- curl <ip-of-pod>
In a Network Policy, you can control which traffic is allowed to access your pod using four methods:
- Allow Specific Pods
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-from-one-pod
namespace: dhruv
spec:
#pod in which networkpolicy apply
podSelector:
matchLabels:
app: backend
#policy types
policyTypes:
- Ingress
- Egress
#From where traffic comes
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
egress:
- to:
- podSelector:
matchLabels:
app: frontend
2. Allow Specific IPs
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-egress-to-ip
namespace: dhruv
spec:
#pod in which networkpolicy apply
podSelector:
matchLabels:
app: my-app
#policy types
policyTypes:
- Egress
#Where our pod ("my-app") can send outside request
egress:
- to:
- ipBlock:
cidr: 192.168.1.0/24
3. Allow Specific Ports in POD
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-specific-ports
namespace: dhruv
spec:
#pod in which networkpolicy apply
podSelector:
matchLabels:
app: web-app
#policy types
policyTypes:
- Ingress
#In which port give access to traffic that comes from web-app pod
ingress:
- ports:
- protocol: TCP
port: 80
- protocol: TCP
port: 443
4. Allow all pods from Specific namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-namespace-ingress
namespace: dhruv
spec:
#pod in which networkpolicy apply
podSelector:
matchLabels:
app: my-app
#policy types
policyTypes:
- Ingress
#From where traffic comes
ingress:
- from:
- namespaceSelector:
matchLabels:
project: my-namespace
Additional Network Policy
- Allow All Ingress to POD
- Allow any pod/ip to access our pod.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-ingress
namespace: dhruv
spec:
#pod in which networkpolicy apply
podSelector: {}
#policy types
policyTypes:
- Ingress
#From where traffic comes
ingress:
- {}
2. Allow Egress to IP
- This defines in which IP our POD outgoing traffic will go.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-egress-to-ip
namespace: dhruv
spec:
#pod in which networkpolicy apply
podSelector:
matchLabels:
app: my-app
#policy types
policyTypes:
- Egress
#Where our pod ("my-app") can send outside request
egress:
- to:
- ipBlock:
cidr: 192.168.1.0/24
Connect With Me
Catch me on LinkedIn for more insights and discussions! Let’s navigate the intricate world of AWS, cloud strategies, Kubernetes, and beyond. Connect with me to exchange ideas, seek advice, or say hello.
Happy deploying! 🚀
Happy Kubernetings! ⎈