Category Archives: kubernetes

Top Kubectl Commands Every DevOps Engineer Needs for Kubernetes Troubleshooting

Introduction

In the fast-paced world of cloud-native applications, Azure Kubernetes Service (AKS) has become a go-to platform for DevOps teams across the world. However, managing and troubleshooting Kubernetes clusters can be challenging, especially when dealing with issues in pods, deployments, or containers. Thankfully, Kubernetes provides a powerful command-line tool called kubectl that allows you to interact with your AKS cluster. This article will walk you through the most essential kubectl commands to help DevOps engineers and cloud professionals effectively Kubernetes Troubleshooting  issues in their AKS clusters.

When to Use These Commands

You should use these kubectl commands when:

  • Pods are in a CrashLoopBackOff or Error state.
  • A deployment is not scaling as expected.
  • Containers fail to start or exhibit unexpected behavior.
  • Networking issues prevent services from communicating.
  • You need to inspect logs to understand what’s happening inside a container.
  • You want to check the status and events related to a pod or deployment.
  • You need to execute commands inside a running container for debugging purposes.

Essential Kubectl Commands for Troubleshooting in AKS

1. Get the Status of Pods, Deployments, and Services

This command lists all the pods, deployments, or services in a specific namespace. It helps you quickly identify if any pods are in a CrashLoopBackOff, Pending, or Error state.

kubectl get pods
kubectl get deployments
kubectl get services
#Example: 
kubectl get pods -n <namespace>

2. Describe a Pod or Deployment

The describe command provides detailed information about a specific pod or deployment, including events, configuration, and status. This is useful for understanding why a pod might be failing or why a deployment isn’t scaling correctly.

The kubectl describe command provides detailed information about various Kubernetes resources, such as pods, nodes, and deployments. By running kubectl describe <resource> <resource-name> -n <namespace>, you can access a wealth of data, including events, conditions, and configuration details, helping you pinpoint the root cause of problems.

kubectl describe pod 
kubectl describe deployment 
#Example: 
kubectl describe pod my-pod -n <namespace>
kubectl describe deployment customer-service -n customer

The output will contain detailed information about the specified pod, including its metadata, container information, conditions, and events. This information can be invaluable for troubleshooting issues with the pod, such as initialization problems, readiness issues, or events related to its lifecycle.

3. View Pod Logs

This command fetches the logs from a specific pod, which is crucial for debugging issues within the container. You can also use the -f flag to follow the logs in real-time.

When application-level issues arise, examining pod logs is crucial. Use kubectl logs <pod-name> -n <namespace> to view the logs of a specific pod in a given namespace. This command is invaluable for identifying errors, exceptions, or issues within your application code.

kubectl logs 
#Example: 
kubectl logs my-pod -n 

4. Execute Commands in a Running Container

This command allows you to open a shell inside a running container. It’s useful for running diagnostic commands or inspecting the file system directly within the container.

#Linux pod: 
kubectl exec -it  -- /bin/bash
#Window pod: 
kubectl exec -it  -- powershell
#Example: 
kubectl exec -it my-pod -n  -- /bin/bash

5. Check Event Logs for a Namespace

This command lists all events in the cluster, sorted by creation time. Events can provide insights into what’s happening in your cluster, such as why a pod was evicted or why a deployment failed.

kubectl get events --sort-by=.metadata.creationTimestamp
#Example: 
kubectl get events -n <namespace> --sort-by=.metadata.creationTimestamp

Real-World Scenario: Troubleshooting Pod Initialization

Suppose you encounter an issue where pods are not initializing correctly. You can use kubectl get events –all-namespaces to identify events related to pod initialization failures, helping you pinpoint the root cause.

6. View Node Resource Utilization

This command shows the CPU and memory usage of pods or nodes. It’s useful for identifying resource bottlenecks that might be causing issues in your AKS cluster.

kubectl top pod
kubectl top node
#Example: 
kubectl top pod -n <namespace>

Conclusion

Troubleshooting issues in Azure Kubernetes Service (AKS) can be challenging, but with the right kubectl commands, you can quickly identify and resolve problems in your pods, deployments, and containers. By using commands like kubectl get, kubectl describe, kubectl logs, and kubectl exec, you can gain deep insights into the state of your AKS cluster and take corrective actions. Whether you’re dealing with a crashing pod, a misbehaving deployment, or a container that’s not responding, these commands are essential tools in your Kubernetes troubleshooting toolkit.

By mastering these essential kubectl commands, you can minimize downtime, improve operational efficiency, and keep your AKS workloads running smoothly.

Troubleshooting DNS Failures in Azure Kubernetes Service (AKS) Clusters

Introduction

Monitoring DNS resolution inside Azure Kubernetes Service (AKS) is essential for maintaining reliable application connectivity. When DNS failures occur, services can experience intermittent connectivity or complete outages. One effective way to diagnose these issues is by using tcpdump with CoreDNS — the DNS server used by AKS.

In this guide, you’ll learn how to configure tcpdump within your CoreDNS deployment to capture and analyze DNS request/response traffic in real time

Prerequisites:

  • You need kubectl configured and connected to your AKS cluster.
  • Ensure you have permissions to manage deployments and pods in your Kubernetes cluster.

Step-by-Step Guide to Configure tcpdump to Find DNS failures

Step 1: Identify the CoreDNS Deployment

First, you need to find the CoreDNS deployment in your Kubernetes cluster: Look for a deployment named coredns in the kube-system namespace.

kubectl get deployments -n kube-system

Look for a deployment named coredns in the kube-system namespace.

Step 2 : Backup the coredns to Local

As a precautionary measure, create a local backup of your CoreDNS deployment YAML file before making any changes. You can achieve this using the following command:

kubectl get deployment coredns -n kube-system -o yaml > coredns.yaml

Step 3 : Add tcpdump Container to CoreDNS Deployment

Method 1: Edit the CoreDNS Deployment

Edit the coredns deployment and add the tcpdump container under the spec.template.spec.containers section of the CoreDNS deployment YAML. Here’s an example of how you can add it and save:

spec:
template:
spec:
containers:
- name: tcpdump
image: docker.io/corfr/tcpdump
args: ["-C", "100", "-W", "20", "-v", "-w", "/data/dump" ]

When you use tcpdump to capture packets, it writes them into a file (like dump00.pcap). If you keep capturing for a long time, that file can grow very large — potentially filling up the pod’s disk.

1️⃣ -C <file_size> — Limit the size of each capture file

This flag sets the maximum size (in megabytes) of a single capture file.

🔹 Example: -C 100
→ Each .pcap file will be limited to 100 MB.
Once the file reaches 100 MB, tcpdump automatically starts a new file.

2️⃣ -W <file_count> — Limit how many files to keep

This flag sets the number of rotated files tcpdump should keep.

🔹 Example: -W 20
→ tcpdump will keep 20 files maximum, rotating them like a circular buffer.
When it reaches the 21st file, it overwrites the oldest file.

Method 2: patch the deployment

Create patch.yaml file with above spec content and save to local and execute using below kubectl.

kubectl patch deployment coredns -n kube-system –patch-file patch.yaml


Post either followed Method 1 or 2, This changes will apply and trigger a rollout of the CoreDNS deployment.

Step 4 : Check the tcpdump container status

