# 4: Understanding Kubernetes: Deep Dive into kubectl create vs kubectl apply, Labels, and Selectors

Kubernetes (K8s) provides several commands to manage resources effectively. This blog explores concepts like `kubectl create` vs `kubectl apply`, YAML configurations, labels, and selectors with examples.

---

### `kubectl create` vs `kubectl apply`

* `kubectl create`: This command is used to create new resources in Kubernetes. However, it only verifies the resource's name during creation. If the resource already exists, it throws an error.  
    Example:
    
    ```plaintext
    kubectl create -f deployment.yaml
    ```
    
    * If `deployment.yaml` defines a resource already present in the cluster, you'll get an error like:
        
        ```plaintext
        Error from server (AlreadyExists): deployments.apps "example-deployment" already exists
        ```
        
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1732107514402/f46c1c77-f3b7-4af8-960f-f538979016b5.png align="center")
    
* `kubectl apply`: Unlike `create`, the `apply` command allows you to modify resources declaratively. It compares the **Live Object Configuration (LOC)**, stored in `etcd`, with the **Last Applied Configuration (LAC)**.
    
    * When you use `apply`, Kubernetes updates the resource and retains a history of the last applied configuration for reference.  
        Example:
        
        ```plaintext
        kubectl apply -f deployment.yaml
        ```
        

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1732107522012/40cb6d92-d072-42d8-a78b-6d2cff111763.png align="center")

#### **How Kubernetes Works with YAML Files**

1. You define resources in a YAML file.
    
2. When you create or apply the YAML, Kubernetes converts it into a **Live Object Configuration (LOC)** stored in `etcd`.
    
3. For `kubectl create`, there is no **Last Applied Configuration (LAC)** stored, as the command doesn't track changes.
    
4. For `kubectl apply`, both LOC and LAC are maintained, enabling smooth updates.
    

---

### **Viewing Pod Details**

To understand the state of a pod:

* **View complete YAML configuration**:
    
    ```plaintext
    kubectl get po qr-app -o yaml
    ```
    
    This displays the YAML file representing the pod `qr-app`.
    
* **View labels of pods**:
    
    ```plaintext
    kubectl get pods --show-labels
    ```
    
    Labels provide metadata about applications, helping identify and organize resources.
    
* **Filter pods by labels**:
    
    ```plaintext
    kubectl get po -l "app=dev"
    ```
    
    This retrieves all pods where the label `app=dev` is present.
    
* **Delete pods by labels**:
    
    ```plaintext
    kubectl delete po -l "app=dev"
    ```
    
    This deletes all pods with the label `app=dev`.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1732107536752/73353e5b-1274-4ff8-9a75-87f71cc2504c.png align="center")
    

---

### **Kubernetes Labels: A Best Practice**

Labels are key-value pairs attached to Kubernetes objects, providing meaningful metadata. Kubernetes recommends adding at least the following **5 labels** for clarity:

1. **name**: Unique name for the application, e.g., `abc.com/name=dotnet`
    
2. **managed-by**: Who or what manages this resource, e.g., `abc.com/managed-by=hassan`
    
3. **version**: Application version, e.g., `v1.0`
    
4. **component**: Application component, e.g., `abc.com/component=frontend`
    
5. **part-of**: The larger application this component belongs to, e.g., `abc.com/part-of=projectX`
    

---

### **Label Selectors**

Label selectors allow you to filter Kubernetes objects based on specific criteria. Examples:

* **Basic selector**: Find pods labeled with `app=nginx`:
    
    ```plaintext
    kubectl get po -l "app=nginx" --show-labels
    ```
    
* **Exclusion selector**: Exclude pods labeled with `client=abc`:
    
    ```plaintext
    kubectl get po -l "app=nginx,client!=abc" --show-labels
    ```
    

For more details on labels and selectors, visit the [Kubernetes Documentation on Labels and Selectors](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/).

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1732107555871/d09837e4-ff9a-4ad1-bcca-fc35e0ce7ff2.png align="center")

---

### **Modifying Labels**

Labels can be modified imperatively or declaratively:

* **Imperative approach**:
    
    ```plaintext
    kubectl label pod nginx managed-by=hassan
    ```
    
    * Note: This method updates the labels immediately but doesn't affect the **Last Applied Configuration (LAC)**.
        
* **Declarative approach**: Update the YAML file and reapply it using `kubectl apply`. This method also updates the LAC, ensuring consistency.
    

---

### **Conclusion**

Understanding commands like `kubectl create` and `kubectl apply` is essential for resource management in Kubernetes. Labels and selectors enhance your ability to organize and manage resources effectively. Adopting best practices such as recommended labels and leveraging LAC for tracking changes will improve your workflow.

Ready to explore more? Check out the official Kubernetes documentation for in-depth guidance.
