Namespaces are the first real boundary most Kubernetes teams use. They do not create separate clusters, but they give you a clean scope for names, RBAC, quotas, policies, and team ownership.
What are Namespaces?
Namespaces are a way to divide cluster resources between multiple users, teams, or applications. They provide scope for names and can be used as a mechanism for isolating resources, implementing access controls, and managing resource quotas.
Namespace vs Cluster
Single Namespace (Default):
┌─────────────────────────────────────┐
│ Default Namespace │
│ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │App1 │ │App2 │ │App3 │ │App4 │ │
│ └─────┘ └─────┘ └─────┘ └─────┘ │
└─────────────────────────────────────┘
All resources mixed together
Multiple Namespaces:
┌─────────────────────────────────────┐
│ Production Namespace │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │App1 │ │App2 │ │App3 │ │
│ └─────┘ └─────┘ └─────┘ │
├─────────────────────────────────────┤
│ Development Namespace │
│ ┌─────┐ ┌─────┐ │
│ │App4 │ │App5 │ │
│ └─────┘ └─────┘ │
├─────────────────────────────────────┤
│ Monitoring Namespace │
│ ┌─────┐ │
│ │App6 │ │
│ └─────┘ │
└─────────────────────────────────────┘
Resources organized and isolated
Key Namespace Benefits
- Resource Isolation: Separate resources between teams/projects
- Access Control: Implement RBAC per namespace
- Resource Management: Set quotas and limits per namespace
- Organization: Logical grouping of related resources
- Multi-tenancy: Support multiple teams on same cluster
Default Namespaces
Kubernetes comes with several pre-created namespaces:
# List all namespaces
kubectl get namespaces
kubectl get ns # Short form
# Expected output:
NAME STATUS AGE
default Active 10d
kube-system Active 10d
kube-public Active 10d
kube-node-lease Active 10d
Built-in Namespaces
- default: Default namespace for resources without explicit namespace
- kube-system: Kubernetes system components and add-ons
- kube-public: Public resources accessible to all users
- kube-node-lease: Node lease objects for heartbeats
Creating and Managing Namespaces
Creating Namespaces
# Create namespace imperatively
kubectl create namespace production
kubectl create namespace development
kubectl create namespace monitoring
# Create via YAML
kubectl apply -f namespace.yaml
# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
environment: production
team: backend
---
apiVersion: v1
kind: Namespace
metadata:
name: development
labels:
environment: development
team: backend
---
apiVersion: v1
kind: Namespace
metadata:
name: monitoring
labels:
environment: production
team: platform
Working with Namespaces
# Set default namespace for current context
kubectl config set-context --current --namespace=production
# Create resources in specific namespace
kubectl create deployment webapp --image=myapp:v1.0 -n production
# Get resources from specific namespace
kubectl get pods -n production
kubectl get services -n development
# Get resources from all namespaces
kubectl get pods --all-namespaces
kubectl get pods -A # Short form
# Describe namespace
kubectl describe namespace production
Resource Quotas and Limits
Resource Quotas
# resource-quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: production-quota
namespace: production
spec:
hard:
requests.cpu: "10"
requests.memory: 10Gi
limits.cpu: "20"
limits.memory: 20Gi
pods: "10"
services: "5"
persistentvolumeclaims: "5"
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: development-quota
namespace: development
spec:
hard:
requests.cpu: "4"
requests.memory: 4Gi
limits.cpu: "8"
limits.memory: 8Gi
pods: "20"
services: "10"
persistentvolumeclaims: "10"
Limit Ranges
# limit-range.yaml
apiVersion: v1
kind: LimitRange
metadata:
name: production-limits
namespace: production
spec:
limits:
- default:
cpu: "1"
memory: "1Gi"
defaultRequest:
cpu: "100m"
memory: "128Mi"
max:
cpu: "2"
memory: "2Gi"
min:
cpu: "50m"
memory: "64Mi"
type: Container
- max:
storage: "10Gi"
min:
storage: "1Gi"
type: PersistentVolumeClaim
Applying Quotas and Limits
# Apply quotas
kubectl apply -f resource-quota.yaml
# Check quota usage
kubectl describe quota production-quota -n production
kubectl get quota -n production
# Check limit ranges
kubectl get limitrange -n production
kubectl describe limitrange production-limits -n production
Multi-Tenancy Implementation
Complete Multi-Tenant Setup
# multi-tenant-setup.yaml
# Team A - Production Environment
apiVersion: v1
kind: Namespace
metadata:
name: team-a-production
labels:
team: team-a
environment: production
---
apiVersion: v1
kind:ResourceQuota
metadata:
name: team-a-production-quota
namespace: team-a-production
spec:
hard:
requests.cpu: "20"
requests.memory: 20Gi
limits.cpu: "40"
limits.memory: 40Gi
pods: "50"
services: "20"
persistentvolumeclaims: "20"
---
# Team A - Development Environment
apiVersion: v1
kind: Namespace
metadata:
name: team-a-development
labels:
team: team-a
environment: development
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-a-development-quota
namespace: team-a-development
spec:
hard:
requests.cpu: "8"
requests.memory: 8Gi
limits.cpu: "16"
limits.memory: 16Gi
pods: "30"
services: "15"
persistentvolumeclaims: "15"
---
# Team B - Production Environment
apiVersion: v1
kind: Namespace
metadata:
name: team-b-production
labels:
team: team-b
environment: production
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-b-production-quota
namespace: team-b-production
spec:
hard:
requests.cpu: "15"
requests.memory: 15Gi
limits.cpu: "30"
limits.memory: 30Gi
pods: "40"
services: "15"
persistentvolumeclaims: "15"
RBAC with Namespaces
Role-Based Access Control Setup
# rbac-setup.yaml
# Team A Developer Role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: team-a-development
name: team-a-developer
rules:
- apiGroups: ["", "apps", "batch"]
resources: ["pods", "services", "deployments", "jobs", "cronjobs"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: [""]
resources: ["configmaps", "secrets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: team-a-developer-binding
namespace: team-a-development
subjects:
- kind: User
name: [email protected]
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: team-a-developer
apiGroup: rbac.authorization.k8s.io
---
# Team A Production Read-Only Role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: team-a-production
name: team-a-production-reader
rules:
- apiGroups: ["", "apps", "batch"]
resources: ["pods", "services", "deployments", "jobs", "cronjobs"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["configmaps", "secrets"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: team-a-production-reader-binding
namespace: team-a-production
subjects:
- kind: User
name: [email protected]
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: team-a-production-reader
apiGroup: rbac.authorization.k8s.io
Network Policies with Namespaces
Isolating Namespaces Network-Wise
# network-policies.yaml
# Deny all ingress to production namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: production-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
---
# Allow ingress only from same namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: production-allow-same-namespace
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: production
---
# Allow development to access production monitoring
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: production-allow-monitoring
namespace: production
spec:
podSelector:
matchLabels:
app: monitoring
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: development
ports:
- protocol: TCP
port: 8080
Namespace Best Practices
1. Organizational Structure
# namespace-best-practices.yaml
# Environment-based organization
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
environment: production
criticality: high
backup: required
---
apiVersion: v1
kind: Namespace
metadata:
name: staging
labels:
environment: staging
criticality: medium
backup: required
---
apiVersion: v1
kind: Namespace
metadata:
name: development
labels:
environment: development
criticality: low
backup: optional
2. Resource Organization Pattern
# complete-namespace-example.yaml
# Production Web Application
apiVersion: v1
kind: Namespace
metadata:
name: webapp-production
labels:
app: webapp
environment: production
team: platform
cost-center: engineering
spec:
finalizers:
- kubernetes
---
# Development Environment for Same App
apiVersion: v1
kind: Namespace
metadata:
name: webapp-development
labels:
app: webapp
environment: development
team: platform
cost-center: engineering
---
# Shared Services Namespace
apiVersion: v1
kind: Namespace
metadata:
name: shared-services
labels:
type: platform
team: devops
criticality: high
Namespace Troubleshooting
Common Issues and Solutions
# Check namespace status
kubectl get namespaces
kubectl describe namespace production
# Check resource quota usage
kubectl describe quota -n production
kubectl top namespace production
# Check network policies
kubectl get networkpolicies -n production
kubectl describe networkpolicy production-deny-all -n production
# Check RBAC permissions
kubectl auth can-i create pods -n production [email protected]
kubectl auth can-i list secrets -n production [email protected]
# Check pod distribution across namespaces
kubectl get pods --all-namespaces -o wide
Debugging Namespace Issues
# Check if namespace exists
kubectl get namespace production
# Check quota violations
kubectl get events --field-selector involvedObject.name=production-quota -n production
# Check network policy blocks
kubectl get events --field-selector involvedObject.kind=NetworkPolicy -n production
# Check RBAC denials
kubectl auth can-i create deployments -n production --as=test-user
Advanced Namespace Patterns
1. Temporary Namespaces for CI/CD
# Create temporary namespace for testing
kubectl create namespace ci-test-$BUILD_NUMBER
kubectl label namespace ci-test-$BUILD_NUMBER temp=true expiry=$(date +%s -d "+2 hours")
# Clean up old temporary namespaces
kubectl delete namespaces -l temp=true --field-selector status.phase=Active
2. Namespace Templates
# namespace-template.yaml
apiVersion: v1
kind: Namespace
metadata:
name: ${NAMESPACE_NAME}
labels:
team: ${TEAM_NAME}
environment: ${ENVIRONMENT}
created-by: automation
spec:
finalizers:
- kubernetes
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: ${NAMESPACE_NAME}-quota
namespace: ${NAMESPACE_NAME}
spec:
hard:
requests.cpu: "${CPU_REQUEST}"
requests.memory: "${MEMORY_REQUEST}"
pods: "${MAX_PODS}"
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: ${NAMESPACE_NAME}-default-deny
namespace: ${NAMESPACE_NAME}
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Namespace Commands Reference
# Namespace Management
kubectl create namespace production
kubectl get namespaces
kubectl describe namespace production
kubectl delete namespace development
# Working with Namespaces
kubectl config set-context --current --namespace=production
kubectl get pods -n production
kubectl get pods --all-namespaces
# Resource Quotas
kubectl create quota production-quota --hard=cpu=10,memory=10Gi,pods=50 -n production
kubectl get quota -n production
kubectl describe quota production-quota -n production
# RBAC with Namespaces
kubectl create role developer --verb=get,list,watch,create,update,patch,delete --resource=pods,services,deployments -n development
kubectl create rolebinding developer-binding --role=developer [email protected] -n development
# Network Policies
kubectl create networkpolicy production-deny-all --namespace=production --pod-selector="" --deny-all-ingress
kubectl get networkpolicies -n production
Practical Notes
- Namespaces provide resource isolation and organization in Kubernetes
- Resource quotas prevent resource exhaustion and enable fair sharing
- RBAC with namespaces enables fine-grained access control
- Network policies provide network-level isolation between namespaces
- Multi-tenancy is achieved through proper namespace design and policies
- Best practices include environment-based and team-based organization
Command Reference
# Namespace Management
kubectl create namespace production
kubectl get namespaces
kubectl describe namespace production
kubectl config set-context --current --namespace=production
# Resource Management
kubectl create quota production-quota --hard=cpu=10,memory=10Gi,pods=50 -n production
kubectl get quota -n production
kubectl create limitrange production-limits --max=cpu=2,memory=2Gi -n production
# Multi-tenancy Setup
kubectl create role developer --verb=get,list,watch,create,update,patch,delete --resource=pods,services,deployments -n development
kubectl create rolebinding developer-binding --role=developer [email protected] -n development
# Network Isolation
kubectl create networkpolicy production-deny-all --namespace=production --pod-selector="" --deny-all-ingress
kubectl get networkpolicies -n production
# Troubleshooting
kubectl auth can-i create pods -n production [email protected]
kubectl get events --field-selector involvedObject.name=production-quota -n production
Where It Fits Next
Namespaces organize who owns resources and how much they can use. Volumes solve a different boundary: what happens to state when pods restart, move, or scale.