Skip to content

Namespaces — Example Manifests

simple-namespace.yaml — Basic Namespace definition

# Simple namespace definition
apiVersion: v1
kind: Namespace
metadata:
  name: development
  labels:
    environment: dev
    team: platform
  annotations:
    description: "Development environment for testing new features"

namespace-with-quota.yaml — Namespace with ResourceQuota

# Development environment with quotas and limits
apiVersion: v1
kind: Namespace
metadata:
  name: development
  labels:
    environment: dev
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: dev-quota
  namespace: development
spec:
  hard:
    # Compute resources
    requests.cpu: "4"
    requests.memory: 8Gi
    limits.cpu: "8"
    limits.memory: 16Gi

    # Object counts
    pods: "10"
    services: "5"
    persistentvolumeclaims: "3"
    configmaps: "10"
    secrets: "10"

    # Storage
    requests.storage: 20Gi
---
apiVersion: v1
kind: LimitRange
metadata:
  name: dev-limits
  namespace: development
spec:
  limits:
  # Container defaults and limits
  - type: Container
    default:  # Default limits if not specified
      cpu: 300m
      memory: 512Mi
    defaultRequest:  # Default requests if not specified
      cpu: 100m
      memory: 128Mi
    max:  # Maximum allowed
      cpu: "1"
      memory: 2Gi
    min:  # Minimum required
      cpu: 50m
      memory: 64Mi

  # Pod limits (all containers combined)
  - type: Pod
    max:
      cpu: "2"
      memory: 4Gi

  # PVC limits
  - type: PersistentVolumeClaim
    min:
      storage: 1Gi
    max:
      storage: 10Gi
---
# Production environment with higher limits
apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    environment: prod
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: prod-quota
  namespace: production
spec:
  hard:
    requests.cpu: "20"
    requests.memory: 40Gi
    limits.cpu: "40"
    limits.memory: 80Gi
    pods: "50"
    services: "20"
    persistentvolumeclaims: "10"
    requests.storage: 100Gi
---
apiVersion: v1
kind: LimitRange
metadata:
  name: prod-limits
  namespace: production
spec:
  limits:
  - type: Container
    default:
      cpu: 500m
      memory: 1Gi
    defaultRequest:
      cpu: 250m
      memory: 512Mi
    max:
      cpu: "4"
      memory: 8Gi
    min:
      cpu: 100m
      memory: 128Mi
  - type: Pod
    max:
      cpu: "8"
      memory: 16Gi

cross-namespace-communication.yaml — Cross-namespace DNS

# Backend namespace and service
apiVersion: v1
kind: Namespace
metadata:
  name: backend
  labels:
    tier: backend
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
  namespace: backend
spec:
  replicas: 2
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
      - name: nginx
        image: nginx:1.25-alpine
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: api-service
  namespace: backend
spec:
  selector:
    app: api
  ports:
  - port: 8080
    targetPort: 80
---
# Frontend namespace
apiVersion: v1
kind: Namespace
metadata:
  name: frontend
  labels:
    tier: frontend
---
# Frontend pod that accesses backend service
apiVersion: v1
kind: Pod
metadata:
  name: web-client
  namespace: frontend
spec:
  containers:
  - name: client
    image: curlimages/curl:8.5.0
    command: ["/bin/sh", "-c"]
    args:
      - |
        echo "Testing cross-namespace communication..."
        echo ""
        echo "1. Short name (will fail - different namespace):"
        curl -v http://api-service:8080 2>&1 || echo "Failed - service not in same namespace"
        echo ""
        echo "2. Fully qualified domain name (will succeed):"
        curl -v http://api-service.backend.svc.cluster.local:8080
        echo ""
        echo "Sleeping..."
        sleep 3600
  restartPolicy: Never

# DNS Resolution in Kubernetes:
# Same namespace:     <service-name>
# Cross namespace:    <service-name>.<namespace>.svc.cluster.local
# External DNS:       <service-name>.<namespace>.svc.cluster.local

compose.yaml — Docker Compose comparison

# Docker Compose - Project-based isolation
# In Compose, isolation is achieved through project names
# Each docker-compose.yml in a different directory = different project

# Project 1: development (in ./dev directory)
# docker-compose up -d --project-name development
services:
  frontend:
    image: nginx:1.25-alpine
    networks:
      - app-network
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

  backend:
    image: nginx:1.25-alpine
    networks:
      - app-network
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

networks:
  app-network:

# Project 2: production (in ./prod directory)
# docker-compose up -d --project-name production
# (same services but different project)

# Kubernetes Equivalent:
# Multiple namespaces with ResourceQuotas
#
# kubectl create namespace development
# kubectl create namespace production
#
# Each namespace has its own:
# - ResourceQuota (like deploy.resources.limits but cluster-wide)
# - LimitRange (defaults for all pods)
# - RBAC (who can access)
# - NetworkPolicies (traffic isolation)

# Key Differences:
#
# 1. Isolation Level:
#    Compose: Project name + network
#    K8s: Namespace + NetworkPolicy
#
# 2. Resource Limits:
#    Compose: Per service (deploy.resources)
#    K8s: Per namespace (ResourceQuota) + per pod (LimitRange)
#
# 3. DNS:
#    Compose: service-name (within same project)
#    K8s: service-name (same namespace) or service.namespace.svc.cluster.local
#
# 4. Management:
#    Compose: docker-compose -p <project> up/down
#    K8s: kubectl -n <namespace> apply/delete
#
# 5. Default Behavior:
#    Compose: Project name from directory name
#    K8s: "default" namespace unless specified
#
# 6. Cleanup:
#    Compose: docker-compose down (removes project resources)
#    K8s: kubectl delete namespace <name> (removes all resources in namespace)