Namespaces
As your Kubernetes cluster grows with multiple teams and applications, you need a way to organize and isolate resources. Namespaces provide a mechanism for dividing cluster resources between multiple users, teams, or projects.
What is a Namespace?
A Namespace is a virtual cluster within a physical Kubernetes cluster. It provides:
- Resource isolation — separate workloads logically
- Name scoping — the same resource name can exist in different namespaces
- Access control — apply RBAC policies per namespace
- Resource quotas — limit CPU/memory per namespace
Think of namespaces like folders on a computer — they organize and separate resources without needing separate clusters.
Default Namespaces
Every Kubernetes cluster comes with four namespaces:
| Namespace | Purpose |
|---|---|
| default | Where resources go if no namespace is specified |
| kube-system | Kubernetes system components (API server, scheduler, etc.) |
| kube-public | Publicly readable data (cluster info, ConfigMaps) |
| kube-node-lease | Node heartbeat data for node health monitoring |
# List all namespaces
kubectl get namespaces
# or: kubectl get ns
Output:
NAME STATUS AGE
default Active 2d
kube-node-lease Active 2d
kube-public Active 2d
kube-system Active 2d
Creating Namespaces
Imperative
kubectl create namespace development
kubectl create namespace staging
kubectl create namespace production
Declarative
apiVersion: v1
kind: Namespace
metadata:
name: development
labels:
environment: dev
team: platform
kubectl apply -f namespace.yaml
Working with Namespaces
Specify Namespace in Commands
# Create a Deployment in a specific namespace
kubectl create deployment nginx --image=nginx -n development
# List Pods in a namespace
kubectl get pods -n development
# List Pods across ALL namespaces
kubectl get pods --all-namespaces
# or: kubectl get pods -A
Specify Namespace in YAML
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: development # ← specify namespace here
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27
Set Default Namespace
Tired of typing -n development every time? Set a default:
# Set default namespace for current context
kubectl config set-context --current --namespace=development
# Verify
kubectl config view --minify | grep namespace
# Now all commands default to "development"
kubectl get pods # Shows Pods in "development" namespace
Cross-Namespace Communication
Pods in different namespaces can communicate using the full DNS name:
<service-name>.<namespace>.svc.cluster.local
# Pod in "development" namespace accessing a service in "production"
curl http://api-service.production.svc.cluster.local
# Short form (within the same cluster)
curl http://api-service.production
Important: Namespaces don’t provide network isolation by default. Any Pod can talk to any other Pod across namespaces. To enforce network isolation, use Network Policies (covered in Chapter 17).
Resource Quotas
Limit the total resources a namespace can consume:
apiVersion: v1
kind: ResourceQuota
metadata:
name: dev-quota
namespace: development
spec:
hard:
pods: "20"
requests.cpu: "4"
requests.memory: "8Gi"
limits.cpu: "8"
limits.memory: "16Gi"
services: "10"
persistentvolumeclaims: "5"
kubectl apply -f quota.yaml
# Check quota usage
kubectl describe resourcequota dev-quota -n development
LimitRanges
Set default resource requests/limits for Pods in a namespace:
apiVersion: v1
kind: LimitRange
metadata:
name: dev-limits
namespace: development
spec:
limits:
- type: Container
default: # Default limits
cpu: "500m"
memory: "256Mi"
defaultRequest: # Default requests
cpu: "100m"
memory: "128Mi"
max: # Maximum allowed
cpu: "2"
memory: "1Gi"
min: # Minimum required
cpu: "50m"
memory: "64Mi"
This ensures every Pod in the development namespace has resource constraints, even if the developer forgets to set them.
Namespace-Scoped vs. Cluster-Scoped Resources
Not all Kubernetes resources live inside a namespace:
Namespace-scoped (exist within a namespace):
- Pods, Deployments, Services, ConfigMaps, Secrets, ReplicaSets, Jobs, Ingress
Cluster-scoped (exist cluster-wide):
- Nodes, Namespaces, PersistentVolumes, ClusterRoles, ClusterRoleBindings, StorageClasses
# See all namespace-scoped resources
kubectl api-resources --namespaced=true
# See all cluster-scoped resources
kubectl api-resources --namespaced=false
Best Practices
Namespace Strategy for Organizations
| Pattern | Example | When to Use |
|---|---|---|
| By environment | dev, staging, prod |
Simple applications |
| By team | team-alpha, team-beta |
Multi-team organizations |
| By project | project-x, project-y |
Multi-project clusters |
| Combined | team-alpha-dev, team-alpha-prod |
Large organizations |
Naming Conventions
# Good
kubectl create ns frontend-dev
kubectl create ns backend-staging
kubectl create ns data-pipeline-prod
# Avoid
kubectl create ns my-stuff # Not descriptive
kubectl create ns PRODUCTION # Must be lowercase
kubectl create ns a # Too short
Clean Up
# Delete a namespace (deletes ALL resources inside it!)
kubectl delete namespace development
Warning: Deleting a namespace removes everything in it — Pods, Deployments, Services, ConfigMaps, Secrets — all gone. Be very careful in production.
Summary
- Namespaces provide logical isolation within a cluster
- Use them to separate environments, teams, or projects
- Resource Quotas limit total resource usage per namespace
- LimitRanges set default resource constraints for Pods
- Cross-namespace communication works via DNS:
<service>.<namespace>.svc.cluster.local - Namespaces don’t enforce network isolation by default (use Network Policies)
What’s Next?
Now let’s learn about ConfigMaps — a way to externalize configuration from your application code, making your containers truly portable.