A namespace is a "logical cluster" inside the real one: the main way to separate environments (dev, prod) and teams and to limit access. Object names only need to be unique within a namespace.
flowchart TB
subgraph C["Cluster"]
D["ns dev<br/>web, api"]
P["ns prod<br/>web, api"]
S["ns kube-system<br/>coredns, kube-proxy"]
end
Built-in namespaces: default, kube-system (system components), kube-public, kube-node-lease (node heartbeats).
Choosing a namespace
- In a manifest:
metadata.namespace: dev. - With kubectl:
-n dev/--namespace dev;-A(--all-namespaces) to see all. - Without one, the current context namespace is used (usually
default).
Notes
- Forgetting
-nis the number one reason you "cannot see" a pod. - Deleting a namespace deletes everything in it.
- Some resources are not namespaced (cluster-scoped): Node, PersistentVolume, Namespace, StorageClass. Check the
NAMESPACEDcolumn ofkubectl api-resources. - Namespaces do not isolate the network; you need NetworkPolicies.
- A ResourceQuota caps the total resources of a namespace:
kubectl create quota dev-quota -n dev --hard=cpu=2,memory=2Gi
kubectl describe quota -n dev
| Command | Meaning |
|---|---|
kubectl create namespace dev |
Create a namespace |
kubectl get pods -n dev |
Pods in dev |
kubectl get pods -A |
Pods in every namespace |
kubectl delete ns dev |
Delete the namespace and everything in it |
Defaults per namespace with LimitRange
A ResourceQuota caps the total; a LimitRange sets defaults and bounds for each container, so pods without resources still get sensible values:
apiVersion: v1
kind: LimitRange
metadata: { name: defaults, namespace: dev }
spec:
limits:
- type: Container
default: { cpu: 500m, memory: 256Mi }
defaultRequest: { cpu: 100m, memory: 128Mi }
When a quota covers CPU or memory, every new pod must declare requests and limits, and a LimitRange is the usual way to fill them in.
Working in a namespace
kubectl config set-context --current --namespace=dev makes dev the default for your current context, so you stop typing -n dev. The community tool kubens does the same with one word. Check the current one with kubectl config view --minify -o jsonpath='{..namespace}'.
Reaching Services in another namespace
A short name like api only resolves inside the same namespace. From elsewhere use api.prod or the full api.prod.svc.cluster.local. Forgetting this is a common reason an app works in one namespace and fails in another.
Security boundaries per namespace
- RBAC Roles and RoleBindings are namespaced, so a team can be admin in
team-aand see nothing inteam-b. - Pod Security Admission is turned on with labels:
kubectl label ns prod pod-security.kubernetes.io/enforce=restrictedrejects pods that run as root or request host access. - NetworkPolicies, quotas, and limits all attach per namespace.
Organising namespaces
Common patterns are one namespace per team, per application, or per environment when environments share a cluster. Avoid deploying everything into default. Namespaces give soft multi-tenancy; teams that must not trust each other at all usually get separate clusters.
A namespace stuck in Terminating usually has a resource whose finalizer cannot complete; kubectl api-resources --verbs=list --namespaced -o name | xargs -n1 kubectl get -n dev helps find what is left.