Once the rollout is complete, use the following command to check if the tcpdump container is running within a coredns pod: The output should display the tcpdump container listed among the containers running within the pod.

kubectl describe pod coredns -n kube-system

Step 5 : Verify the dump 

Access the core dns pod using the following command, replacing <coredns-pod-name> with the actual pod name:

kubectl exec -it <coredns-pod-name> -n kube-system -c tcpdump — sh

Once inside the pod, navigate to the /data directory to view the captured packets. You should find a file named “dump00” containing the captured network traffic data.

ls /data

There should be a dump00 file present.

Step 6: Downloading Logs from coredns 

At this point we wait for a few occurrences of the issue. Not sure how long this will take, that would depend on how often you see the error which you expect to collect in dumps. Once enough data is collected, you can exec into each of the pods and rename the file to apply the proper extension and then copy it to your local directory.

After enter in to the coredns pod, execute the below cmd ( you can able to see more dumps like dump00 , dump01, dump01….) to rename all the dump files as you required (XX replace with the your own name). Ensure you executing this command after moving to /data directory. Repeat this step, based on how much dump file present inside the coredns pod.

mv dump00 dumpXX.pcap

Finally exit the pod and in powershell/cmd, you can start to download from coredns to you local

kubectl cp kube-system/coredns-86c697cd8-6qtx9:/data/dump00.pcap -c tcpdump ./coredns-dump00

Step 7: Cleanup (Optional)

Remember to remove the tcpdump container from the CoreDNS deployment once you have completed your troubleshooting to avoid unnecessary resource usage and potential security risks. By restarting the coredns pods, the latest change will removed and back to its original state.

Conclusion

Configuring tcpdump on CoreDNS in AKS allows you to monitor DNS traffic effectively for troubleshooting and analysis purposes. By integrating tcpdump with CoreDNS, you can observe real DNS traffic patterns and isolate failures within your AKS cluster. This approach is invaluable for diagnosing name resolution issues that affect microservice communication or external dependencies. Use it in a controlled manner, and remove the tcpdump container once troubleshooting is complete. 

Notes

  • Security: Exercise caution with tcpdump as it can capture sensitive information. Ensure appropriate access controls and secure practices are in place.
  • Performance: Running tcpdump may impact pod performance and network throughput. Use it judiciously, especially in production environments.
  • Logging and Monitoring: Consider integrating tcpdump logs with your existing logging and monitoring solutions for better visibility and analysis.

Mastering Persistent Storage in Azure Kubernetes Service (AKS): A Step-by-Step Guide Using Azure Disks

Kubernetes is the leading managed container orchestration platform preferred by customers deploying microservices-based architectures in the cloud. Azure Kubernetes Service offers Kubernetes as a managed service, where the container orchestration platform is handled by Azure, enabling customers to focus on the developments of applications. Then how does AKS meet Kubernetes storage demands?

Containers are stateless, which means data is not stored locally—these containers depend on attached persistent volumes to handle the data lifecycle. This blog will walk through the steps required for provisioning persistent volumes and configuring them to be used by containers in Azure Kubernetes Service clusters.

What is Persistent Storage?

Persistent Storage is a mechanism to store data outside the lifecycle of a container or application, ensuring that critical information (like databases, user uploads, or configuration files) persists even if the container restarts, crashes, or is replaced. It’s essential for stateful applications (e.g., databases, CMS) that require data durability.

By default, the storage associated with pods is deleted when the pod lifecycle ends. For stateful applications, however, storage is expected to be persistent so that the data can remain available every time the pods gets recreated in the cluster. Container persistent storage in a Kubernetes cluster is provisioned using the PersistentVolume subsystem, which provides PersistentVolume and PersistentVolumeClaim API resources.

The PersistentVolumeClaim requests for a specific storage class, say Azure disks or Azure Files, and the underlying storage resource gets provisioned. This PersistentVolumeClaim is referenced in the pod definition so that the provisioned storage is mounted to the pod. In this way the PersistentVolume is linked to the PersistentVolumeClaim whenever the provisioned storage is mounted to the pod requesting the resource.

Note: The following steps will assume that the AKS cluster is already provisioned and that the administrator has access to execute the commands listed in this blog.

Provision Persistent Storage Using Azure Disks

There are four major steps in creating and attaching persistent storage using Azure disks in Azure Kubernetes Service.

1. Define/Create of storage class.
2. Configuration of persistent volume claim (PVC) that references of storage class.
3. Create the persistent volume claim and provision the volume.
4. Reference the PVC in the Pod specification to attach the Azure Disk ie., Attaching the provisioned volume to the pod by referencing the specific pod in the pod definition file.’

Let’s explore this process in detail with sample configuration files.

How AKS Uses Azure Disk Storage Classes

Azure Kubernetes Service (AKS) simplifies persistent storage management by offering two pre-configured storage classes for Azure Disks: default and managed-premium. These classes let teams provision storage tailored to workload requirements while abstracting backend complexity. Here’s how they work and where they shine—or fall short.

  • Built-in Storage Classes
  • default (Standard HDD)
  1. default (Standard HDD)
    • Backend: Relies on cost-effective Azure Standard HDD storage.
    • Use Case: Ideal for non-critical workloads like backups, logs, or dev/test environments where high throughput isn’t a priority.
  2. managed-premium (Premium SSD)
    • Backend: Leverages Azure Premium SSD for low latency and high IOPS.
    • Use Case: Suited for production workloads (e.g., databases, transactional apps) demanding consistent performance and faster data access.

Limitations of Built-in Classes

While convenient, the pre-built storage classes come with constraints:

No Post-Provisioning Resizing: Once a volume is created, you can’t expand its size—a hurdle for growing datasets or scaling applications.

Fixed Configuration: Default settings (e.g., performance tiers, redundancy) may not align with specialized needs.

Default: This storage class uses the standard Azure storage which leverages HDDs in the backend.

Creating Custom Storage Classes

In this section we’ll show you how users can create custom storage classes to suit their specific requirements.

1. Make Ready of StorageClass YAML

Connect to the AKS cluster from your management tool of choice (here i used powershell/CMD to connect the cluster using kubectl). For this demonstration we will be using Azure CL. From the Azure CLI, save the following manifest as storage-class.yaml

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: managed-standard-custom
provisioner: disk.csi.azure.com
reclaimPolicy: retain
allowVolumeExpansion: true
parameters:
  storageaccounttype: Premium_LRS
  kind: Managed

This file can be used to create a storage class that uses Premium_LRS managed disks. The reclaimPolicy is set to retain so that the persistent volume is not deleted even if the pod to which it is attached gets deleted. With the parameter allowVolumeExpansion set to true, the volume can now be resized even after provisioning.

 

ProvisionerStorage TypeRecommended UseNotes
disk.csi.azure.comAzure Managed Disks (Block Storage)High-performance workloads requiring dedicated block storage on a single nodeCSI-based; supports dynamic provisioning, volume expansion, and advanced features. Recommended for new deployments. :contentReference[oaicite:0]{index=0}
kubernetes.io/azure-disk (deprecated)Azure Managed Disks (Block Storage)Legacy setups using in-tree driversDeprecated in favor of the CSI-based disk.csi.azure.com provisioner.
file.csi.azure.comAzure Files (File Storage)Workloads needing shared storage (ReadWriteMany), such as content management or shared configuration filesCSI-based; supports SMB or NFS file shares with dynamic provisioning. :contentReference[oaicite:1]{index=1}
kubernetes.io/azure-file (deprecated)Azure Files (File Storage)Legacy deployments requiring shared file storageDeprecated in favor of the CSI-based file.csi.azure.com provisioner.
azureblob-csiAzure Blob Storage (Object Storage mounted as a filesystem)Workloads that use large unstructured datasets, such as logs or archival dataEnables mounting of Blob storage via CSI as a filesystem (using protocols like NFS or BlobFuse). Suitable for applications that do not require block storage.

 

