Lesson 2.2: Namespaces and Resource Quotas


Kubernetes Namespaces

A Namespace in Kubernetes is a virtual cluster or a logical boundary that allows you to partition and isolate resources within a single physical Kubernetes cluster. Namespaces enable multiple teams, projects, or environments (e.g., development, staging, production) to share the same cluster while avoiding conflicts and maintaining resource separation.

Why Use Namespaces?

  • Resource Isolation:
    • Separate resources (e.g., Pods, Services, Deployments) for different teams, projects, or environments.
    • Example: A dev namespace for development and a prod namespace for production.
  • Access Control:
    • Apply role-based access control (RBAC) to restrict users or teams to specific namespaces.
  • Avoid Naming Conflicts:
    • Resources can have the same name in different namespaces (e.g., a frontend Deployment in both dev and prod).
  • Resource Quotas:
    • Enforce resource limits (CPU, memory) per namespace to prevent overconsumption.
  • Logical Grouping:
    • Organize resources into logical groups (e.g., monitoring for Prometheus and Grafana).

How Namespaces Work

  • Default Namespaces:
    • Kubernetes creates a few namespaces by default:
      • default: For resources created without specifying a namespace.
      • kube-system: For Kubernetes system components (e.g., kube-proxy, CoreDNS).
      • kube-public: For publicly accessible resources (rarely used).
      • kube-node-lease: For node lease objects (used internally for node heartbeats).
  • Custom Namespaces:
    • You can create namespaces like dev, prod, or team-a.
  • Scoped Resources:
    • Most Kubernetes objects (e.g., Pods, Services, Deployments) are namespaced.
    • Cluster-wide resources (e.g., Nodes, PersistentVolumes, ClusterRoles) are not namespaced.

Getting namespaces

[root@master ~]# kubectl get ns NAME STATUS AGE default Active 3h47m kube-node-lease Active 3h47m kube-public Active 3h47m kube-system Active 3h47m local-path-storage Active 3h47m # OR [root@master ~]# kubectl get namespaces NAME STATUS AGE default Active 3h47m kube-node-lease Active 3h47m kube-public Active 3h47m kube-system Active 3h47m local-path-storage Active 3h47m

Creating namespaces

[root@master ~]# kubectl create namespace dev namespace/dev created # OR [root@master ~]# cat ns.yml apiVersion: v1 kind: Namespace metadata: name: prod [root@master ~]# kubectl apply -f ns.yml namespace/prod created [root@master ~]# kubectl get ns NAME STATUS AGE default Active 3h48m dev Active 27s prod Active 5s

Creating Resources with namespace

[root@master ~]# cat deploy-nginx.yml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deploy namespace: dev labels: env: demo spec: template: metadata: name: nginx labels: env: demo annotations: kubernetes.io/change-cause: "Deployment with nginx:1.27.4-alpine" spec: containers: - name: nginx image: nginx:1.27.4-alpine replicas: 3 selector: matchLabels: env: demo [root@master ~]# kubectl apply -f deploy-nginx.yml # Without providing the namespace [root@master ~]# kubectl get deployments No resources found in default namespace. [root@master ~]# kubectl get pods NAME READY STATUS RESTARTS AGE nginx-rc-8ct8h 1/1 Running 0 3h53m nginx-rc-gfhzz 1/1 Running 0 3h53m nginx-rc-k2wcr 1/1 Running 0 3h53m # Using the provided namespace [root@master ~]# kubectl get deployments --namespace dev NAME READY UP-TO-DATE AVAILABLE AGE nginx-deploy 3/3 3 3 3m43s [root@master ~]# kubectl get pods --namespace dev NAME READY STATUS RESTARTS AGE nginx-deploy-6dc6975759-bztj2 1/1 Running 0 3m49s nginx-deploy-6dc6975759-c282t 1/1 Running 0 3m49s nginx-deploy-6dc6975759-chwlt 1/1 Running 0 3m49s # Getting all the resources [root@master ~]# kubectl get deployments --all-namespaces NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE dev nginx-deploy 3/3 3 3 4m59s kube-system coredns 2/2 2 2 3h57m local-path-storage local-path-provisioner 1/1 1 1 3h57m [root@master ~]# kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE default nginx-rc-8ct8h 1/1 Running 0 3h54m default nginx-rc-gfhzz 1/1 Running 0 3h54m default nginx-rc-k2wcr 1/1 Running 0 3h54m dev nginx-deploy-6dc6975759-bztj2 1/1 Running 0 5m9s dev nginx-deploy-6dc6975759-c282t 1/1 Running 0 5m9s dev nginx-deploy-6dc6975759-chwlt 1/1 Running 0 5m9s

Deleting deployment with namespace

# nginx-deploy deployment not deleted becuase it lies in the namespace [root@master ~]# kubectl delete deployment nginx-deploy Error from server (NotFound): deployments.apps "nginx-deploy" not found # You have to mention the namespace [root@master ~]# kubectl delete deployment nginx-deploy --namespace dev deployment.apps "nginx-deploy" deleted

Common Use Cases

  • Multi-Tenancy:
    • Different teams (e.g., team-a, team-b) use separate namespaces to avoid conflicts.
  • Environment Separation:
    • Use dev, staging, and prod namespaces for different stages of the software lifecycle.
  • Access Control:
    • Restrict developers to the dev namespace while allowing admins full cluster access.
  • Resource Quotas:
    • Limit the dev namespace to 4 CPUs and 8GB RAM, while prod has higher limits.
  • Monitoring and Logging:
    • Deploy monitoring tools (e.g., Prometheus, Grafana) in a dedicated monitoring namespace.

