# 9: Kubernetes: Using LimitRange and Network Policies with Examples

Kubernetes offers robust features to manage resources and secure communication between pods and namespaces. In this blog, we’ll explore two such features: **LimitRange** and **Network Policies**, with detailed explanations and practical examples to help you implement them in your cluster.

---

## **1\. Managing Resource Quotas with LimitRange**

### **What is LimitRange?**

A **LimitRange** is a Kubernetes object used to enforce constraints on resource requests and limits for pods or containers within a namespace. It ensures resources are allocated fairly and avoids scenarios where a single application consumes excessive resources, causing instability in the cluster.

### **Why Use LimitRange?**

* **Prevent Over-Allocation**: Avoid resource contention by setting maximum limits.
    
* **Stability**: Ensure a minimum allocation of resources to avoid application crashes.
    

### **How LimitRange Works**

When a **LimitRange** is applied to a namespace:

1. Pods or containers must request resources within the defined `min` and `max` boundaries.
    
2. If resource requests are not specified in a pod's definition, Kubernetes applies the default values from the **LimitRange**.
    

---

### **Example: Applying LimitRange**

Here’s an example YAML file for a LimitRange:

```plaintext
apiVersion: v1
kind: LimitRange
metadata:
  name: example-limitrange
  namespace: test
spec:
  limits:
  - default:
      cpu: "500m"
      memory: "512Mi"
    defaultRequest:
      cpu: "200m"
      memory: "256Mi"
    max:
      cpu: "1"
      memory: "1Gi"
    min:
      cpu: "100m"
      memory: "128Mi"
    type: Container
```

This configuration sets the following constraints:

* **Minimum**: Pods must request at least `100m` CPU and `128Mi` memory.
    
* **Maximum**: Pods cannot request more than `1` CPU and `1Gi` memory.
    
* **Defaults**: If no values are specified, Kubernetes assigns `500m` CPU and `512Mi` memory.
    

#### **Apply the LimitRange**

Save the YAML file as `limit-range.yaml` and apply it to the `test` namespace:

```plaintext
kubectl apply -f limit-range.yaml
```

---

### **Scenario: What Happens Without Resource Requests?**

Without a **LimitRange**, attempting to create a pod without specifying resource requests or limits may cause the pod to fail or consume unbounded resources. With a **LimitRange**, the pod inherits the default values, ensuring it runs within the constraints.

#### **Check Pod Resource Allocation**

You can verify the pod’s resource allocation with the following command:

```plaintext
kubectl describe pod <pod-name>
```

Look for the `QoS Class`, which should show **Burstable**, indicating the pod uses the default values.

---

## **2\. Securing Communication with Network Policies**

### **What is a Network Policy?**

A **Network Policy** is a Kubernetes resource that controls the flow of traffic between pods, namespaces, and external endpoints. By default, all pods in Kubernetes can communicate with each other. Network Policies allow you to enforce restrictions based on your application’s security requirements.

For more details, refer to the [Kubernetes Network Policies documentation](https://kubernetes.io/docs/concepts/services-networking/network-policies/).

---

### **Example: Applying Network Policies**

#### **Step 1: Create a Namespace and Label It**

Let’s start by creating a namespace `test` and labeling it for identification:

```plaintext
kubectl create ns test
kubectl label ns test area=test
kubectl get ns --show-labels
```

---

#### **Step 2: Define a Network Policy**

Below is an example Network Policy that allows all pods in the `prod` namespace to receive ingress (incoming) traffic from any source:

```plaintext
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all-ingress
  namespace: prod
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector: {}
```

**Explanation**:

* `podSelector: {}`: Matches all pods in the `prod` namespace.
    
* `policyTypes: Ingress`: The policy applies to incoming traffic.
    
* `from` with `podSelector: {}`: Allows traffic from all pods in any namespace.
    

---

#### **Step 3: Apply the Network Policy**

Save this YAML as `network-policy.yaml` and apply it:

```plaintext
kubectl apply -f network-policy.yaml
```

---

#### **Step 4: Verify the Network Policy**

List the applied network policies in the `prod` namespace:

```plaintext
kubectl get networkpolicy -n prod
```

---

### **Advanced Use Case: Namespace-to-Namespace Communication**

Suppose you want to allow a pod in the `test` namespace to communicate with a pod in the `prod` namespace. The following Network Policy achieves this:

```plaintext
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-test-to-prod
  namespace: prod
spec:
  podSelector:
    matchLabels:
      role: backend
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          area: test
      podSelector:
        matchLabels:
          role: frontend
```

**Explanation**:

* **Namespace Selector**: Only allows traffic from namespaces labeled with `area=test`.
    
* **Pod Selector**: Only allows traffic from pods labeled `role=frontend` in the `test` namespace to pods labeled `role=backend` in the `prod` namespace.
    

---

## **Conclusion**

* **LimitRange**: Helps enforce resource allocation constraints, ensuring stability and preventing resource overuse or application crashes.
    
* **Network Policies**: Enhance security by controlling pod communication within and across namespaces.
    

By implementing these features, you can optimize resource usage and enforce strong security policies in your Kubernetes cluster. Try these configurations in your environment to see their impact in action!
