# 6: Kubernetes Deployment and Services: A Practical Guide & Scaling and Services

When working with Kubernetes (K8s), starting with simple pod deployments is a common first step. However, managing pods manually comes with challenges like:

1. **No Self-Healing:** Pods don’t automatically recover when they fail.
    
2. **No Scaling (Manual or Automatic):** Scaling up or down requires manual intervention.
    
3. **No Upgrade Without Downtime:** Updating applications requires taking pods down, causing downtime.
    
4. **No Rollbacks:** Reverting to a previous version of an application is not straightforward.
    

To address these issues, **Deployments** and **ReplicaSets** provide a robust, declarative solution.

---

## Understanding Kubernetes Deployments

### Key Features of Deployments:

* **Declarative Updates:** Use YAML files to define the desired state of your application.
    
* **Scaling:** Supports both manual and automatic scaling through ReplicaSets.
    
* **Self-Healing:** Pods are automatically recreated if they fail.
    
* **Upgrade and Rollback:** Update applications seamlessly without downtime and revert to previous versions if needed.
    

### Components of a Deployment YAML File:

A Deployment YAML typically has three main sections:

1. **Metadata:** Includes the name and labels of the deployment.
    
2. **Replicas:** Specifies the desired number of pod replicas.
    
3. **Pod Template:** Describes the pod configuration, including labels, container specifications, and ports.
    

#### Important Note:

The **labels in the ReplicaSet must match the labels in the pods** for the ReplicaSet to manage the pods correctly.'

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1732197232904/54c989ba-d4f8-4bad-bad7-21a212e7d265.png align="center")

---

### Example: Nginx Deployment

After applying a deployment, Kubernetes creates:

1. A **Deployment** resource (e.g., `nginx-deployment`).
    
2. A **ReplicaSet** (e.g., `nginx-deployment-7f98c79676`).
    
3. Pods managed by the ReplicaSet (e.g., `nginx-deployment-7f98c79676-46kz2`).
    

#### Commands to Explore the Deployment:

* **Get Deployment:**
    
    ```plaintext
    kubectl get deployment
    ```
    
* **Describe Deployment:**
    
    ```plaintext
    kubectl describe deployment nginx-deployment
    ```
    
* **Get ReplicaSets:**
    
    ```plaintext
    kubectl get rs
    ```
    
* **Describe ReplicaSet:**
    
    ```plaintext
    kubectl describe rs nginx-deployment-7f98c79676
    ```
    

#### Observations:

The pods are created and managed by the ReplicaSet, not directly by the Deployment.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1732197263994/fab6f05b-296e-46e6-a224-df2cdbf4e75b.png align="center")

---

## Introduction to Kubernetes Services

### Why Use Services?

Deployments and ReplicaSets efficiently manage pods, but connecting to pods directly can be challenging because pod IPs are dynamic and can change. A **Service** abstracts pod communication by providing:

1. A **stable IP address** for accessing applications.
    
2. Load balancing across multiple pod replicas.
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1732197213498/89d854b5-4187-443f-85f5-61598c018b75.png align="center")

### Key Features of Services:

* **Selector Matching:** Services use selectors to identify and route traffic to the pods with matching labels.
    
* **Endpoints Management:** Services continuously monitor and update pod IPs to ensure connectivity.
    
* **Target Port:** The port where the application is running within the pod.
    

#### Commands to Manage Services:

* **Get Deployments:**
    
    ```plaintext
    kubectl get deployment
    ```
    
* **Get Services:**
    
    ```plaintext
    kubectl get service
    ```
    
* **Shortcut for Services:**
    
    ```plaintext
    kubectl get svc
    ```
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1732197200818/ba503982-0a93-4027-9682-aad7d7a4a476.png align="center")
    
    ## Troubleshooting Services
    
    ### No Endpoints in Service?
    
    If a service does not display any endpoints, it usually indicates a label mismatch.
    
    * **Reason:** The labels defined in the service selector do not match any pods managed by a ReplicaSet.
        
    * **Fix:** Ensure the service selector labels match the pod labels managed by the ReplicaSet.
        
    
    #### Example:
    
    * **Service Selector:**
        
        ```plaintext
        selector:
          app: nginx
          tier: frontend
        ```
        
    * **Pod Labels:**
        
        ```plaintext
        labels:
          app: nginx
          tier: frontend
        ```
        
    
    If these labels don’t align, the service will fail to register endpoints.
    
    ---
    
    ### Handling Multiple Labels in Services
    
    When a service uses multiple selectors, a pod must match **all labels** for it to be added as an endpoint.
    
    #### Example:
    
    * **Service Selector:**
        
        ```plaintext
        selector:
          app: nginx
          env: production
        ```
        
    * **Pod Labels:**
        
        ```plaintext
        labels:
          app: nginx
          env: production
          team: devops
        ```
        
    
    In this case, the pod matches because it has both `app: nginx` and `env: production`. Additional labels (e.g., `team: devops`) do not impact the matching process.
    
    ---
    
    ## Scaling Deployments
    
    ### Manual Scaling
    
    Manual scaling adjusts the number of replicas in your deployment to handle increased or decreased load.
    
    #### Command-Based Scaling:
    
    Use the following command to scale your deployment to five replicas:
    
    ```plaintext
    kubectl scale --replicas=5 deployment nginx-deployment
    ```
    
    #### YAML-Based Scaling:
    
    Scaling using YAML is a declarative approach and is generally preferred in production environments. Update the `replicas` field in your deployment YAML file:
    
    ```plaintext
    spec:
      replicas: 5
    ```
    
    Apply the updated configuration:
    
    ```plaintext
    kubectl apply -f deployment.yaml
    ```
    
    ---
    
    ### Automatic Scaling
    
    Automatic scaling requires the **Horizontal Pod Autoscaler (HPA)**, which adjusts replicas based on real-time metrics like CPU and memory usage.
    
    #### Prerequisite: Metrics Server
    
    Ensure a metrics server is installed in your cluster. It provides the data needed for autoscaling.
    
    #### HPA Configuration
    
    Here’s an example of an HPA configuration:
    
    ```plaintext
    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: nginx-deployment-hpa
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: nginx-deployment
      minReplicas: 2
      maxReplicas: 10
      metrics:
        - type: Resource
          resource:
            name: cpu
            target:
              type: Utilization
              averageUtilization: 50
    ```
    
    Add this HPA configuration to your deployment setup. You can find a detailed example in the [HPA Configuration Repository](https://github.com/muhammadhassanb111/kubernetes-yt/blob/master/ch-03-deployments/hpa-for-autoscaler-deployment.yaml).
    
    ---
    
    ### Simulating Load for Autoscaling
    
    To simulate load on your application and observe the HPA in action, use the following command:
    
    ```plaintext
    while true; do curl http://<service-ip-address>; done
    ```
    
    #### Verify HPA Status:
    
    Check the status of your Horizontal Pod Autoscaler:
    
    ```plaintext
    kubectl get hpa
    ```