2. Apply the yaml file using the following command

$ kubectl apply -f storage-class.yaml

Upon successful execution, you will get a message that the storage class has been created.

Create Persistent Volume Claim and Persistent Volume

The next step is to create a persistent volume claim (PVC), which uses the storage class defined in the above to provision an Azure disk as a persistent volume.

1. Create custom-pvc.yaml file in the Azure CLI window

Create the PVC creation YAML as shown below,

The PVC will request for an Azure disk of 10 GB with accessmode as ReadWriteOnce. That means only one node can mount the volume as read-write.

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: custom-pvc
  namespace: default
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: managed-standard-custom
  volumeMode: Filesystem
Access ModeDescription
ReadWriteOnceThe volume can be mounted as read-write by a single node. It can allow multiple pods to access it when running on the same node.
ReadOnlyManyThe volume can be mounted as read-only by many nodes.
ReadWriteManyThe volume can be mounted as read-write by many nodes.
ReadWriteOncePodFEATURE STATE: Kubernetes v1.29 [stable]
The volume can be mounted as read-write by a single Pod. This ensures that only one pod across the whole cluster can read or write to the PVC.

 

2. To create the volume itself, run the following command:

kubectl apply -f custom-pvc.yaml

On successful execution you will see a message that the persistent volume claim has been created.

After creation, the provisioned volume can also be seen from the Azure portal. Browse to the resource group where the AKS nodes are created to find the newly provisioned disk listed there. 

As highlighted in yellow, you can able to view  Persistent Volume has created with name of  “pvc-ae14b4f9-68d5-4aed-baf3-6addfe4e8b3d”

Once PVC is create successfully (status is bound) then the Persistent volume will create automatically and mapped to the PVC (refer above and below image)

 

And you can also verify disk with name of Persistent Volume by searching in the Azure portal as shown in below, where our mount data will be stored.

You can also run the following command to list the pvc status. It will be listed as “bound” to the created persistent volume:

You can also get all the PVC in your cluster, you can use kubectl get pvc

Attach a Persistent Volume to AKS

After creating the persistent volume claim and the Azure disk, it can be attached to a new pod by referencing the name of the persistent volume claim in the deployment or pod yaml.

1. Create file Nginx.yaml with the following content

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      restartPolicy: Always
      containers:
        - name:  nginx
          image: crdgtlshared02.azurecr.io/nginx:latest
          volumeMounts:
            - name: volume
              mountPath: /tmp/
      volumes:
        - name: volume
          persistentVolumeClaim:
            claimName: custom-pvc
      nodeSelector:
        kubernetes.azure.com/agentpool: userlnxpool
        kubernetes.azure.com/mode: user
        kubernetes.io/os: linux

The volume is mounted at /tmp/ as specified by the mountpath parameter.

Note that the image for the container is taken from my Azure container registry. Alternatively, it can also be downloaded from the Azure container registry.

2. Next, create the pod using the following command:

kubectl apply -f Nginx.yaml

When successfully executed, we can able to view the deployment is created successfully as shown below.

We also ensure in Azure portal by viewing pod will be created as shown below images under default namespace.

3. Verify that the persistent volume is attached to the pod 

kubectl describe pod nginx

The PVC will request for an Azure disk of 10 GB with access mode as ReadWriteOnce. That means only one node can mount the volume as read-write.

You can see that the volume is listed and and uses the claim name “custom-pv.”

Check Volume mount in your pod

To connect to the running Azure container instance, use the following command and run the df command to view the volumes:

kubectl exec -it <pod-name> -n <namespace> -- /bin/bash
kubectl exec -it nginx-7466c47dd6-h9tvz -n default -- /bin/bash

/dev/sdb : >> This indicates the device file associated with the storage. In this case, /dev/sdb refers to the second SCSI disk on the system.]

1K-blocks: 10218772 >>This shows the total size of the filesystem in 1-kilobyte blocks. Here, it amounts to approximately 10,218,772 KB, or roughly 9.75 GB.

Use%: 1% >> This shows the percentage of the filesystem’s capacity that is currently used. In this case, only 1% of the space is utilized.

Mounted on: /tmp >>This specifies the mount point, which is the directory where the filesystem is attached to the system. Here, the device /dev/sdb is mounted on /tmp, the standard directory for temporary files in Unix-like systems.

When AKS Won’t Scale Down: How We Fixed a Real Node Pool Autoscaling Failure in Production

Managing autoscaling in Azure Kubernetes Service (AKS) is not always straightforward. Recently, we ran into a problem where node pool scale down was not happening in both regions, and workloads were consuming resources beyond the defined cluster threshold. This article walks through the scenario, investigation, and resolution.

Scenario: Node Pool Not Scaling Down

The Context: A Planned Node Migration

Our production AKS cluster was running a node pool named mslnxpool02 (D-series VMs) on Kubernetes version 1.31.9. Following a performance review, Microsoft recommended migrating our workloads to E-series VMs for better resource utilization and cost-efficiency aligned with our application’s profile.

  1. To execute this migration, our team proceeded with a blue-green approach:
  2. Created a new node pool with E-series VMs.
  3. Used identical node labels on both the old (D-series) and new (E-series) node pools.

Relied on our Deployments, which used these labels as node Selectors (from starting we having this node selectors so only applied same label to new node pool), to automatically schedule new pods onto the E-series nodes as we cordoned and drained the D-series nodes.

The strategy was to incrementally scale up the E-series pool while simultaneously scaling down the D-series pool, allowing the cluster auto scaler to seamlessly re-schedule pods and reduce node count.

The Problem: Scale-Down Stalls, Incurring Cost

The initial phase of scaling up the new node pool and migrating pods worked as expected. However, we soon noticed a critical issue: the D-series node pool failed to scale down.

Despite workloads being successfully migrated and cluster resource usage dropping significantly, several nodes in the mslnxpool02 pool remained active. Even after waiting for an extended period to account for the cluster auto scaler’s cooldown delays, the node count remained stubbornly high. This resulted in unnecessary cloud costs and a cluster full of underutilized nodes.

The question was: Why was the scale-down stuck?

The following sections detail our investigation and the root cause we uncovered.

Step 1: Investigating the Node health

In my cluster, I had a node pool mslnxpool02 with multiple nodes running Kubernetes v1.31.9. Despite low workloads, the cluster auto scaler wasn’t scaling down the pool. Checking the nodes showed that they were all in a Ready state:

#check with powershell
kubectl get nodes | findstr lnxpool02

At first glance, the nodes looked healthy, but the auto scaler wasn’t freeing up any of them.

Step 2: Describe the Each Node for cause

To understand why the node couldn’t be scaled down, I began with a detailed inspection of one of the stuck nodes: aks-mslnxpool02-33931444-vmss000017.

kubectl describe node aks-lnxpool02-33931444-vmss000017

