Skip to content

So far, every object we’ve created—Pods, Deployments, Services—has been placed into a single, global space. For our small examples, this has been fine. But imagine a real-world cluster used by multiple teams, for multiple projects, across multiple environments (development, staging, production). A single, flat space would quickly become unmanageable.

The solution to cluster organization is the Namespace. You can think of a Namespace as a virtual cluster inside your physical Kubernetes cluster. It provides a scope for your resources, allowing you to partition the cluster for different purposes.

Using Namespaces solves several key problems:

  1. Name Collisions: In a single, default space, most resource names must be unique. Two teams cannot both create a Deployment named my-api. Namespaces solve this by requiring names to be unique only within that namespace. my-api in the team-a namespace is completely different from my-api in the team-b namespace.
  2. Organization and Isolation: Namespaces are the primary way to group resources that belong together. You can create a namespace for each environment (dev, staging, prod) or for each team. This makes it much easier to see what belongs to whom.
  3. Access Control and Resource Management: Namespaces are a cornerstone of Kubernetes security and policy. You can set rules (called Role-Based Access Control, or RBAC) that say “developers on Team A can only create, view, and delete resources inside the team-a-dev namespace.” You can also set resource quotas on a namespace to limit the total amount of CPU, memory, or number of Pods that can be used within it.

When you start a cluster, it already has a few namespaces:

  • default: The namespace where your resources are placed if you don’t specify one. We’ve been using this all along.
  • kube-system: Where the core components of the Kubernetes control plane run. You should almost never create or modify anything here.
  • kube-public: A special namespace that is readable by all users. It’s mostly used for exposing public cluster information.
  • kube-node-lease: Used internally by Kubernetes for node heartbeats to determine availability.


  1. Create Namespaces We can create namespaces with a simple kubectl command.

    Terminal window
    kubectl create namespace dev
    kubectl create namespace staging

    You can list all the namespaces in your cluster:

    Terminal window
    kubectl get namespaces
    # NAME STATUS AGE
    # default Active 1h
    # dev Active 10s
    # kube-node-lease Active 1h
    # kube-public Active 1h
    # kube-system Active 1h
    # staging Active 5s
  2. Deploy an Application into a Specific Namespace We will reuse a simple deployment definition. Create a file named app-deployment.yaml:

    app-deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: my-app
    spec:
    replicas: 2
    selector:
    matchLabels:
    app: my-app
    template:
    metadata:
    labels:
    app: my-app
    spec:
    containers:
    - name: nginx
    image: nginx:1.21.6

    Now, let’s deploy this application into our dev namespace using the -n (or --namespace) flag.

    Terminal window
    kubectl apply -f app-deployment.yaml -n dev

    And now we can deploy the exact same configuration into the staging namespace without any conflict.

    Terminal window
    kubectl apply -f app-deployment.yaml -n staging
  3. Viewing Namespaced Resources If you run kubectl get pods now, you won’t see anything. That’s because the command defaults to looking in the default namespace. To see our pods, we must specify the namespace.

    Terminal window
    # See pods in the 'dev' namespace
    kubectl get pods -n dev
    # NAME READY STATUS RESTARTS AGE
    # my-app-55bcfd65f7-abcde 1/1 Running 0 1m
    # my-app-55bcfd65f7-fghij 1/1 Running 0 1m
    # See pods in the 'staging' namespace
    kubectl get pods -n staging
    # NAME READY STATUS RESTARTS AGE
    # my-app-55bcfd65f7-klmno 1/1 Running 0 50s
    # my-app-55bcfd65f7-pqrst 1/1 Running 0 50s

    To see all pods across all namespaces, use the -A flag:

    Terminal window
    kubectl get pods -A
  4. Cleaning Up with Namespaces One of the most powerful features of namespaces is for cleanup. Instead of deleting each deployment, service, and pod individually, you can just delete the entire namespace. This will destroy all resources created within it.

    Terminal window
    kubectl delete namespace dev
    kubectl delete namespace staging

    This is an incredibly efficient way to tear down an entire environment you were using for testing.

  • Namespaces are the primary tool for organizing a Kubernetes cluster.
  • Use them to partition your cluster by team, project, or environment (dev, staging, prod).
  • Always specify the namespace you are working in with kubectl -n <namespace-name>.
  • Namespaces are the foundation upon which Kubernetes security (RBAC) and resource limits (ResourceQuotas) are built.
  • Deleting a namespace is a fast and final way to delete all the resources it contains.

We’ve now covered how to organize your cluster. Let me know when you are ready for Chapter 4: Handling Batch Workloads with Jobs & CronJobs.