Kubernetes Namespace Best Practices
Organize Kubernetes clusters with namespace best practices. Separation strategies, resource quotas, network policies, RBAC per namespace, naming
π‘ Quick Answer: Use namespaces to separate environments (dev/staging/prod), teams, or applications. Apply ResourceQuotas to prevent resource hogging, NetworkPolicies for network isolation, and RBAC Roles for access control per namespace. Donβt over-namespace β most clusters need 5-20 namespaces, not hundreds.
The Problem
- All resources in
defaultnamespace β no isolation, hard to manage - Teams competing for cluster resources without limits
- No access control separation between teams/environments
- Canβt apply different policies to different workloads
- Naming collisions between applications from different teams
The Solution
Namespace Organization Patterns
Pattern 1: By Environment
βββ dev
βββ staging
βββ production
βββ (system namespaces)
Pattern 2: By Team
βββ team-frontend
βββ team-backend
βββ team-data
βββ team-ml
βββ shared-infra
Pattern 3: By Application (Microservices)
βββ app-ecommerce
βββ app-payments
βββ app-notifications
βββ app-analytics
βββ platform
Pattern 4: Combined (Recommended)
βββ production-frontend
βββ production-backend
βββ staging
βββ dev
βββ monitoring
βββ logging
βββ ingress
βββ cert-managerCreate Namespace with Labels
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
environment: production
team: platform
kubernetes.io/metadata.name: production # Auto-label (K8s 1.22+)
annotations:
owner: "platform-team@example.com"
budget: "engineering"Resource Quotas
apiVersion: v1
kind: ResourceQuota
metadata:
name: production-quota
namespace: production
spec:
hard:
requests.cpu: "20"
requests.memory: "40Gi"
limits.cpu: "40"
limits.memory: "80Gi"
pods: "100"
services: "20"
persistentvolumeclaims: "30"
requests.nvidia.com/gpu: "8"
---
# Limit ranges for individual pods
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: production
spec:
limits:
- default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "100m"
memory: "128Mi"
max:
cpu: "4"
memory: "8Gi"
min:
cpu: "50m"
memory: "64Mi"
type: ContainerRBAC Per Namespace
# Team can manage their namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: team-admin
namespace: team-frontend
rules:
- apiGroups: ["", "apps", "batch"]
resources: ["*"]
verbs: ["*"]
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses", "networkpolicies"]
verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: frontend-team-admin
namespace: team-frontend
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: team-admin
subjects:
- kind: Group
name: "frontend-developers"
apiGroup: rbac.authorization.k8s.ioNamespace vs Cluster: When to Separate
Use Namespaces when: Use Separate Clusters when:
βββ Same trust level βββ Different trust levels
βββ Shared infrastructure βββ Compliance isolation required
βββ Resource quotas sufficient βββ Different K8s versions needed
βββ Network policies provide isolation βββ Hard multi-tenancy (untrusted)
βββ Same team/org βββ Different regions/DCs
βββ Development vs staging βββ Customer-dedicated environmentsCommon Issues
Canβt see resources β βNo resources found in default namespaceβ
- Cause: Resources are in another namespace; forgot
-nflag - Fix: Use
kubectl get pods -A(all namespaces); or set default:kubectl config set-context --current --namespace=production
ResourceQuota blocking deployments
- Cause: Pods donβt set resource requests/limits; quota requires them
- Fix: Add requests/limits to all pods; or set LimitRange for defaults
Cross-namespace service access
- Cause: Services are namespace-scoped; need full DNS name
- Fix: Use
<service>.<namespace>.svc.cluster.localfor cross-namespace access
Best Practices
- Never use
defaultfor production β create explicit namespaces - Apply ResourceQuotas β prevent one team from consuming all resources
- Set LimitRange defaults β pods without limits get sensible defaults
- RBAC per namespace β teams can only access their namespaces
- NetworkPolicy per namespace β default deny + explicit allows
- Label namespaces β enables namespace-based NetworkPolicy selectors
- 5-20 namespaces is typical β donβt over-namespace (one per microservice is too many)
- Set default namespace in context β
kubectl config set-context --current --namespace=X
Key Takeaways
- Namespaces provide logical isolation: resource quotas, RBAC, network policies
- Not physical isolation β pods in different namespaces share nodes and network
- Label namespaces for NetworkPolicy cross-namespace rules
- ResourceQuota prevents resource hogging; LimitRange sets per-pod defaults
- Cross-namespace access:
<service>.<namespace>.svc.cluster.local - Typical patterns: by environment, by team, or combined
- Use separate clusters for hard multi-tenancy or compliance requirements

Recommended
Kubernetes Recipes β The Complete Book100+ production-ready patterns with detailed explanations, best practices, and copy-paste YAML. Everything in one place.
Get the Book βLearn by Doing
CopyPasteLearn β Hands-on Cloud & DevOps CoursesMaster Kubernetes, Ansible, Terraform, and MLOps with interactive, copy-paste-run lessons. Start free.
Browse Courses βπ Deepen Your Skills β Hands-on Courses
Courses by CopyPasteLearn.com β Learn IT by Doing