This command provides a comprehensive overview of the node’s status, capacity, and all the pods running on it. Here’s a breakdown of what I looked for and what I found:

  1. The node was Ready.
  2. Multiple workloads were running on it, including system pods (e.g., kube-proxy, csi-azure*, ama-logs, myapplication pods).
  3. One workload (my service) (customerfeed-service) had large CPU and memory requests as shown below:

CPU Requests: 6100m of 7820m (78%)
CPU Limits: 13 cores (166%)
Memory Requests: 2688Mi
Memory Limits: 10Gi

 

This explained part of the problem: auto scaler cannot evict pods that request a large percentage of node resources unless they can be rescheduled elsewhere.

Now we found the cause, the scaling down was not happened due to the high utilization of some application pods, which not allowing Node pool to scale down.

Step 3: Isolating the Node with Cordon Command

After identifying that the node was blocked from scaling down due to the customerfeed-service pod, the next step was to manually intervene and signal to the cluster that this node was a candidate for removal. This is where the kubectl cordon command comes in.

The primary goal of cordoning a node is to isolate it from receiving any new workloads. Think of it as putting up a “Do Not Enter” sign for the Kubernetes scheduler. This is a crucial, non-disruptive first step in any node maintenance or decommissioning process.

In simple , To prepare the node for scale-down, I manually cordoned it so no new pods would schedule on it:

kubectl cordon aks-mslnxpool02-33931444-vmss000017

Now the node appeared as Ready,SchedulingDisabled

kubectl get nodes | findstr mslnxpool02

aks-lnxpool02-33931444-vmss000017 Ready,SchedulingDisabled <none> 47d v1.31.9

This change told the cluster auto scaler that the node was un-schedulable.

In my case, i had done cordon for all the node pool and  you can confirm in the UI as well like below

Key Takeaways Highlights:

  • cordon is Non-Disruptive: It’s a safe first step that doesn’t affect running pods.

  • It’s a Signal: It tells both the Kubernetes scheduler and the Cluster Autoscaler to avoid this node.

  • It’s Not a Solution by Itself: Cordoning prepares the node but doesn’t solve the underlying resource fragmentation problem. It’s often the prelude to a drain operation.

Step 4: Allocation adjustment or restart the effected pod

After cordoning the node pool, we needed to address the affected pods that were preventing the autoscaler from acting. Simply cordoning ensures no new pods are scheduled on the node, but the existing high-utilization pod continues running and blocking scale down.

To resolve this, we took two possible actions:

Option A:  Restart the Affected Pod (Quick Fix)

If adjusting manifests immediately isn’t feasible (for example, in production during peak hours), a faster approach is to restart the affected pod so it can be rescheduled to a healthier node pool(as old node pool is restricted to schedule so it will map to new node pool):

1. Delete the Pod

 
kubectl delete pod <pod-name> -n <namespace>

2. Kubernetes Rescheduling

Kubernetes automatically recreates the pod on another available node pool.

This helps free up utilization on the cordoned pool, enabling the Cluster Auto scaler to scale it down.

⚠️ Note: This is a temporary workaround. Without fixing the resource requests in the deployment, the issue may reappear.

Option B:  Allocation Adjustment (Preferred)

1. Review Pod Resource Requests and Limits

Check the resources.requests and resources.limits configuration in the deployment manifest. In our case, the application pod had very high actual CPU utilization, but its configuration did not reflect realistic usage, keeping the node pinned.

In our case, the application pod had very high CPU requests, which forced the scheduler to keep nodes active.

Example snippet:

resources:
  requests:
    cpu: "2000m"   # 2 cores requested
    memory: "4Gi"
  limits:
    cpu: "3000m"
    memory: "6Gi"

2. Adjust Resource Requests

Increase the CPU or memory requests (based on observed utilization) to match actual needs. This ensures Kubernetes schedules pods more accurately and avoids overcommitting nodes.

Example snippet:

resources:
  requests:
    cpu: "6000m"   # increased to 4 core
    memory: "4Gi"
  limits:
    cpu: "4000m"
    memory: "6Gi"

This alignment gives the auto scaler a true view of resource usage, enabling it to correctly evaluate which nodes can safely scale down.

Conclusion

Node pool scale-down issues in AKS often come down to workload placement and resource requests. In this scenario, a single oversized pod was preventing the auto scaler from acting. By analyzing node workloads, cordoning, and draining, I was able to resolve the problem and allow auto scaler to scale down efficiently.

Boost Application Reliability with Kubernetes postStart Hooks (Real-World Examples Inside)

Introduction

Hooks allow developers to run custom logic at critical points in a container’s lifecycle. These hooks help with initialization and graceful shutdown, ensuring applications are reliable, performant, and consistent. In this article, we’ll explore lifecycle hooks in Kubernetes, with a focus on the postStart hook, real-world use cases, and practical examples using Windows IIS containers.

Types of Hooks in Kubernetes

Kubernetes offers two primary lifecycle hooks for containers:

postStart Hook:

Triggered immediately after a container is started.

Commonly used for initializing services, setting up configurations, or performing other preparatory tasks before the application is fully operational. PostStart Hook provides us ability to perform some task before the pod is completely initialized. This hook is executed immediately after a container is created. However, there is no guarantee that the hook will execute before the container ENTRYPOINT command. This is useful for scenarios where you want to perform some setup before the main container in the pod starts running.

preStop Hook:

Triggered just before a container is terminated.

Often used to gracefully shut down services, close connections, or clean up resources to ensure data integrity and prevent resource leaks. This is particularly useful for applications that need to gracefully shut down, ensuring that ongoing processes complete before the container stops. Examples of tasks include closing database connections, finalizing transactions, or notifying external systems about impending shutdown.

In this post, we are going to discuss more deep in to the postStart Hook

Use Case : When and Where is the postStart Hook Required?

The postStart lifecycle hook is useful in scenarios where specific tasks need to be performed before the main application in a container becomes functional. Some common use cases include:

Environment Setup: Copying necessary files or templates. Modifying configuration files dynamically based on the environment.

Application Warm-up: Performing application-specific warm-up tasks to reduce the latency of initial requests.

Service Initialization: Setting up dependencies or configurations required by the application. Starting background services or processes necessary for the container’s operation.

Example Scenario

Consider a scenario where an ASP.NET application hosted on IIS requires a startup script (startup.ps1) to configure IIS settings, initialize application-specific environment configuration substitution, or perform other preparatory tasks. Using the postStart hook ensures that these configurations are executed as soon as the container starts.

Configuring the postStart Lifecycle Hook

Here’s an example Kubernetes pod specification that uses the postStart lifecycle hook to execute a PowerShell script: In the provided example, the postStart hook logs a message to C:\poststart.log in a Windows IIS container, confirming successful initialization. By leveraging postStart hooks, you can add flexibility and control to your containerized applications, ensuring they are fully prepared to handle their workloads upon startup.

For this example, i had explain with simple logging the message in the poststart. Based on requirement, you can have .ps1 (startup.ps1)/configuration file to execute during the container creation.

Example 1: Create Simple log file in PostStart

STEP 1: Create the pod using below YAML

Save the below YAML as iis-pod and run the below kubectl cmd to create the pods in AKS, as shown in the STEP 2

