Kubernetes Namespaces
Video: Day 10/40 — Kubernetes Namespace Explained • https://www.youtube.com/watch?v=yVLXIydlU_0 • Duration: ~28 min
Key terms
| Term | Meaning |
|---|---|
| Namespace | Virtual partition for resources inside one cluster |
| default | Namespace used when none is specified |
| kube-system | Namespace for cluster components |
| ResourceQuota | Caps total resource use in a namespace |
| Scope | Whether an object is namespaced or cluster-scoped |
| Cross-namespace DNS | <svc>.<ns>.svc.cluster.local to reach other namespaces |
Problem & solution
Putting every team and environment in one shared space causes name collisions, no isolation, and no way to scope quotas or access. We need logical boundaries inside a single physical cluster.
Solution: Partition the cluster into namespaces (dev/staging/prod) for isolation, resource quotas, and scoped RBAC.
The analogy
A big port leases out separate sections, one to each tenant company, and each tenant hangs its own signage inside its patch. Two tenants can both post a sign reading Pier 7 because each sign only means something within that company's leased section, so the names never collide. Kubernetes namespaces work the same way: each is a leased section of the cluster where a Service named web in dev and another Service named web in prod can coexist without clashing.
Where this fits in the cluster
The same cluster entities appear in every day's notes; the diagram below shows where this day's topic fits.
What is a Namespace?
A virtual cluster inside a cluster — a logical boundary to group and isolate resources (pods, services, configmaps...). Great for separating teams/envs.
Graph legend — one team's frontend app across three env namespaces:
| Graph node | Maps to | What it does |
|---|---|---|
| ns team-a-dev / -staging / -prod | three Namespace objects | Isolated env slices for the same team's app |
| frontend pod | the Online Boutique frontend Deployment's pods | The same app deployed once per environment |
| svc frontend | a Service named frontend in each ns | Same Service name reused per namespace without clashing |
Default namespaces
A fresh cluster ships with four namespaces, each with a job.
default -> where your objects go if none specified
kube-system -> control-plane components (coredns, proxy...)
kube-public -> world-readable cluster info
kube-node-lease -> node heartbeat lease objects
Why use them?
Namespaces (logical partitions that group and isolate a set of resources inside one cluster) earn their keep through four concrete benefits. Each bullet below is a reason teams reach for them.
- Isolation: same names in different namespaces don't clash.
- Access control: scope RBAC roles per namespace.
- Resource quotas: cap CPU/memory per namespace.
- Organization: group by team / environment / app.
Commands
The core commands for creating namespaces and scoping kubectl to one with -n.
kubectl get ns # list namespaces
kubectl create namespace dev # create
kubectl get pods -n dev # list pods in ns
kubectl get pods --all-namespaces # everything (-A)
kubectl run nginx --image=nginx -n dev # create in ns
# set default ns for current context (stop typing -n)
kubectl config set-context --current --namespace=dev
Namespace in YAML
Set metadata.namespace to pin an object to a specific namespace instead of
default.
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: dev # <- pin the object to a namespace
spec:
containers:
- name: nginx
image: nginx
Worked example: svc-test vs svc-demo
The demo runs the same nginx workload twice, once per namespace, each fronted by its own service. It shows isolation and how to cross the boundary.
Graph legend — the same nginx workload in two namespaces:
| Graph node | Maps to | What it does |
|---|---|---|
| ns default / ns demo | two Namespace objects | Separate name scopes in one cluster |
| nginx x3 | three nginx:1.27 pods per namespace | Identical real workload deployed in each ns |
| svc-test / svc-demo ClusterIP | a Service (type ClusterIP) per ns | Each fronts its own namespace's nginx pods |
| cross-namespace call | a request to svc-demo.demo.svc.cluster.local | Reaching the other namespace's Service by FQDN |
- svc-test lives in
defaultand load-balances the 3 nginx pods there. - svc-demo lives in
demoand load-balances the 3 nginx pods there. - Both services can be named the same kind of thing without clashing — names are unique per namespace, so the two never collide.
- A pod in
defaulthittingsvc-testuses the short name (same namespace). - To reach across, a pod in
defaultcallssvc-demoby its FQDN, and a pod indemocallssvc-testby its FQDN. The arrow crossing the boundary in the diagram is exactly this cross-namespace call.
kubectl create namespace demo
kubectl run nginx --image=nginx:1.27 -n default # x3 -> behind svc-test
kubectl run nginx --image=nginx:1.27 -n demo # x3 -> behind svc-demo
kubectl expose pod nginx --name=svc-test -n default --port=80
kubectl expose pod nginx --name=svc-demo -n demo --port=80
# from a pod in default:
curl svc-test # short name, same ns
curl svc-demo.demo.svc.cluster.local # FQDN, cross ns
Each service still gets its own ClusterIP; the FQDN just resolves to that IP through CoreDNS. Namespaces don't block traffic by default — they scope names, not the network (that's what NetworkPolicies are for).
Cross-namespace DNS
A pod reaches a service in another namespace by using its fully-qualified DNS name; same-namespace calls can use the short name.
same ns: curl web
other ns: curl web.dev.svc.cluster.local
<service>.<namespace>.svc.cluster.local
ResourceQuota (cap a namespace)
A ResourceQuota caps how much CPU, memory, and how many objects a namespace can consume.
apiVersion: v1
kind: ResourceQuota
metadata:
name: dev-quota
namespace: dev
spec:
hard:
pods: "10"
requests.cpu: "2"
requests.memory: 2Gi
Not namespaced
Some objects are cluster-scoped (not in any namespace):
nodes, namespaces, persistentvolumes, clusterroles
check: kubectl api-resources --namespaced=false
End-to-end flow
Namespaces scope names and access, and a call into another namespace uses the fully qualified DNS name.
Graph legend — namespaces scope names, RBAC, quota, and DNS:
| Graph node | Maps to | What it does |
|---|---|---|
| kubectl apply -n team-a-dev | kubectl ... -n <ns> | Targets one namespace for the created objects |
| Object created in team-a-dev | metadata.namespace | Pins the resource to that namespace |
| RBAC and ResourceQuota scoped to team-a-dev | Role/RoleBinding + ResourceQuota | Access and caps apply only within the namespace |
| short name | same-namespace DNS lookup | Resolves frontend within the caller's ns |
| FQDN frontend.team-a-dev.svc.cluster.local | <svc>.<ns>.svc.cluster.local | Reaches a Service in another namespace |
Key takeaways
- Namespaces = logical isolation within one cluster.
- Names are unique per namespace, not cluster-wide.
- Use
-n <ns>/-A, and cross-ns DNS =svc.ns.svc.cluster.local.
Checklist
- [ ] Created a namespace and ran a pod in it
- [ ] Listed resources with
-nand-A - [ ] Set a default namespace on the context
- [ ] Reached a service across namespaces by FQDN