Kubernetes Level 01 Day 03: Resource Isolation Using Namespaces and Targeted Pod Deployment¶
This document explains how a dedicated Namespace was created and how a Pod was deployed inside it. The purpose of this task is to understand logical isolation inside a Kubernetes cluster and to ensure that workloads are placed intentionally rather than relying on the default namespace.
The objective required the following:
- Namespace name:
dev - Pod name:
dev-nginx-pod - Image:
nginx:latest
The important concept here is that namespaces act as isolation boundaries. Resources must be explicitly created inside them.
- Kubernetes Level 01 Day 03: Resource Isolation Using Namespaces and Targeted Pod Deployment
- Understanding Namespaces Before Creating Them
- Step 1: Create the Namespace
- Step 2: Deploy the Pod Inside the Namespace
- Step 3: Verify Pod Placement and Status
- Demonstrating Namespace Isolation Behavior
- Setting a Default Namespace for kubectl Context
- Deleting Resources
- Internal Mechanics of Namespaces
- Final State After Completion
Understanding Namespaces Before Creating Them¶
A Kubernetes cluster is shared infrastructure. Multiple teams, environments, or applications may run inside the same cluster. Without namespaces, all resources exist in a single global space, which leads to naming conflicts and management complexity.
Namespaces provide:
- Logical separation of resources
- Isolation of object names
- Independent management scope
- Foundation for resource quotas and access control
If no namespace is specified when creating resources, Kubernetes places them in the default namespace automatically.
Step 1: Create the Namespace¶
Before deploying anything into dev, the namespace must exist.
Imperative Method¶
kubectl create namespace dev
Expected output:
namespace/dev created
Verify namespace creation:
kubectl get namespaces
# OUTPUT
NAME STATUS AGE
default Active 30m
dev Active 83s
kube-node-lease Active 30m
kube-public Active 30m
kube-system Active 30m
local-path-storage Active 30m
You should see dev listed alongside default system namespaces such as default, kube-system, and kube-public.
Declarative Method (Infrastructure as Code)¶
Create a YAML file.
vi namespace.yaml
Add the following content.
apiVersion: v1
kind: Namespace
metadata:
name: dev
Apply it:
kubectl apply -f namespace.yaml
Using YAML allows version control and reproducibility of environment setup.
Step 2: Deploy the Pod Inside the Namespace¶
Once the namespace exists, the Pod must explicitly target it.
Imperative Method¶
kubectl run dev-nginx-pod --image=nginx:latest -n dev
# OUTPUT
pod/dev-nginx-pod created
The -n dev flag tells the API server to create this Pod inside the dev namespace instead of default.
Internally, the API server stores this Pod object under the namespace key in etcd. Namespaces are implemented as logical prefixes in Kubernetes object storage.
Declarative Method¶
Create a file named dev-pod.yaml.
vi dev-pod.yaml
Insert the following configuration.
apiVersion: v1
kind: Pod
metadata:
name: dev-nginx-pod
namespace: dev
spec:
containers:
- name: dev-nginx-container
image: nginx:latest
Apply it:
kubectl apply -f dev-pod.yaml
By specifying namespace: dev under metadata, we bind the Pod to that namespace explicitly.
Step 3: Verify Pod Placement and Status¶
If you check Pods without specifying namespace:
kubectl get pods
You may see no results because this command defaults to the default namespace.
Now check inside dev:
kubectl get pods -n dev
Expected output:
NAME READY STATUS RESTARTS AGE
dev-nginx-pod 1/1 Running 0 10s
To confirm deeper configuration:
kubectl describe pod dev-nginx-pod -n dev
# OUTPUT:
Name: dev-nginx-pod
Namespace: dev
Priority: 0
Service Account: default
Node: kodekloud-control-plane/172.17.0.2
Start Time: Sat, 14 Feb 2026 05:17:47 +0000
Labels: run=dev-nginx-pod
Annotations: <none>
Status: Running
IP: 10.244.0.5
IPs:
IP: 10.244.0.5
Containers:
dev-nginx-pod:
Container ID: containerd://95496463bc694e2548d58e088c1d8dfb433d08e2086b360b58d56ab5564ce577
Image: nginx:latest
Image ID: docker.io/library/nginx@sha256:341bf0f3ce6c5277d6002cf6e1fb0319fa4252add24ab6a0e262e0056d313208
Port: <none>
Host Port: <none>
State: Running
Started: Sat, 14 Feb 2026 05:17:55 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-x5sx2 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-x5sx2:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m8s default-scheduler Successfully assigned dev/dev-nginx-pod to kodekloud-control-plane
Normal Pulling 2m8s kubelet Pulling image "nginx:latest"
Normal Pulled 2m1s kubelet Successfully pulled image "nginx:latest" in 7.061660581s (7.061676706s including waiting)
Normal Created 2m1s kubelet Created container dev-nginx-pod
Normal Started 2m kubelet Started container dev-nginx-pod
To check across all namespaces:
kubectl get pods -A
# OUTPUT:
NAMESPACE NAME READY STATUS RESTARTS AGE
dev dev-nginx-pod 1/1 Running 0 2m42s
kube-system coredns-5d78c9869d-6kxdw 1/1 Running 0 31m
kube-system coredns-5d78c9869d-zkz9q 1/1 Running 0 31m
kube-system etcd-kodekloud-control-plane 1/1 Running 0 31m
kube-system kindnet-k9xz4 1/1 Running 0 31m
kube-system kube-apiserver-kodekloud-control-plane 1/1 Running 0 32m
kube-system kube-controller-manager-kodekloud-control-plane 1/1 Running 0 31m
kube-system kube-proxy-9m67t 1/1 Running 0 31m
kube-system kube-scheduler-kodekloud-control-plane 1/1 Running 0 32m
local-path-storage local-path-provisioner-6bc4bddd6b-sc5zh 1/1 Running 0 31m
This shows a cluster-wide view.
Demonstrating Namespace Isolation Behavior¶
Try creating another Pod with the same name in the default namespace:
kubectl run dev-nginx-pod --image=nginx:latest
This will succeed because names are unique only within a namespace, not across the entire cluster.
Now verify:
kubectl get pods -A
You will observe two Pods with identical names but in different namespaces.
This proves that namespaces prevent naming collisions.
Setting a Default Namespace for kubectl Context¶
To avoid using -n dev repeatedly, configure the current context.
kubectl config set-context --current --namespace=dev
Now run:
kubectl get pods
The command automatically queries the dev namespace.
To revert back:
kubectl config set-context --current --namespace=default
Deleting Resources¶
To delete the Pod:
kubectl delete pod dev-nginx-pod -n dev
To delete the entire namespace:
kubectl delete namespace dev
Deleting a namespace removes all resources contained within it.
Internal Mechanics of Namespaces¶
Namespaces do not create separate physical clusters. All resources still run on the same worker nodes. The isolation is logical and enforced by the API server.
Each object is stored under a namespace key in etcd. When queries are made, Kubernetes filters results based on namespace context.
Namespaces also serve as a boundary for:
- Resource quotas
- Network policies
- Role-Based Access Control (RBAC)
They are foundational for multi-tenant cluster environments.
Final State After Completion¶
At the end of this setup:
- Namespace
devexists - Pod
dev-nginx-podruns insidedev - The image
nginx:latestis deployed - Isolation from the
defaultnamespace is confirmed - Namespace context behavior is understood
This task establishes the foundation for environment separation inside Kubernetes clusters, which is essential for development, staging, and production segregation.