kind: Pod
metadata:
name: iis-pod
spec:
containers:
- name: iis-container
image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2022
lifecycle:
postStart:
exec:
command:
- cmd
- /c
- echo PostStart hook executed > C:\poststart.log
ports:
- containerPort: 80
#Execute the YAML to create the pod
kubectl create -f iis-pod.yaml

STEP 2: Check the pod status

Execute the below Kubectl comments to ensure pod is running successfully.

# Command to get pods’ status:

kubectl get pods

# Command to view the details of Pod:

kubectl describe pod iis-pod

STEP 3: Get in to the pod to verify poststart.log file

The postStart hook executes the specified command and the text “PostStart hook executed” is written to the file C:\poststart.log. The container initializes and becomes ready to handle requests on port 80

Explanation of the Configuration (Command Breakdown)

  • The exec : field specifies the command to be executed:
  • cmd: Specifies the Windows Command Prompt as the executor.
  • /c: Tells the Command Prompt to execute the provided command and then terminate.
  • echo PostStart hook executed > C:\poststart.log: Writes the text “PostStart hook executed” into the file C:\poststart.log. If the file does not exist, it is created automatically. If it exists, the content is overwritten.
  • Port 80 : The container exposes port 80, which is the default HTTP port for IIS.
# Enter in to the pod using Kubectl
kubectl exec -n default iis-pod -it -- powershell

Example 2: Create Warmup in PostStart

The postStart hook waits 5 seconds for IIS to initialize. It sends an HTTP GET request to http://localhost to ensure the default page is accessible and finally the HTTP response is saved to C:\warmup.log, which can be inspected for debugging or verification.

Explanation of the Configuration (Command Breakdown)

  • Start-Sleep -Seconds 5; : Introduces a short delay to ensure IIS has started before making a request.
  • Invoke-WebRequest -Uri http://localhost: Sends an HTTP request to the IIS default page hosted on the same container.
  • Out-File -FilePath C:\warmup.log -Force; : Saves the HTTP response to the file C:\warmup.log. The -Force option ensures the file is created or overwritten if it exists.
  • Error Handling: A try block handles successful execution, and the catch block logs errors if the warm-up process fails.
  • Ports 80: The container exposes port 80, which is used by IIS to serve the application.
apiVersion: v1
kind: Pod
metadata:
name: iis-pod-warmup
spec:
containers:
- name: iis-container
image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2022
lifecycle:
postStart:
exec:
command:
- powershell
- '-Command'
- >
try {
Start-Sleep -Seconds 5; # Wait for IIS to start
Invoke-WebRequest -Uri http://localhost -UseBasicParsing | Out-File -FilePath C:\warmup.log -Force;
Write-Host "Warm-up request completed successfully.";
} catch {
Write-Error "Warm-up request failed: $_";
}
ports:
- containerPort: 80

Output

Conclusion

Kubernetes lifecycle hooks like postStart give developers greater control over container startup behavior. Whether you’re initializing services, warming up applications, or preparing IIS environments, hooks can significantly improve reliability and user experience.

 

Mastering the Kubernetes kubectl Patch Command with Examples in Azure AKS

Managing Kubernetes resources efficiently is essential for scalable cloud-native applications. The kubectl patch command lets you quickly update running Kubernetes resources — such as labels, container images, or replicas — without redeploying entire configurations. In this article, you’ll learn how to use kubectl patch within Azure Kubernetes Service (AKS), complete with practical examples.

What is the kubectl patch Command?

Patch is a command line option for updating Kubernetes API objects. You can use it to update a running configuration. You do this by supplying it with the section to update, instead of a completely new configuration, as you would with kubectl apply.

The command works by “patching” changes onto the current resource configuration. Unlike a kubectl replace operation, the patch operation only modifies specific fields in the resource configuration.

What can we do using Kubectl patch command?

With kubectl patch, you can quickly fix issues with updating the name, image, label, replicas, affinity/tolerations, environment variables, configaps, secrets, volumes, ports, etc. kubectl patch supports YAML and JSON formats. Using either format, you can drill into the specific field of the resource and change it to your desired value. Kubectl supports three different patching strategies: Strategic Merge (the default) and JSON Merge. You utilize these formats through the patching strategy.

“kubectl patch supports three strategies: Strategic Merge Patch (default), JSON Merge Patch, and JSON Patch. Each has different use cases depending on the complexity of your update.”

Sample deployment YAML file

Let’s say we have the following Nginx deployment YAML file, we originally had only one label (environment: prod), and we want to add a new label to specify the app we are running (app: nginx). We will use the –patch command to enter the new labels:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.14.2
          ports:
            - containerPort: 80

Example 1: Patch the label to the deployment

Method 1: Patch using Inline JSON 

In our case, we would like to add environment for the deployment as prod, for this we would run the following command to add the new labels:

kubectl patch deployment nginx-deployment --patch '{\"metadata\": {\"labels\": {\"environment\": \"prod\"}}}'

For the patch command to work, you must correctly include the map and lists in the original YAML file, so Kubernetes knows exactly where to go to add/update the new value properly.

We are going to discuss very simple example of using the kubectl patch command to update fields in your Kubernetes deployment file.

If you want to patch from the YAML file, you can create file with the required update and save as .YAML as shown in below and execute the file using kubectl.

Method 2: Patch using YAML file

“This patch file only contains the section you want to update, not the full deployment manifest.

#Save the file using below manifest (patch.yaml)
metadata:
  labels:
    environment: prod
#execute the command to apply the new changes in the existing pod
kubectl patch deployment nginx-deployment --patch-file ./thi/patch.yaml


You can run the following to check the YAML for the new updates:

#View the YAML in the notpad
kubectl edit deployment nginx-deployment
#View the YAML in the console itself
kubectl get deployment nginx-deployment -o yaml

In return, we get the following YAML file:

Example 2: Patch the label to the Pod level

In this same scenario, if we wanted to update the labels within the Pod template, you would have to drill into the spec field instead of the metadata.

Usually, you would drill into the metadata and spec fields for kubectl patch, but this would also work with other YAML fields, such as status or even a new custom field you created through a CRD (custom resource definition).

In the following example, we are attempting to add a new label environment: prod to the existing labels within the pod template, as the following:

#replace : Modifies the value of an existing field.
#add: Adds/replace a new field or value to an array.
#remove: Removes a field or an element from an array.
#copy: Copies the value of one field to another
#test: Verifies that a specific field has a certain value. The patch operation will fail if the condition is not met
#move: Moves a value from one location to another within the object
kubectl patch deployment nginx-deployment --type='json' --patch='[{"op": "add", "path": "/spec/template/metadata/labels/environment", "value":"prod"}]

The above cmd will be used for both adding new or updating the existing fields. To check if the deployment got the new labels, you can run the following:

kubectl get deployment nginx-deployment --show-labels

Example 3: Update Pod label and container image

We will attempt to update the image of the ingress from older version to new version and update the label value together . This will require us to drill further into the list (the – is a list and will use [ ] to tap into it from the kubectl patch command) instead of a map (uses { }):

kubectl patch deployment nginx-deployment --patch '{\"spec\": {\"template\": {\"metadata\": {\"labels\": {\"environment\": \"production\"}}, \"spec\": {\"containers\": [{\"name\": \"nginx\", \"image\": \"nginx:1.14.2\"}]}}}}'

Conclusion

