How to Manage Kubernetes Namespaces Effectively
Master Kubernetes namespace organization for multi-team environments. Learn resource quotas, network policies, and RBAC per namespace.
The Problem
You have multiple teams or applications sharing a Kubernetes cluster and need to organize, isolate, and control resources between them.
The Solution
Use namespaces to create logical boundaries with resource quotas, network policies, and RBAC controls.
Understanding Namespaces
Namespaces provide:
- Logical separation of resources
- Resource quota enforcement
- RBAC boundaries
- Network policy isolation
- Easier management of related resources
Default Namespaces
| Namespace | Purpose |
|---|---|
default | Default for resources without namespace |
kube-system | Kubernetes system components |
kube-public | Publicly accessible data |
kube-node-lease | Node heartbeat leases |
Creating Namespaces
Basic Namespace
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
environment: production
team: platformNamespace with Annotations
apiVersion: v1
kind: Namespace
metadata:
name: team-backend
labels:
team: backend
cost-center: engineering
annotations:
owner: "backend-team@example.com"
description: "Backend services for the main application"Apply:
kubectl apply -f namespace.yamlOr create directly:
kubectl create namespace stagingResource Quotas
Limit resources per namespace:
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: team-backend
spec:
hard:
# Compute resources
requests.cpu: "10"
requests.memory: "20Gi"
limits.cpu: "20"
limits.memory: "40Gi"
# Object counts
pods: "50"
services: "20"
secrets: "50"
configmaps: "50"
persistentvolumeclaims: "10"
# Storage
requests.storage: "100Gi"Check quota usage:
kubectl describe resourcequota compute-quota -n team-backendLimitRanges
Set default and max limits for containers:
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: team-backend
spec:
limits:
- type: Container
default:
cpu: "500m"
memory: "256Mi"
defaultRequest:
cpu: "100m"
memory: "128Mi"
max:
cpu: "2"
memory: "2Gi"
min:
cpu: "50m"
memory: "64Mi"
- type: PersistentVolumeClaim
max:
storage: "10Gi"
min:
storage: "1Gi"Network Isolation
Default Deny All
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: team-backend
spec:
podSelector: {}
policyTypes:
- Ingress
- EgressAllow Within Namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-same-namespace
namespace: team-backend
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {} # Same namespaceAllow from Specific Namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-monitoring
namespace: team-backend
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoringRBAC Per Namespace
Namespace Admin Role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: namespace-admin
namespace: team-backend
rules:
- apiGroups: ["", "apps", "batch", "networking.k8s.io"]
resources: ["*"]
verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: backend-team-admin
namespace: team-backend
subjects:
- kind: Group
name: backend-developers
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: namespace-admin
apiGroup: rbac.authorization.k8s.ioRead-Only Access
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: namespace-viewer
namespace: team-backend
rules:
- apiGroups: ["", "apps", "batch"]
resources: ["*"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: qa-team-viewer
namespace: team-backend
subjects:
- kind: Group
name: qa-team
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: namespace-viewer
apiGroup: rbac.authorization.k8s.ioNamespace Organization Strategies
By Environment
βββ development
βββ staging
βββ productionBy Team
βββ team-frontend
βββ team-backend
βββ team-data
βββ team-platformBy Application
βββ app-web
βββ app-api
βββ app-workerCombined Strategy
βββ prod-frontend
βββ prod-backend
βββ prod-shared
βββ staging-frontend
βββ staging-backend
βββ dev-frontend
βββ dev-backendComplete Namespace Setup
# 1. Namespace
apiVersion: v1
kind: Namespace
metadata:
name: team-backend
labels:
team: backend
environment: production
---
# 2. Resource Quota
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: team-backend
spec:
hard:
requests.cpu: "10"
requests.memory: "20Gi"
limits.cpu: "20"
limits.memory: "40Gi"
pods: "50"
---
# 3. Limit Range
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: team-backend
spec:
limits:
- type: Container
default:
cpu: "500m"
memory: "256Mi"
defaultRequest:
cpu: "100m"
memory: "128Mi"
---
# 4. Network Policy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: team-backend
spec:
podSelector: {}
policyTypes:
- Ingress
---
# 5. Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
name: team-backend-sa
namespace: team-backendWorking with Namespaces
Set Default Namespace
# Set for current context
kubectl config set-context --current --namespace=team-backend
# Or use kubens
kubens team-backendView Resources Across Namespaces
# All pods in all namespaces
kubectl get pods -A
# Specific resource across namespaces
kubectl get deployments --all-namespacesCross-Namespace Service Access
Services can be accessed across namespaces:
<service-name>.<namespace>.svc.cluster.localExample:
env:
- name: DATABASE_HOST
value: "postgres.database.svc.cluster.local"Namespace Cleanup
Delete Namespace (and all resources)
kubectl delete namespace team-backendβ οΈ Warning: This deletes ALL resources in the namespace!
Delete Resources But Keep Namespace
kubectl delete all --all -n team-backendBest Practices
1. Use Labels Consistently
metadata:
labels:
team: backend
environment: production
cost-center: engineering2. Always Set Resource Quotas
Prevent runaway resource consumption.
3. Apply Network Policies
Default to deny, explicitly allow needed traffic.
4. Use Namespace-Scoped RBAC
Grant minimal permissions per namespace.
5. Document Namespace Purpose
Use annotations for ownership and purpose.
Key Takeaways
- Namespaces provide logical isolation in Kubernetes
- Use ResourceQuotas to limit resource consumption
- Use LimitRanges for default container limits
- Apply NetworkPolicies for network isolation
- Configure RBAC for access control per namespace
π Go Further with Kubernetes Recipes
Love this recipe? Thereβs so much more! This is just one of 100+ hands-on recipes in our comprehensive Kubernetes Recipes book.
Inside the book, youβll master:
- β Production-ready deployment strategies
- β Advanced networking and security patterns
- β Observability, monitoring, and troubleshooting
- β Real-world best practices from industry experts
βThe practical, recipe-based approach made complex Kubernetes concepts finally click for me.β
π Get Your Copy Now β Start building production-grade Kubernetes skills today!
π Get All 100+ Recipes in One Book
Stop searching β get every production-ready pattern with detailed explanations, best practices, and copy-paste YAML.
Want More Kubernetes Recipes?
This recipe is from Kubernetes Recipes, our 750-page practical guide with hundreds of production-ready patterns.