Day 17 Network Policy in Kubernetes
Arjun Adhikari
DevOps | kubernetes | Linux | AWS | Terraform | Ansible |SQL | GIT | Docker | Shell Script | Networking
What is Network Policy?
By default, a pod can communicate with any other pods whether it’s present in any namespaces. But if we want to secure our pod by providing access to only known pods or authorized pods with the help of Network Policy we can protect our pod by accessing only authorized pods. For example, frontend pod can interact with both the backend and database pods, the backend pod can communicate with the frontend and database pods, and the database pod can exchange data with both the frontend and backend pods. While this open communication is convenient for many use cases, there are scenarios where you might want to restrict communication between certain pods for security or organizational reasons.
Network Policy allows us to define the rules for communicating between the pods. With the help of Networking Policy, Kubernetes provides fine-grained controls over what traffic is permitted or denied which leads to enhancing the security and isolation of your applications..
Why do we use a network policy in Kubernetes?
- Traffic Control: How Pods communicate with each other and with Services, allowing users to restrict or allow traffic based on specific criteria such as labels, namespaces, and ports.
- Security: By default, Kubernetes allows all traffic between Pods and between Pods and Services within the cluster network. Network Policies enable users to deny all traffic and then explicitly allow only the necessary communication. This enhances the security of the applications running in the cluster.
- Isolation: Network Policies help isolate different applications or services within the cluster.
- Compliance: (Policy as Compliance) Network Policies help achieve compliance by allowing organizations to define and enforce stricter network access rules.
Key Features:
Policy Rules: Network Policies consist of a set of rules which define how the traffic is allowed or denied. We can specify these rules by pod labels, namespaces, or particular IPs.
Pod Selectors: If we want to apply the Network Policy to the particular pod then we can use Pod Selector which will select the particular pod and apply the Network Policy on that pod.
Ingress and Egress: Network Policies allow us to define the Ingress and Egress rules. Ingress means incoming traffic on the pod from the outside whereas Egress means outgoing traffic to the internet(anywhere) from the pod itself.
Namespaces: If we want to apply our Network Policy to the group of pods which is present in the particular namespace then we can namespaceSelector which will help us to invoke the Network Policy on all pods within the particular namespace.
Priority: Network Policy also provides the priority feature which defines the priority of the rules which helps to get fine-grained control over the traffic rules of your application.
First, we need to be sure about which CNI (Container Network Interface) is installed in our cluster. Some of CNI plugins ( flannel, kindnet) don't support network policy . So we need to use Calico,cilium, weave-net etc
Example : Frontend, Backend and Database Deployments
Let’s create three pods: Frontend, Backend, and Database, along with three corresponding services. We will then demonstrate how these pods can initially communicate with each other and how this changes after applying Network Policies.
apiVersion: v1
kind: Pod
metadata:
name: frontend
labels:
role: frontend
spec:
containers:
- name: nginx
image: nginx
ports:
- name: http
containerPort: 80
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: frontend
labels:
role: frontend
spec:
selector:
role: frontend
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: v1
kind: Pod
metadata:
name: backend
labels:
role: backend
spec:
containers:
- name: nginx
image: nginx
ports:
- name: http
containerPort: 80
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: backend
labels:
role: backend
spec:
selector:
role: backend
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: v1
kind: Pod
metadata:
name: mysql
labels:
name: mysql
spec:
containers:
- name: mysql
image: mysql:latest
env:
- name: "MYSQL_USER"
value: "mysql"
- name: "MYSQL_PASSWORD"
value: "mysql"
- name: "MYSQL_DATABASE"
value: "testdb"
- name: "MYSQL_ROOT_PASSWORD"
value: "verysecure"
ports:
- name: http
containerPort: 3306
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: db
labels:
name: mysql
spec:
selector:
name: mysql
ports:
- protocol: TCP
port: 3306
targetPort: 3306
Let's verify pod communication, (by default all pods can communicate with each other)
checking connection for backend from frontend pod
$ kubectl exec -it frontend -- bash
checking connection between frontend and bd pod
install telnet package to frontend container
# apt update && apt install telnet
checking connection between fronend and back end
We can see that, all pods can communicate with each other.
Now, let's apply a Network Policy to restrict communication:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-test
spec:
podSelector:
matchLabels:
name: mysql
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
role: backend
ports:
- port: 3306
After applying the above manifest let's again check the connection of the pod
From front end we are unable to connect db pod
领英推è
From the backend pod, we are able to connect db pod
Explanation
- podSelector: This selects the pods to which the network policy will apply. In this case, it applies to pods with the label name: mysql, targeting the MySQL pod(s).
- policyTypes: Specifies the type of traffic the policy controls, here it is Ingress, controlling incoming traffic to the MySQL pod.
- ingress: This section defines the rules for incoming traffic:
from: Specifies that only pods with the label role: backend are allowed to send traffic to the MySQL pod.
ports: Restricts traffic to port 3306.
Additional Kubernetes Network Policy Examples
Ex 1: Allow All Ingress Traffic
This Network Policy allows all incoming traffic to the selected pods. It’s useful when you want to ensure that your pods are accessible from any source.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-ingress
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- {}
Explanation
- podSelector: An empty selector means this policy applies to all pods in the namespace.
- policyTypes: Specifies that this policy controls ingress traffic.
- ingress: An empty ingress rule allows all incoming traffic.
Example 2: Deny All Egress Traffic
This Network Policy denies all outgoing traffic from the selected pods. It’s useful for highly secure environments where pods should not communicate externally.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-egress
namespace: default
spec:
podSelector:
matchLabels:
app: secure-app
policyTypes:
- Egress
egress: []
Explanation
- podSelector: Selects pods labeled app: secure-app.
- policyTypes: Specifies that this policy controls egress traffic.
- egress: An empty egress rule denies all outgoing traffic.
Example 3: Allow Ingress from a Specific Namespace
This Network Policy allows incoming traffic to the selected pods only from pods in a specific namespace.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-namespace-ingress
namespace: default
spec:
podSelector:
matchLabels:
app: my-app
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
project: my-namespace
Explanation
- podSelector: Selects pods labeled app: my-app.
- policyTypes: Specifies that this policy controls ingress traffic.
- ingress: Allows incoming traffic from pods in the namespace labeled project: my-namespace.
Example 4: Allow Egress to a Specific IP Range
This Network Policy allows outgoing traffic from the selected pods to a specific IP range.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-egress-to-ip
namespace: default
spec:
podSelector:
matchLabels:
app: my-app
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 10.10.1.0/8
Explanation
- podSelector: Selects pods labeled app: my-app.
- policyTypes: Specifies that this policy controls egress traffic.
- egress: Allows outgoing traffic to the IP range 10.10.1.0/8.
Example 5: Allow Ingress Traffic on Specific Ports
This Network Policy allows incoming traffic to the selected pods only on specific ports.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-specific-ports
namespace: default
spec:
podSelector:
matchLabels:
app: web-app
policyTypes:
- Ingress
ingress:
- ports:
- protocol: TCP
port: 80
- protocol: TCP
port: 443
Explanation
- podSelector: Selects pods labeled app: web-app.
- policyTypes: Specifies that this policy controls ingress traffic.
- ingress: Allows incoming traffic on ports 80 (HTTP) and 443 (HTTPS).
Conclusion
Network policies are essential for securing Kubernetes clusters by controlling the traffic flow between pods and other network endpoints. By defining rules based on pod labels and namespaces, we can ensure that only authorized communication occurs within your cluster.
DevOps | Linux
6 个月Great ????