The kubectl patch command is a versatile tool for managing Kubernetes resources, particularly in dynamic environments like Azure Kubernetes Service. It allows for targeted updates with minimal effort, making it ideal for quick fixes and operational adjustments. By mastering the kubectl patch command, AKS administrators can maintain agility and efficiency in managing their clusters.

Whether you are adding labels, scaling deployments, or updating container images, kubectl patch ensures you can implement changes quickly and confidently. Embrace this command to streamline your Kubernetes workflows and keep your AKS environment optimized.

“Next time you’re troubleshooting or making small updates in AKS, try kubectl patch instead of redeploying. What’s your favorite kubectl command? Drop it in the comments 👇”

Frequently Asked Questions (FAQ)

1. When should I use kubectl patch instead of kubectl apply?

Use kubectl patch when you want to make quick, targeted changes to a Kubernetes resource without redeploying the entire manifest. For example, updating a label, changing an image tag, or adding an environment variable can be done faster with kubectl patch. If you need to manage large or version-controlled manifests, kubectl apply is still the better choice.

2. Can I rollback a kubectl patch?

No, kubectl patch itself does not provide a rollback mechanism. Once applied, the changes are immediately reflected in the resource. To revert, you must either:

  • Manually patch again with the previous values, or

  • Redeploy the original manifest using kubectl apply -f <file.yaml>.
    Using GitOps or storing manifests in source control is recommended to track and revert changes easily.

3. What are common errors with kubectl patch?

Some common errors include:

  • Incorrect JSON/YAML syntax – forgetting quotes, brackets, or commas.

  • Missing path values – targeting the wrong field (e.g., metadata vs spec.template.metadata).

  • Unsupported patch type – not specifying --type=json when using JSON Patch operations.

  • Read-only fields – trying to patch fields like status or metadata.uid, which cannot be modified.

4. Does kubectl patch work for all Kubernetes resources?

Yes, kubectl patch works for most standard Kubernetes resources like Deployments, Pods, Services, ConfigMaps, and Secrets. However, some Custom Resource Definitions (CRDs) may not fully support all patch types depending on their schema.

5. Is kubectl patch safe to use in production?

Yes, but with caution. Since it makes live changes to resources, there is no automatic rollback. It is best used for small, urgent fixes in production. For long-term changes, update your manifests and use kubectl apply to keep your deployments consistent.

 

 

Update AKS Node Pools with Labels: A Comprehensive Guide Using Azure CLI

In today’s dynamic cloud environments, effectively managing your Azure Kubernetes Service (AKS) clusters is paramount. Labels offer a robust mechanism for organizing and optimizing your AKS resources, enabling efficient workload management and cost control. This comprehensive guide will delve into the az aks nodepool update command (azure aks nodepool update), demonstrating how to apply labels to your AKS node pools using the Azure CLI. We’ll explore practical use cases, essential prerequisites, and provide a step-by-step implementation guide.

What is the az aks nodepool update Command?

The az aks nodepool update command is an integral part of the Azure CLI toolkit. In essence, it empowers administrators to update specific properties of an existing AKS node pool. Moreover, utilizing labels with this command enables better management and resource allocation by categorizing node pools for specific workloads.

When to Use ?

This command proves particularly useful in the following scenarios:

  • Workload Segmentation: Assign specific workloads, such as .NET applications, to designated node pools. For example, you can label a node pool as “dotnet” to easily identify nodes suitable for .NET applications.
  • Cost Management: Apply labels to categorize node pools by environments (e.g., production, staging) to track costs more effectively. Consequently, this facilitates accurate cost allocation and budgeting.
  • Efficient Scheduling: Utilize Kubernetes label selectors in deployment manifests to target workloads to specific node pools. As a result, you can optimize resource utilization and improve application performance
  • Cluster Management: Enhance visibility and filtering when managing multiple node pools. In addition, labels simplify cluster management by providing a clear and organized structure.

Prerequisites

Before executing the az aks nodepool update command, ensure the following prerequisites are met:

       1. Azure CLI Installed:

Ensure the Azure CLI is installed and updated to the latest version. You can install it from the Azure CLI Documentation. Verify the installation using: az --version

Verify installation using:  az  –version

       2. Access Permissions:

You must possess the appropriate permissions to manage AKS resources. Typically, you’ll require the Azure Kubernetes Service Contributor or Owner role.

       3. Existing AKS Cluster and Node Pool:

An AKS cluster and the node pool you intend to label must already exist

      4. Resource Details:

Identify the resource group, cluster name, and node pool name.

How to Use the Command

To update labels on an AKS node pool using the Azure CLI, employ the following command:

az aks nodepool update \
  --resource-group <resource-group> \
  --cluster-name <aks-cluster-name> \
  --name <node-pool-name> \
  --labels <key=value>

For instance, to add a label nodepooltype=dotnet to the node pool prdnxpool01 in a production AKS cluster:

az aks nodepool update \
--resource-group rg-apps-prd-01 \
--cluster-name aks-dgtl-app-prd-we-01 \
--name prdnxpool01 \
--labels nodepooltype=dotnet

Command Breakdown

–resource-group: Specifies the resource group of the AKS cluster.
–cluster-name: The name of the AKS cluster.
–name: The name of the node pool to be updated.
–labels: Key-value pairs for the labels to apply to the node pool.

Validating the Update

Once the command executes successfully, you can verify the labels using the following method:

az aks nodepool show \
--resource-group rg-apps-prd-01 \
--cluster-name aks-dgtl-app-prd-we-01 \
--name prdnxpool01

OUTPUT

Conclusion:

In conclusion, effectively labeling AKS node pools is a critical practice for optimizing your Kubernetes workloads, improving resource utilization, and streamlining cluster management. The az aks nodepool update command within the Azure CLI provides a user-friendly and efficient method for applying and managing labels. By implementing the strategies outlined in this guide, you can enhance your AKS cluster’s performance, reduce operational overhead, and gain greater control over your Kubernetes deployments.

For more insights on Kubernetes and Azure, stay tuned to our blog!
Got questions or additional tips? Share them in the comments below!

 

Mastering Kubernetes HPA: How to Filter Horizontal Pod Autoscalers on Linux and Windows

Introduction to Horizontal Pod Autoscalers (HPAs)

In Kubernetes, a Horizontal Pod Autoscaler (HPA) is a critical resource that automatically scales the number of pods in a deployment, replica set, or stateful set based on observed CPU utilization, memory usage, or custom metrics. HPAs ensure that your applications can handle varying workloads efficiently by scaling out (adding more pods) during high demand and scaling in (removing pods) during low demand and another activity to monitor hpa by kubernetes hpa filtering.

When managing Kubernetes clusters, you often need to monitor and filter HPAs across multiple namespaces. For example, you might want to list all HPAs in specific namespaces or filter them based on certain criteria. On Linux, the grep command is commonly used for filtering text output. However, Windows does not natively support grep, so alternative methods are required.

In this article, we’ll explore how to filter kubectl get hpa output on both Linux and Windows systems (kubernetes hpa filtering) , using native tools and third-party utilities.

kubernetes hpa filtering

Filtering kubectl get hpa Output on Linux

Linux systems natively support the grep command, which is a powerful tool for filtering text. Here’s how you can use grep to filter kubectl get hpa output.

Example: Filter HPAs in Specific Namespaces

