Kubernetes Labels, Resource Limits and Init Containers for CKAD
Learn labels, selectors, resource limits, OOMKilled, init containers and CRDs through hands-on AKS labs for CKAD prep.

π Hi! Iβm Dani, a passionate automation, Ansible, DevOps, and Cloud technologies enthusiast. I currently work as a Middleware Solutions Architect at Atradius, leading middleware automation and optimizing IT infrastructure. π‘ My Story: I started my career specializing in Oracle Middleware, working with technologies such as WebLogic, Oracle Database, Oracle iPlanet Web Server, and Oracle JDK. Over time, my focus shifted towards deployment automation, continuous integration, and process optimization in complex enterprise environments. π Impact & Achievements: β Direct the automation of Oracle Fusion Middleware (FMW) with Ansible, streamlining the installation, configuration, and patching processes for Oracle WebLogic, SOA Suite, and OSB. β Lead IBM WebSphere Application Server (WAS) automation with Ansible and AWX, including installation, configuration, certificates, and deployments, reducing implementation times by 70%. β Integrated Azure DevOps with AWX, eliminating manual deployment tasks and reducing human intervention to a simple approval step. β Mentor and train teams on Ansible automation, fostering continuous improvement and knowledge transfer. ππ₯ In my free time, I enjoy playing padel and basketball, always looking for new challenges and improvements, both in sports and technology. I also love building web applications with Oracle APEX, bringing ideas to life through low-code development. π₯ Letβs connect! π§ Email: dbenitez.vk@gmail.com π LinkedIn: https://www.linkedin.com/in/danielbenitezaguila π» GitHub: https://github.com/dbeniteza
Introduction
This part of my CKAD studies focused on how Kubernetes manages resources, identifies workloads, initializes applications, and extends the Kubernetes API.
These topics are common in real-world troubleshooting and frequently appear in CKAD scenarios. Through hands-on AKS exercises, I explored labels, selectors, resource requests and limits, init containers, and Custom Resource Definitions (CRDs).
Understanding Labels and Selectors
Labels are key-value pairs attached to Kubernetes resources.
Create a Deployment:
kubectl create deployment design --image=nginx
deployment.apps/design created
kubectl get deployments.apps design -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
design 1/1 1 1 30s nginx nginx app=design
View Pods using a selector:
kubectl get -l app=design pod
NAME READY STATUS RESTARTS AGE
design-6c5dcd6c46-xnl9l 1/1 Running 0 64s
Labels allow Kubernetes to:
Group resources
Identify workloads
Connect Services to Pods
Enable filtering and automation Lesson learned:
Labels are one of the most important building blocks in Kubernetes.
What Happens When a Pod Label Changes?
An interesting experiment involved manually changing the label of a Deployment-managed Pod.
After modifying the label, the Pod no longer matched the Deployment selector.
Kubernetes immediately created a replacement Pod.
Result:
Original Pod (modified label)
+
New Pod (matching Deployment selector)
This demonstrates the reconciliation loop that continuously drives the cluster toward its desired state.
Working with Selectors
Selectors make it easy to target groups of resources. Having the following YAML file:
apiVersion: v1
kind: List
items:
- apiVersion: v1
kind: Pod
metadata:
labels:
team: security
name: label-pod1
spec:
containers:
- image: nginx
name: web-a
- apiVersion: v1
kind: Pod
metadata:
labels:
team: security
name: label-pod2
spec:
containers:
- image: nginx
name: web-b
- apiVersion: v1
kind: Pod
metadata:
labels:
linux: rhel
name: label-pod3
spec:
containers:
- image: nginx
name: web-c
- apiVersion: v1
kind: Pod
metadata:
labels:
domain: apps
name: label-pod4
spec:
containers:
- image: nginx
name: web-d
Find Pods:
kubectl get --selector team=security pod
NAME READY STATUS RESTARTS AGE
label-pod1 1/1 Running 0 2m4s
label-pod2 1/1 Running 0 2m4s
Delete Pods using labels:
kubectl delete --selector domain=apps pod
pod "label-pod4" deleted from default namespace
kubectl delete --selector linux=rhel pod
pod "label-pod3" deleted from default namespace
This is a powerful technique for managing multiple resources at once.
Resource Requests and Limits
One of the most valuable exercises involved resource management.
Example:
spec:
containers:
- image: vish/stress
imagePullPolicy: Always
name: stressmeout
resources:
limits:
cpu: "1"
memory: "1Gi"
requests:
cpu: "0.5"
memory: "500Mi"
args:
- -cpus
- "2"
- -mem-total
- "1950Mi"
- -mem-alloc-size
- "100Mi"
- -mem-alloc-sleep
- "1s"
Definition:
Requests represent guaranteed resources.
Limits represent maximum allowed resources. Kubernetes uses requests for scheduling decisions and limits for runtime enforcement.
Kubernetes uses requests for scheduling decisions and limits for runtime enforcement.
Understanding OOMKilled
To test resource enforcement, a stress container attempted to consume more memory than allowed. Pod status: OOMKilled
This occurs when a container exceeds its memory limit. Lesson learned:
CPU can be throttled.
Memory cannot.
Exceeding memory limits frequently results in OOMKilled. This is one of the most common production incidents in Kubernetes.
This is one of the most common production incidents in Kubernetes.
kubectl create -f stress.yaml
deployment.apps/stress created
kubectl get pod
NAME READY STATUS RESTARTS AGE
stress-74fb49bffd-ccsbq 0/1 OOMKilled 0 17s
kubectl logs stress-74fb49bffd-ccsbq
I0622 15:06:58.615747 1 main.go:26] Allocating "1950Mi" memory, in "100Mi" chunks, with a 1s sleep between allocations
I0622 15:06:58.615802 1 main.go:39] Spawning a thread to consume CPU
I0622 15:06:58.615807 1 main.go:39] Spawning a thread to consume CPU
Understanding Init Containers
Init containers execute before application containers start.
Example:
apiVersion: v1
kind: Pod
metadata:
name: init-tester
labels:
app: inittest
spec:
containers:
- name: webservice
image: nginx
initContainers:
- name: failed
image: busybox
command: [/bin/false]
kubectl create -f init-tester.yaml
pod/init-tester created
kubectl get pod
NAME READY STATUS RESTARTS AGE
init-tester 0/1 Init:Error 2 (20s ago) 22s
kubectl logs init-tester
Defaulted container "webservice" out of: webservice, failed (init)
Error from server (BadRequest): container "webservice" in pod "init-tester" is waiting to start: PodInitializing
The Pod remained stuck in Init:Error, because the init container failed immediately. Checking status and logs helped identify the failure.
Key Takeaways
The review exercises combined several concepts:
Resource requests and limits
Label filtering
Bulk resource deletion
OOMKilled troubleshooting
Init container debugging
The combination of these topics closely resembles real CKAD troubleshooting scenarios.



