Namespaces: Organizing Workloads
Namespaces help organize Kubernetes resources inside a cluster. They are useful for separating teams, applications, environments, and lab work — but they are not the same thing as strong security isolation by themselves.
What this lesson covers
So far, most of our labs used the default namespace. That is fine for early learning, but real clusters need better organization. Namespaces provide a way to group related resources inside the same Kubernetes cluster.
By the end of this lesson, you should understand:
- What a Namespace is
- What Namespaces are good for
- What Namespaces do not solve by themselves
- How to list existing Namespaces
- How to create a Namespace
- How to deploy resources into a specific Namespace
- How to query resources across all Namespaces
- How to set a default Namespace for your current context
- How Services resolve across Namespaces
- How to clean up a Namespace and everything inside it
The short version
A Namespace is a logical grouping of Kubernetes resources inside a cluster.
Instead of putting every Pod, Deployment, Service, ConfigMap, and Secret into the same space, you can separate them:
default kube-system training dev test prod team-a team-b
Each Namespace can contain resources with the same names as resources in another Namespace.
For example, this is allowed:
dev/nginx test/nginx prod/nginx
The name nginx can exist in multiple Namespaces because the full identity includes the Namespace.
Why Namespaces matter
Namespaces help reduce confusion as clusters grow.
They are commonly used to separate:
- Applications
- Teams
- Environments
- Lab work
- System components
- Temporary test workloads
Without Namespaces, everything ends up in the same default bucket. That becomes hard to read, hard to manage, and easy to accidentally change.
What Namespaces are not
Namespaces are not the same as separate clusters.
They do not automatically provide:
- Strong network isolation
- Separate node pools
- Separate administrators
- Separate etcd databases
- Automatic security boundaries
- Automatic resource limits
Those controls require additional configuration.
Namespace-scoped vs cluster-scoped resources
Many Kubernetes resources live inside a Namespace.
Namespace-scoped resources include:
- Pods
- Deployments
- ReplicaSets
- Services
- ConfigMaps
- Secrets
- Ingress resources
Some resources are cluster-scoped and do not belong to a single Namespace.
Cluster-scoped resources include:
- Nodes
- Namespaces
- PersistentVolumes
- ClusterRoles
- ClusterRoleBindings
- StorageClasses
This matters because some commands need a Namespace and others do not.
Before you start the lab
This lab assumes:
- Docker Desktop is running
- Your kind cluster exists
- kubectl is installed
- Your current context is kind-stealth-k8s-lab
Check your context:
kubectl config current-context
You should see:
kind-stealth-k8s-lab
Check your node:
kubectl get nodes
If your cluster no longer exists, recreate it:
kind create cluster --name stealth-k8s-lab
Step 1: List existing Namespaces
Run:
kubectl get namespaces
You will usually see Namespaces like:
default kube-node-lease kube-public kube-system local-path-storage
What these are
- default: The default place for resources if you do not specify a Namespace.
- kube-system: System components often run here.
- kube-public: A Namespace intended for publicly readable cluster information.
- kube-node-lease: Used for node heartbeat lease objects.
- local-path-storage: Often present in kind for local storage support.
Step 2: See resources across all Namespaces
Run:
kubectl get pods -A
The -A flag means all Namespaces.
You can also run:
kubectl get services -A kubectl get deployments -A
This is useful when you are not sure where something exists.
Step 3: Create a Namespace
Create a Namespace for this lab:
kubectl create namespace training-lab
Confirm it exists:
kubectl get namespaces
You should see training-lab in the list.
Step 4: Create a Deployment in the Namespace
Create a Deployment inside the training-lab Namespace:
kubectl create deployment namespace-web-lab --image=nginx:latest -n training-lab
The -n flag means Namespace.
Check Deployments in the default Namespace:
kubectl get deployments
You should not see namespace-web-lab there.
Now check the training-lab Namespace:
kubectl get deployments -n training-lab
You should see the Deployment.
Step 5: Check Pods in the Namespace
Run:
kubectl get pods -n training-lab
You should see the Pod created by the Deployment.
You can also check across all Namespaces:
kubectl get pods -A
Now you should see the Pod listed under the training-lab Namespace.
Step 6: Create a Service in the Namespace
Expose the Deployment with a Service inside the same Namespace:
kubectl expose deployment namespace-web-lab --port=80 --target-port=80 --type=ClusterIP -n training-lab
Check Services in the Namespace:
kubectl get services -n training-lab
Check endpoints:
kubectl get endpoints -n training-lab
You should see endpoints for the Service.
Step 7: Port-forward to the Service in the Namespace
Run:
kubectl port-forward -n training-lab service/namespace-web-lab 8080:80
Keep that PowerShell window open. Then open a browser and go to:
http://localhost:8080
You should see the nginx welcome page.
Press Ctrl+C in PowerShell to stop port-forwarding.
Step 8: Create the same resource name in another Namespace
Create another Namespace:
kubectl create namespace training-lab-2
Now create another Deployment with the same name, but in the second Namespace:
kubectl create deployment namespace-web-lab --image=httpd:latest -n training-lab-2
This works because resource names only need to be unique within the same Namespace.
Check both:
kubectl get deployments -n training-lab kubectl get deployments -n training-lab-2
Both Namespaces can have a Deployment named namespace-web-lab.
Step 9: Use a Namespace in YAML
You can specify a Namespace in a resource manifest.
Create a file named:
namespace-configmap-lab.yaml
Paste this into the file:
apiVersion: v1 kind: ConfigMap metadata: name: namespace-config-lab namespace: training-lab data: APP_MODE: namespace-training LOG_LEVEL: info
Apply it:
kubectl apply -f namespace-configmap-lab.yaml
Check ConfigMaps in the default Namespace:
kubectl get configmaps
You should not see it there.
Check ConfigMaps in training-lab:
kubectl get configmaps -n training-lab
You should see namespace-config-lab.
Step 10: Set the default Namespace for your current context
Typing -n training-lab repeatedly can get annoying. You can set the default Namespace for your current kubectl context:
kubectl config set-context --current --namespace=training-lab
Now run:
kubectl get pods kubectl get services kubectl get configmaps
kubectl will use training-lab by default for namespace-scoped resources.
Confirm the current Namespace
Run:
kubectl config view --minify --output 'jsonpath={..namespace}'
You should see:
training-lab
Step 11: Reset the default Namespace back to default
Before we finish, set your current context back to the default Namespace:
kubectl config set-context --current --namespace=default
Confirm:
kubectl config view --minify --output 'jsonpath={..namespace}'
You should see:
default
Step 12: Understand service DNS across Namespaces
Kubernetes provides DNS names for Services.
Inside the same Namespace, a workload can usually reach a Service by short name:
namespace-web-lab
From another Namespace, it is safer to use a more complete name:
namespace-web-lab.training-lab.svc.cluster.local
The pattern is:
<service-name>.<namespace>.svc.cluster.local
You do not need to memorize every DNS detail right now. The key idea is that Namespace affects service discovery.
Step 13: Describe a Namespace
Run:
kubectl describe namespace training-lab
You may see labels, annotations, and status information. Later, when we cover quotas and policies, this view becomes more useful.
Step 14: Delete a Namespace and everything inside it
Deleting a Namespace deletes the namespace-scoped resources inside it.
Delete the first lab Namespace:
kubectl delete namespace training-lab
Delete the second lab Namespace:
kubectl delete namespace training-lab-2
Check Namespaces:
kubectl get namespaces
It may take a little time for the Namespaces to fully terminate.
Why this is useful
Namespaces are convenient for labs because you can place all related resources into a Namespace and then delete the Namespace to clean up most of the lab.
Common Namespace troubleshooting commands
Use this flow when you cannot find a resource or suspect you are looking in the wrong place:
kubectl config current-context
kubectl config view --minify --output 'jsonpath={..namespace}'
kubectl get namespaces
kubectl get pods
kubectl get pods -A
kubectl get deployments -A
kubectl get services -A
kubectl get configmaps -A
kubectl describe namespace <namespace-name>
This usually tells you:
- Which cluster kubectl is pointed at
- Which Namespace kubectl uses by default
- Whether the Namespace exists
- Whether the resource exists in another Namespace
- Whether you accidentally created something in default
Common Namespace mistakes
Looking only in default
If you run kubectl get pods without a Namespace, you may only see resources in your current default Namespace.
Forgetting the current default Namespace was changed
If you set a default Namespace for your context, kubectl will keep using it until you change it again.
Assuming Namespaces provide full isolation
Namespaces organize resources, but security isolation requires additional controls.
Deleting the wrong Namespace
Deleting a Namespace can delete many resources at once. Be careful in shared or production clusters.
Where Namespaces fit in real environments
In real clusters, Namespaces are often paired with:
- RBAC: Controls who can do what inside a Namespace.
- ResourceQuotas: Limit how much CPU, memory, or object count a Namespace can consume.
- LimitRanges: Apply default or maximum resource limits.
- NetworkPolicies: Control allowed network traffic.
- Pod Security Standards: Restrict risky Pod behavior.
- Admission policies: Enforce cluster rules when resources are created or updated.
We will cover these later. For now, focus on how Namespaces organize resources and affect kubectl commands.
What you just learned
In this lesson, you:
- Listed existing Namespaces
- Viewed resources across all Namespaces
- Created Namespaces
- Created Deployments and Services inside specific Namespaces
- Created duplicate resource names in different Namespaces
- Used Namespace metadata in YAML
- Changed the default Namespace for your current context
- Reset the default Namespace back to default
- Learned how Namespace affects Service DNS
- Deleted Namespaces to clean up lab resources
Check your understanding
Use these questions to test whether the Namespace concepts made sense.
- What does a Namespace do in Kubernetes?
- Can two different Namespaces contain resources with the same name?
- What flag tells kubectl which Namespace to use?
- What does -A mean in kubectl get pods -A?
- Name two resources that are usually namespace-scoped.
- Name two resources that are cluster-scoped.
- Why can deleting a Namespace be dangerous?
- What command sets the default Namespace for the current context?
- Why should you reset your default Namespace after a lab?
- What is the full DNS pattern for a Service across Namespaces?
- Are Namespaces complete security boundaries by themselves?
- What are three controls commonly paired with Namespaces in real environments?
Answer key
- A Namespace logically groups Kubernetes resources inside a cluster.
- Yes, as long as the resources are in different Namespaces.
- -n or --namespace.
- All Namespaces.
- Examples: Pods, Deployments, Services, ConfigMaps, Secrets, Ingress resources.
- Examples: Nodes, Namespaces, PersistentVolumes, ClusterRoles, ClusterRoleBindings, StorageClasses.
- Because deleting a Namespace deletes the namespace-scoped resources inside it.
- kubectl config set-context --current --namespace=<namespace-name>.
- To avoid accidentally running future commands in the wrong Namespace.
- <service-name>.<namespace>.svc.cluster.local.
- No. They need additional controls to act as meaningful security boundaries.
- Examples: RBAC, ResourceQuotas, LimitRanges, NetworkPolicies, Pod Security Standards, and admission policies.