Suppose you want to list all HPAs in the namespace1 and namespace2 namespaces. You can use the following command:

kubectl get hpa -A -o wide | grep -E 'namespace1|namespace2'

kubectl get hpa -A -o wide | grep -E 'customer|identity'

Explanation:

  • kubectl get hpa -A -o wide: Fetches all HPAs across all namespaces (-A) and displays them in a wide format (-o wide).
  • grep -E ‘namespace1|namespace2’: Filters the output to show only lines containing namespace1 or namespace2.

Filtering kubectl get hpa Output on Windows

Windows does not natively support grep, but you can achieve similar functionality using PowerShell or by installing Unix-like tools.

Option 1: Use PowerShell’s Select-String

PowerShell has a built-in command called Select-String that works similarly to grep.

Example: Filter HPAs for all Namespaces

Fetches all HPAs across all namespaces.

kubectl get hpa -A
kubectl get hpa -A -o wide

Example: Filter HPAs in Specific Namespaces

kubectl get hpa -A -o wide | Select-String -Pattern 'namespace1|namespace2'

kubectl get hpa -A -o wide | Select-String -Pattern 'customer|identity'

Select-String -Pattern ‘namespace1|namespace2’: Filters the output to show only lines containing namespace1 or namespace2.

Option 2: Use findstr & Where-object (Native Windows Command)

Windows has a built-in command called findstr that can be used for basic text filtering.

Example: Filter HPAs in Specific Namespaces

kubectl get hpa -A -o wide | findstr "namespace1 namespace2"

kubectl get hpa -A -o wide | Where-Object { $_ -match 'customer|identity' }

findstr “namespace1 namespace2”: Filters the output to show only lines containing namespace1 or namespace2.

Using grep in Window’s Machine

Windows does not natively support grep, but you can achieve similar functionality using PowerShell or by installing Unix-like tools as shown in below.

choco install grep

Post installation, you can use the grep in you window machine. Ensure you are installing grep by opening the PowerShell console in the Admin mode to have successful installation.

Conclusion

For US-based teams, mastering kubectl HPA filtering and monitoring is essential for cost-efficient, high-performance Kubernetes clusters. By combining Linux/Windows command-line tools with enterprise-grade observability platforms, organizations can achieve seamless autoscaling aligned with industry best practices

 

Step-by-Step Guide: How to Create & Manage Custom Kubernetes Namespaces using Kubectl

Namespace are a foundational concept in Kubernetes that enable logical isolation of resources within a cluster. They allow teams, projects, or environments (e.g., dev, staging, prod) to share the same cluster without interfering with each other. By default, Kubernetes includes system namespaces like default, kube-system, and kube-public, but creating custom namespaces is essential for organizing workloads securely and efficiently. This article explains how to create, manage, and use custom namespaces using kubectl, with detailed examples and best practices.

What Is Kubernetes Namespace?

By using Namespaces, you can separate your cluster into different groups that are isolated from one another. For instance, you can create two separate Namespaces for an application — one for development and one for production. The development Namespace can be used for testing, debugging, and experimentation purposes, while the production Namespace can be used for hosting the stable and publicly accessible version of the application.

When you create a Namespace, any Kubernetes objects such as Pods, Deployments, and DaemonSets that you launch in it will exist exclusively within that Namespace. More importantly, all operations you perform, such as scaling and deleting resources, will only affect the objects in that specific Namespace.

Why Use Kubernetes Namespace?

Imagine a cluster hosting hundreds of applications, each with its own Deployments, ConfigMaps, and Secrets. Without Namespaces, managing these resources becomes chaotic:

Risk of Accidental Changes: Modifying or deleting the wrong resource is easy.

Lack of Visibility: Resources from different teams or projects clutter the same space.

Shared Resource Limits: A single team could monopolize cluster resources.

Namespaces solve these issues by:

  • Grouping Resources: Organize resources by team (e.g., frontend, backend), environment (dev, prod), or function (monitoring, logging).
  • Enforcing Policies: Apply Role-Based Access Control (RBAC) and resource quotas per Namespace.
  • Simplifying Management: Isolate troubleshooting and operations to specific contexts.

Prerequisites

Before creating a Namespace, ensure you have:

  1. A Running Kubernetes Cluster or mini kube for local setups.
  2. kubectl Installed: Configured to communicate with your cluster.

All commands in this guide are tested on Azure Kubernetes cluster

How to Create a Custom Kubernetes Namespace?

With the prerequisites taken care of, creating a custom Namespace in Kubernetes is a simple process. Here’s how you can do it:

Step 1: Check available Namespaces

Open a terminal and run the following command to list all the Namespaces in your cluster:

kubectl get namespaces

This will list all the Namespaces in your cluster, along with their status and age:

You will see a list of Namespaces shown in the console. Note that the Namespaces you’ll see besides the “default” Namespace will vary depending on your cluster configuration. For example, if you run the “kubectl get namespaces” command on a Kubernetes cluster, you’ll get the following output:

You may notice that in addition to the “default” Namespace, some Namespaces appear in both outputs while others are unique to each one. These additional Namespaces are not relevant to our discussion, so you can ignore them. However, understanding the “default” Namespace is important.

By default, all Kubernetes resources are created in the “default” Namespace if no Namespace is specified. The “default” Namespace is created automatically when Kubernetes is installed.

Step 2: Create a Custom Namespace

Run the following command to create a new Kubernetes Namespace called “production”. You can name your Namespace anything you like.

The output shows that the “staging” Namespace has been created successfully. We can verify this by executing the “kubectl get namespaces” command. As you can see, the new Namespace named “staging” is now listed along with the other Namespaces in the cluster. We can now use this Namespace to deploy applications related to lower environment and manage resources.

How to Create a Deployment in a Custom Namespace?

In the previous section, we created a custom Namespace named “staging”.

Now, let we create a Deployment that runs an “nginx” web server inside this Namespace. We can use the “kubectl create deployment” command for creating deployment. However, we need to specify the Namespace using the “-n” or “–namespace” flag, as shown below. Else it will create the deployment in the default namespace.

In this command, we have specified the “nginx” image and the “staging” Namespace using the “-n” flag. We have also given the deployment the name “mynginx”.

kubectl create deployment mynginx --image=nginx -n=production

The output shows that the deployment has been created successfully and you can check the status of the deployment using kubectl get cmdlet with the “-n” flag to list the Deployments in the “production” Namespace.

kubectl get deployment -n staging

As you can see, the “mynginx” Deployment is now running inside the “production” Namespace.

How to Delete a Custom Kubernetes Namespace?

In above steps, we have created a custom Namespace called “staging”, let’s see how we can delete it.

Deleting a Namespace is a simple operation in Kubernetes but we need to more careful before doing this action as it will delete all the resources like deployment/pods will get deleted. We can use the “kubectl delete namespace” command followed by the name of the Namespace we want to delete. Run the following command to delete the “staging” Namespace:

[su_highlight background=”#ffffff” color=”#f91355″]Deleting a namespace removes all resources within it, including Pods, Deployments, ConfigMaps, and Services. Use this command with caution.[/su_highlight]

kubectl delete namespace staging

Here is the output we get after executing the command:

To verify that the “staging” Namespace has been successfully deleted, we can list the available Namespaces in our cluster using the kubectl get namespace command as shown in above step (Step 1: Check available Namespaces):

What Happens When You Delete the Namespace in Kubernetes?

Remember that deleting a Namespace also deletes all the resources created inside it. In our case, we had created a Deployment called “mynginx” inside the “staging” Namespace. Now that we have deleted this Namespace, we have also deleted this “mynginx” Deployment.

Remember to be careful when deleting Namespaces, as it can result in the loss of important resources. Always double-check before performing such operations.

  1. Cascade Deletion: Kubernetes terminates all resources inside the namespace.
    • Pods are gracefully shut down.
    • PersistentVolumes (if not retained) are deleted.
    • Services, Deployments, and Secrets are removed.
  2. Irreversible Action: Once deleted, resources cannot be recovered unless backed up externally.
  3. Finalizers: Some resources may delay deletion if they have finalizers (e.g., waiting for storage cleanup).

Summary

Deleting a namespace is a powerful but irreversible operation. Always verify resources inside the namespace, use dry-run simulations, and ensure backups exist. If a namespace gets stuck, manually removing finalizers can resolve the issue. By following these practices, you minimize the risk of accidental data loss in your Kubernetes cluster.

To limit CPU, memory, or Pod counts per namespace in Kubernetes, you can use Resource Quotas and Limit Ranges. Resource Quotas define hard limits for resource consumption within a namespace, while Limit Ranges enforce minimum and maximum resource constraints on individual Pods or containers. We will discuss more about this deep drive in upcoming article.

How to Copy Files from and to Kubernetes Pods: A Comprehensive Guide for Windows and Linux

Introduction

Azure Kubernetes Service (AKS) is a powerful platform for deploying and managing containerized applications. However, managing files within pods can sometimes be challenging. This article will guide you through the process of Copy File From Pod to Local and upload file from local to pod, covering both Windows and Linux environments. We’ll explore practical examples using kubectl exec and kubectl cp commands, empowering you to effectively manage your AKS deployments. In this article we will have more dig how to Copy Files from and to Kubernetes Pods using windows and Linux pods.

Prerequisites Copy Files from and to Kubernetes

  • Before proceeding, ensure you have the following:
  • Access to an AKS cluster.
  • The kubectl command-line tool installed and configured to interact with your cluster.
  • Basic knowledge of Kubernetes and pod management.

Copying Files to and from Windows Pods

Step 1: Copying Files from a Windows Pod to Local

To copy a file from a Windows pod to your local system, use the kubectl cp command. For instance:

#Syntax :
kubectl cp <pod-name>:<container-path> <local-file-path>

Replace <pod-name> and <container-path> as described above.
Replace <local-file-path> with the desired destination path on your local machine.

#Example: 
kubectl cp sitecore-bg/cdnewbooking-upgrade-8875f7d95-pg4xq:/inetpub/wwwroot/web.config web.config

In this example:

sitecore-bg/cdnewbooking-upgrade-8875f7d95-pg4xq is the pod name.
/inetpub/wwwroot/web.config is the file path inside the pod.
web.config is the destination file on your local system.

Step 2: Copy File From Local to Window Pod

To copy a file from a Windows pod to your local system, use the kubectl cp command. For instance:

#Syntax : 
kubectl cp <local-file-path> <pod-name>:<container-path>

Replace <local-file-path> with the path to the file on your local machine.
Replace <pod-name> with the name of the pod.
Replace <container-path> with the desired destination path within the pod’s container.

#Example: 
kubectl cp web.config sitecore-bg/cdnewbooking-upgrade-8875f7d95-pg4xq:/inetpub/wwwroot/web.config

This command uploads the web.config file to the specified path inside the pod.

web.config is the source file on your local system.
sitecore-bg/cdnewbooking-upgrade-8875f7d95-pg4xq is the pod name.
/inetpub/wwwroot/web.config is the file path inside the pod.

Step 3: Entering & Verify in Windows Pod

To interact directly with a Windows pod, use the kubectl exec command. For example:

Utilize the kubectl exec command to access the PowerShell shell within your Windows pod:

#Syntax : 
kubectl exec -n <namespace> <pod-name> -it -- powershell

Replace <namespace> with the actual namespace of your pod.
Replace <pod-name> with the unique name of the pod.

#Example : 
kubectl exec -n sitecore cd202404232-657b6c6d87-lj7xp -it -- powershell


Copy Files to and From Linux Pods

Step 1: Copying Files from a Linux Pod to local

Use the kubectl cp command to copy files from the pod to your local machine:

#Syntax :
kubectl cp <pod-name>:<container-path> <local-file-path>

To copy a directory from a Linux pod to your local system, use the following command:

#Example: 
kubectl cp solr/solr-leader-202312186-78b759dc5b-8pkrl:/var/solr/data ./solr_data

Here:

solr/solr-leader-202312186-78b759dc5b-8pkrl is the pod name.
/var/solr/data is the directory path inside the pod.
./solr_data is the destination directory on your local machine.

Step 2: Copying Files to a Linux Pod

Use the kubectl cp command to copy files from your local machine to the pod:

#Syntax :
kubectl cp <local-file-path> <pod-name>:<container-path>

To upload files or directories to a Linux pod, use:

#Example: 
kubectl cp solr/solr-leader-202312186-78b759dc5b-8pkrl:/var/solr/data ./solr_data

This command copies the solr_data directory from the specified Linux pod to your current local directory.

Step 3: Entering & Verify in a Linux Pod

Utilize the kubectl exec command to access the bash shell within your Linux pod:

#Syntax : Replace <namespace> and <pod-name> as described above.
kubectl exec -it <pod-name> -n <namespace> -- bash

For Linux-based pods, start a bash session using: This opens a bash shell inside the Linux pod.

#Example: 
kubectl exec -it solr-leader-202312186-78b759dc5b-8pkrl -n solr -- bash

FAQ

1. How do I find the name of a pod in my cluster?

Run kubectl get pods -n <namespace>. This will list all pods in the specified namespace along with their statuses.

2. Can I copy entire directories between my system and a pod?

Yes, the kubectl cp command supports copying directories. Use the directory path in the source and destination arguments.

3. Why do I get a “permission denied” error when copying files?

This typically happens due to insufficient permissions in the pod’s file system. Verify the access rights of the target directory or file.

4. What happens if I specify an incorrect file path inside the pod?

The kubectl cp command will fail and display an error stating that the specified path does not exist.

5. Can I use kubectl cp with compressed files?

Yes, you can use kubectl cp to transfer compressed files. However, you may need to extract or compress them manually before or after the transfer.

6. Is it possible to copy files between two pods directly?

No, kubectl cp does not support direct pod-to-pod file transfers. Copy the files to your local system first and then upload them to the target pod.

7. How do I check if a file was successfully copied?

After copying, use kubectl exec to enter the pod and verify the file’s existence in the target directory.

8. Does kubectl cp work with all storage classes?

Yes, kubectl cp works regardless of the underlying storage class since it operates at the pod file system level.

Conclusion

Copying files to and from AKS pods is a vital skill for efficiently managing your Kubernetes environment. By following the examples provided for both Windows and Linux pods, you can streamline your workflow and tackle common tasks with ease. Bookmark this guide for future reference and elevate your Kubernetes management expertise.

With AKS becoming a preferred choice for enterprises in the United States, mastering these commands ensures you’re equipped to handle file operations effortlessly. Have questions or additional tips? Share them in the comments below!