Limitations of Namespaces

  • No Nested Namespaces:
    • Namespaces cannot be nested (e.g., dev/frontend is not allowed).
  • Cluster-Scoped Resources:
    • Some resources (e.g., Nodes, PersistentVolumes) are not namespaced.
  • DNS for Services:
    • Services in different namespaces can be accessed via <service-name>.<namespace>.svc.cluster.local.
  • No Network Isolation:
    • Namespaces do not isolate network traffic by default. Use Network Policies for this.

Example of namespace

# Information dev [root@master ~]# kubectl get deploy --namespace=dev NAME READY UP-TO-DATE AVAILABLE AGE nginx-deploy-dev 3/3 3 3 16h [root@master ~]# kubectl get pods --namespace=dev -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deploy-dev-6dc6975759-b6fpg 1/1 Running 0 16h 10.244.1.10 cka-cluster2-worker <none> <none> nginx-deploy-dev-6dc6975759-fxh8j 1/1 Running 0 16h 10.244.2.8 cka-cluster2-worker2 <none> <none> nginx-deploy-dev-6dc6975759-zhxvf 1/1 Running 0 16h 10.244.2.7 cka-cluster2-worker2 <none> <none> [root@master ~]# kubectl get svc --namespace=dev No resources found in dev namespace. # Accessing prod pod using pod ip [root@master ~]# kubectl exec -it nginx-deploy-dev-6dc6975759-b6fpg --namespace=dev -- sh / # curl 10.244.1.8 <html> <h1>Welcome to nginx!</h1> </html> # Create service in dev namespace [root@master ~]# kubectl expose deployment nginx-deploy-dev --name=svc-dev --port 80 --namespace=dev service/svc-dev exposed [root@master ~]# kubectl get svc --namespace=dev NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE svc-dev ClusterIP 10.96.69.18 <none> 80/TCP 15s # Curl using the svc IP [root@master ~]# kubectl exec -it nginx-deploy-dev-6dc6975759-b6fpg --namespace=dev -- sh / # curl 10.96.219.79 <html> <h1>Welcome to nginx!</h1> </html> # Curl using the svc name of prod / # curl svc-prod curl: (6) Could not resolve host: svc-prod # Curl using FQDN, if the ndots is set to 5 then remove this part for dev pods / # cat /etc/resolv.conf search dev.svc.cluster.local svc.cluster.local cluster.local localdomain nameserver 10.96.0.10 # options ndots:5 / # curl svc-prod.prod.svc.cluster.local <html> <title>Welcome to nginx!</title> </html> # ------------- # Information prod [root@master ~]# kubectl get deploy --namespace=prod NAME READY UP-TO-DATE AVAILABLE AGE nginx-deploy-prod 3/3 3 3 16h [root@master ~]# kubectl get pods --namespace=prod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deploy-prod-6dc6975759-dzfvl 1/1 Running 0 16h 10.244.1.8 cka-cluster2-worker <none> <none> nginx-deploy-prod-6dc6975759-ldtlw 1/1 Running 0 16h 10.244.2.6 cka-cluster2-worker2 <none> <none> nginx-deploy-prod-6dc6975759-m2cj9 1/1 Running 0 16h 10.244.1.9 cka-cluster2-worker <none> <none> [root@master ~]# kubectl get svc --namespace=prod No resources found in prod namespace. [root@master ~]# # Accessing dev pod using pod ip / # curl 10.244.1.10 <html> <title>Welcome to nginx!</title> </html> # Create service in prod namespace [root@master ~]# kubectl expose deployment nginx-deploy-prod --name=svc-prod --port=80 --namespace=prod service/svc-prod exposed [root@master ~]# kubectl get svc --namespace=prod NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE svc-prod ClusterIP 10.96.219.79 <none> 80/TCP 8s # Curl using the svc IP [root@master ~]# kubectl exec -it nginx-deploy-prod-6dc6975759-dzfvl --namespace=prod -- sh / # curl 10.96.69.18 <html> <h1>Welcome to nginx!</h1> </html> # Curl using the svc name of dev / # curl svc-dev curl: (6) Could not resolve host: svc-dev # Curl using FQDN, if the ndots is set to 5 then remove this part for prod pods / # cat /etc/resolv.conf search prod.svc.cluster.local svc.cluster.local cluster.local localdomain nameserver 10.96.0.10 # options ndots:5 / # curl svc-dev.dev.svc.cluster.local <!DOCTYPE html> <html> <title>Welcome to nginx!</title> </html>

In this example:

  • dev namespace contains nginx-deploy-dev deployment and svc-dev service
  • prod namespace contains nginx-deploy-prod deployment and svc-prod service

Resources in different namespaces can communicate directly using:

  • Pod IP addresses (cluster-wide)
    • (e.g., 10.244.1.10) are cluster-wide unique:
    • curl 10.244.1.8 (pod in prod namespace) worked
    • curl 10.244.1.10 (pod in dev namespace) worked
  • Service IP addresses (cluster-wide)
    • curl 10.96.219.79 (prod service) worked
    • curl 10.96.69.18 (dev service) worked
  • Fully Qualified Domain Names (FQDNs)
    • When you tried curl svc-prod from dev namespace, it didn't work curl: (6) Could not resolve host: svc-prod
    • But using FQDN worked: curl svc-prod.prod.svc.cluster.local Namespaces don't provide network isolation by default - they only provide logical separation.

ndots:5: "If a domain name has 5 or more dots, try it as-is first before appending search domains", so remove it.

All systems normal

© 2025 2023 Sanjeeb KC. All rights reserved.