Teams and environments share clusters through namespaces; most kubectl mistakes involve the wrong one.
A namespace is a scope for names: you can have a web Deployment in shop and another in blog. Most objects (pods, Services, Deployments, ConfigMaps, Secrets) are namespaced; some are cluster-wide (Nodes, PersistentVolumes, StorageClasses, ClusterRoles, Namespaces themselves). kubectl api-resources --namespaced=false lists the latter.
Built-in namespaces:
default: where things go if you don't say.kube-system: control-plane and add-on components.kube-publicandkube-node-lease: rarely touched.
Namespaces are the unit for:
- RBAC: a Role grants rights inside one namespace.
- ResourceQuota and LimitRange: cap total CPU/memory/objects and set default container limits per namespace.
- NetworkPolicy: policies apply to pods in their namespace.
They are not a strong security boundary by themselves: pods in different namespaces can talk to each other unless NetworkPolicies say otherwise, and they share nodes.
Deleting a namespace deletes everything in it, which makes per-branch preview environments easy to clean up and makes kubectl delete ns dangerous.
Set metadata.namespace in manifests or use -n; avoid relying on the context's default for anything important.
Example
kubectl create namespace shop
kubectl get ns
kubectl -n shop create deployment web --image=nginx:1.27
kubectl get deploy -A # all namespaces
kubectl config set-context --current --namespace=shop
# cap what the namespace may consume
kubectl -n shop create quota team-quota \
--hard=requests.cpu=4,requests.memory=8Gi,pods=40
kubectl -n shop describe quota team-quotaRemember
- Names are unique per namespace, not per cluster
- RBAC, quotas and network policies are scoped by namespace
- Namespaces don't isolate network traffic by default
Watch out for
- Assuming separate namespaces mean pods can't reach each other.