Skip to content

Kubernetes Namespaces

Namespaces partition a single Kubernetes cluster into logically isolated environments. Resources within a namespace are isolated from those in other namespaces (with some exceptions like nodes and persistent volumes).

NamespacePurpose
defaultWhere resources go if no namespace is specified
kube-systemKubernetes system components (DNS, metrics-server, etc.)
kube-publicPublicly readable resources (cluster info)
kube-node-leaseNode heartbeat objects
Terminal window
kubectl create namespace staging

Or from YAML:

apiVersion: v1
kind: Namespace
metadata:
name: staging
labels:
env: staging
Terminal window
# Specify namespace with -n
kubectl get pods -n staging
kubectl apply -f deployment.yaml -n staging
# See resources in all namespaces
kubectl get pods --all-namespaces
kubectl get pods -A
# Set a default namespace for your context
kubectl config set-context --current --namespace=staging

Services are reachable across namespaces using their fully qualified DNS name:

<service-name>.<namespace>.svc.cluster.local

From the default namespace, reach a service in staging:

http://api-service.staging.svc.cluster.local

Prevent one team or environment from consuming all cluster resources:

apiVersion: v1
kind: ResourceQuota
metadata:
name: staging-quota
namespace: staging
spec:
hard:
pods: "20"
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
persistentvolumeclaims: "10"
Terminal window
kubectl apply -f quota.yaml
kubectl describe resourcequota -n staging

Set default resource requests and limits for pods in a namespace:

apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: staging
spec:
limits:
- default:
cpu: 500m
memory: 256Mi
defaultRequest:
cpu: 100m
memory: 128Mi
type: Container

RBAC roles are namespace-scoped by default:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dev-team-binding
namespace: staging
subjects:
- kind: Group
name: dev-team
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: developer
apiGroup: rbac.authorization.k8s.io

Dev/Staging/Prod in one cluster:

Terminal window
kubectl create namespace dev
kubectl create namespace staging
kubectl create namespace prod

Pros: shared infrastructure cost, easier cluster management Cons: production workloads compete for resources with dev; requires strong RBAC and quotas

One cluster per environment: Better isolation, harder to manage. Preferred for strict compliance requirements.

Terminal window
kubectl delete namespace staging

This deletes all resources inside — use with caution. Terminating can hang if there are resources with finalizers; check with:

Terminal window
kubectl get namespace staging -o yaml