What are the Kubernetes built-in namespaces default, kube-system, kube-public and kube-node-lease for, and which namespace does kubectl use without -n?
answer
- four namespaces a cluster makes itself
- one is a fallback, one is public
- heartbeat Leases per node
- flag, then context, then fallback
- NamespaceLifecycle guards deletion
basics
~10 sKubernetes creates default for objects with no namespace, kube-system for control-plane and add-on components, kube-public for world-readable data, and kube-node-lease for node heartbeat Leases. Without -n, kubectl uses the kubeconfig context's namespace, else default.
solid answer
~40 sA fresh cluster has four system namespaces. `default` is where objects land when nothing names a namespace, and it holds the `kubernetes` Service that fronts the API server. `kube-system` holds components the cluster itself runs: CoreDNS, kube-proxy and, on kubeadm clusters, the control-plane static pods. `kube-public` is meant to be readable by everyone; kubeadm keeps the `cluster-info` ConfigMap there and lets anonymous clients read it for node bootstrap. `kube-node-lease` holds one `Lease` per node, which the kubelet renews every 10 seconds by default as a cheap heartbeat. kubectl picks a namespace in this order: the `-n`/`--namespace` flag, then the current kubeconfig context's `namespace`, then `default`. The API server recreates these namespaces if they go missing, and refuses to delete `default`, `kube-system` and `kube-public`.
code
bash · 4 lineskubectl get namespaces
kubectl get leases -n kube-node-lease
kubectl config set-context --current --namespace=records-dev
kubectl get podsgo deeper
Recall the four system namespaces and one thing each holds, and the order kubectl uses to choose a namespace when -n is missing.
Explain why node heartbeats are Leases, how kubeadm uses kube-public for discovery, and how a manifest's own namespace interacts with the -n flag.
Show the operational habits: no workloads in default or kube-system, context namespaces set per environment, and watching for objects that land in default by accident.
Treat the system namespaces as the platform's reserved space and decide which of them tenants may read, and how an accidental default deployment is caught.
## The four system namespaces When a Kubernetes API server starts, it makes sure a small set of **system namespaces** exists and recreates any that are missing. On a current cluster there are four. | Namespace | What lives there | Who should put things there | |---|---|---| | `default` | Objects created without a namespace; the `kubernetes` Service for the API server | Nobody on purpose in a shared cluster | | `kube-system` | CoreDNS, kube-proxy, network-plugin agents, control-plane static pods on kubeadm clusters | Cluster operators only | | `kube-public` | Data meant to be readable by every client, such as kubeadm's `cluster-info` ConfigMap | Cluster tooling | | `kube-node-lease` | One `Lease` object per node, used as a heartbeat | The kubelet | ### default `default` is the fallback. A manifest without `metadata.namespace`, applied from a kubeconfig context with no namespace set, ends up here. It also contains the `kubernetes` Service, the in-cluster address of the API server. In a team cluster, workloads in `default` are usually a sign that someone forgot `-n`, and platform teams often block or watch it. ### kube-system `kube-system` is for the cluster's own components. On a kubeadm cluster, and on most laptop clusters built the same way, you find: - the control-plane static pods (`kube-apiserver`, `kube-controller-manager`, `kube-scheduler`, `etcd`), whose manifests the kubelet reads from disk; - the DNS add-on (CoreDNS) and `kube-proxy`; - the network plugin's agents and other add-ons. Leader-election Leases for kube-controller-manager and kube-scheduler also live here. Application workloads do not belong in `kube-system`: its ServiceAccounts often hold broad permissions, and mixing app pods in makes those permissions easier to misuse. ### kube-public `kube-public` is a convention: a place for information any client may read. kubeadm creates the `cluster-info` ConfigMap there, holding the cluster CA certificate and API server address, and binds the anonymous user to a Role that can read that one ConfigMap. A joining node can then discover the cluster before it has credentials. Nothing secret belongs in this namespace. ### kube-node-lease Each node has a `Lease` object here, named after the node. The kubelet renews it every 10 seconds by default, a quarter of its 40-second lease duration. A Lease update is far smaller than rewriting the whole `Node` status, so the node lifecycle controller uses Lease renewals as the main "this node is alive" signal on large clusters. ## Deletion protection The **NamespaceLifecycle** admission plugin in kube-apiserver rejects a delete of `default`, `kube-system` or `kube-public` with the message `this namespace may not be deleted`. `kube-node-lease` is not on that list, but the API server runs its own check every minute and recreates any missing system namespace, so a deleted `kube-node-lease` comes back once its deletion completes. The lifecycle of ordinary namespaces, including a namespace stuck in `Terminating`, is a separate subject. ## How kubectl picks a namespace For namespaced resources, kubectl resolves the namespace in a fixed order: 1. The `-n` / `--namespace` flag on the command line. 2. The `namespace` field of the current context in the kubeconfig. 3. The literal `default`. Two details trip people up: - A manifest that sets `metadata.namespace` **wins over the context** when you pass no `-n`. If you pass `-n` with a different value, kubectl refuses with an error saying the namespace in the object does not match the namespace given. - `-A` (`--all-namespaces`) lists across every namespace and ignores both the flag and the context. To stop typing `-n` on a laptop cluster, set the context namespace once: ```bash kubectl config set-context --current --namespace=records-dev kubectl config view --minify -o jsonpath='{..namespace}' ``` The second command prints the namespace the current context now uses. ## Practical habits - Create a namespace per application or environment (`records-dev`, `records-review`) instead of using `default`. - Treat `kube-system` as off-limits for application pods. - Never store anything sensitive in `kube-public`. - Leave `kube-node-lease` alone; its objects are the node heartbeat. - On a laptop cluster, make the context namespace part of your prompt or shell setup, so it is always visible which namespace a bare `kubectl` command will touch. Most "my pod disappeared" moments on a single-node dev cluster are a command that ran against `default` or against the wrong context namespace.
- Why does Kubernetes keep node heartbeats as Lease objects in kube-node-lease rather than only in Node status?A `Lease` is a tiny object, so renewing it every 10 seconds costs far less in API server and etcd traffic than rewriting a large `Node` status. The kubelet still updates Node status, but less often. The node lifecycle controller treats Lease renewals as the main liveness signal, which scales much better on clusters with many nodes.
- Is it acceptable to deploy application workloads into the Kubernetes kube-system namespace?No. `kube-system` holds cluster components whose ServiceAccounts often carry broad permissions. Application pods there are easier to escalate from, harder to audit, and get caught by policies meant for system add-ons. Put applications in their own namespaces, so quotas, RBAC and network rules can be applied to them separately.
saying these in an interview costs you the question
- kube-public is a safe place for shared credentials
- kubectl always uses default unless you pass -n
- Application pods can go in kube-system if they are important
- kube-node-lease stores the kubelet's TLS certificates
- Deleting default is a quick way to clean up a dev cluster