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.

Resources for Further Learning