Overall Analogy: Building Wings in an Apartment Complex#

Namespaces are easy to understand when compared to building wings in an apartment complex:

Apartment Complex AnalogyKubernetes NamespaceRole
Wing 101, Wing 102 separationNamespaceLogically isolate resources
Per-wing maintenance budgetResourceQuotaLimit total resources per namespace
Per-unit electricity/water limitLimitRangeDefault resources per Pod/container
Management office restricted areakube-systemDedicated space for system components
Public bulletin board areakube-publicSpace accessible to all users
Per-wing access cardRBAC + NamespaceSeparate access permissions

In this way, a Namespace is like “dividing management areas by building wing within a single apartment complex.”


Target Audience: Operators who want to systematically manage resources in a Kubernetes cluster Prerequisites: Pod, Deployment, Service concepts After reading this: You will understand how to configure multi-tenant environments using Namespaces

TL;DR
  • Namespaces logically isolate resources within a cluster
  • You can limit resource usage with ResourceQuota and LimitRange
  • Multi-tenant operations are possible through team/environment separation

What Is a Namespace?#

A Namespace is a mechanism that divides a single physical cluster into multiple virtual clusters. Resources with the same name can exist in different Namespaces.

FeatureDescription
Resource isolationSeparate resources by team/project
Name scopingCreate resources with the same name in different Namespaces
Access controlCombine with RBAC for permission separation
Resource limitsSet usage caps with ResourceQuota

Namespace Isolation Structure#

flowchart TB
    subgraph Cluster["Kubernetes Cluster"]
        subgraph NS1["Namespace: team-a"]
            D1["Deployment<br>web-app"]
            S1["Service<br>web-svc"]
            D1 --> P1["Pod"]
            D1 --> P2["Pod"]
        end
        subgraph NS2["Namespace: team-b"]
            D2["Deployment<br>web-app"]
            S2["Service<br>web-svc"]
            D2 --> P3["Pod"]
            D2 --> P4["Pod"]
        end
        subgraph NS3["Namespace: kube-system"]
            CS["CoreDNS"]
            KP["kube-proxy"]
        end
    end

Each Namespace is an independent space, so a web-app Deployment with the same name can exist in both team-a and team-b.

Default Namespaces#

When you create a Kubernetes cluster, the following Namespaces are automatically created.

NamespacePurpose
defaultThe default space used when no Namespace is specified
kube-systemKubernetes system components (CoreDNS, kube-proxy, etc.)
kube-publicPublic resources readable by all users
kube-node-leaseStores Lease objects for node heartbeats
Warning
Arbitrarily modifying or deleting resources in the kube-system Namespace may cause the cluster to malfunction.

Creating and Using Namespaces#

Creating a Namespace#

apiVersion: v1
kind: Namespace
metadata:
  name: team-a
  labels:
    team: a
    environment: production
# Create with YAML
kubectl apply -f namespace.yaml

# Or create with command
kubectl create namespace team-a

Creating Resources in a Specific Namespace#

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  namespace: team-a    # Specify Namespace
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
      - name: app
        image: nginx:1.25
        ports:
        - containerPort: 80

Specifying Namespace in kubectl#

# List Pods in a specific Namespace
kubectl get pods -n team-a

# List Pods across all Namespaces
kubectl get pods --all-namespaces

# Change default Namespace
kubectl config set-context --current --namespace=team-a

ResourceQuota#

ResourceQuota limits the total resource usage for an entire Namespace.

apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-a-quota
  namespace: team-a
spec:
  hard:
    requests.cpu: "4"
    requests.memory: 8Gi
    limits.cpu: "8"
    limits.memory: 16Gi
    pods: "20"
    services: "10"
    persistentvolumeclaims: "5"
FieldDescription
requests.cpu / requests.memoryUpper limit for total resource requests
limits.cpu / limits.memoryUpper limit for total resource limits
podsMaximum number of Pods
servicesMaximum number of Services
persistentvolumeclaimsMaximum number of PVCs
# Check ResourceQuota
kubectl describe resourcequota team-a-quota -n team-a

LimitRange#

LimitRange sets default values and ranges for individual Pod/container resources within a Namespace.

apiVersion: v1
kind: LimitRange
metadata:
  name: team-a-limits
  namespace: team-a
spec:
  limits:
  - type: Container
    default:
      cpu: "500m"
      memory: "256Mi"
    defaultRequest:
      cpu: "100m"
      memory: "128Mi"
    max:
      cpu: "2"
      memory: "2Gi"
    min:
      cpu: "50m"
      memory: "64Mi"
FieldDescription
defaultDefault limit values applied when limits are not specified
defaultRequestDefault request values applied when requests are not specified
maxMaximum values a container can set
minMinimum values a container must set
Relationship Between ResourceQuota and LimitRange
ResourceQuota limits the total resource amount for the entire Namespace, while LimitRange limits the resource range for individual containers. Using both together enables effective resource management.

Cross-Namespace Communication#

To access a Service in a different Namespace within the same cluster, use the FQDN (Fully Qualified Domain Name).

<service-name>.<namespace>.svc.cluster.local
flowchart LR
    subgraph NS1["Namespace: team-a"]
        PA["Pod A"]
    end
    subgraph NS2["Namespace: team-b"]
        SB["Service<br>api-svc"]
        PB["Pod B"]
        SB --> PB
    end
    PA -->|"api-svc.team-b.svc.cluster.local"| SB
Access MethodExampleDescription
Same Namespaceapi-svcAccess by Service name only
Different Namespaceapi-svc.team-bAppend Namespace name
Full FQDNapi-svc.team-b.svc.cluster.localComplete DNS name

Hands-on: Multi-Tenant Setup with Namespaces#

Configure Namespace and Resource Limits#

# Create Namespace
kubectl create namespace team-a

# Apply ResourceQuota
kubectl apply -f resourcequota.yaml

# Apply LimitRange
kubectl apply -f limitrange.yaml

# Verify configuration
kubectl describe namespace team-a

Deploy Resources and Verify#

# Create Deployment in team-a Namespace
kubectl apply -f deployment.yaml -n team-a

# Check resource usage
kubectl describe resourcequota team-a-quota -n team-a

# Expected output:
# Name:                   team-a-quota
# Resource                Used    Hard
# --------                ----    ----
# limits.cpu              1       8
# limits.memory           512Mi   16Gi
# pods                    2       20
# requests.cpu            200m    4
# requests.memory         256Mi   8Gi

Frequently Used kubectl Commands#

CommandDescription
kubectl get namespacesList Namespaces
kubectl create namespace <name>Create Namespace
kubectl delete namespace <name>Delete Namespace (deletes all internal resources)
kubectl get all -n <namespace>List resources in a specific Namespace
kubectl describe resourcequota -n <namespace>Check resource usage
Namespace Deletion Warning
Deleting a Namespace also deletes all resources within it (Pods, Services, ConfigMaps, etc.). Always verify before deleting.

Next Steps#

Now that you understand Namespaces, proceed to the following:

GoalRecommended Document
Stateful workloadsStatefulSet
Access controlRBAC
Network policiesNetworkPolicy