Qingular

Namespaces and Multi-Tenancy

·CKAk8s练习

Namespace management, ResourceQuota, LimitRange, resource isolation, and cross-namespace communication

← Back to CKA Practice Index

Overview

Namespaces provide a resource isolation mechanism within a Kubernetes cluster. The CKA exam focuses on namespace creation, ResourceQuota and LimitRange configuration, and namespace-level resource management.


1. Namespace Creation and Management

1.1 Creating Namespaces

kubectl create namespace team-a
kubectl create ns team-b

# Declarative YAML
apiVersion: v1
kind: Namespace
metadata:
  name: team-a
# Generate YAML
kubectl create namespace team-a --dry-run=client -o yaml

1.2 Viewing Namespaces

# View all namespaces
kubectl get namespaces
kubectl get ns

# View namespace details
kubectl describe namespace team-a

# View resource quotas in a namespace
kubectl get quota -n team-a
kubectl describe quota -n team-a

# View resources in a namespace
kubectl get all -n team-a
kubectl get pods,svc,deploy -n team-a

1.3 Switching Namespaces

# Specify the namespace in commands
kubectl get pods -n team-a
kubectl get pods --namespace=team-a

# All namespaces
kubectl get pods --all-namespaces
kubectl get pods -A

# Set the default namespace for kubectl context (not commonly used in the exam; not persisted server-side)
kubectl config set-context --current --namespace=team-a

1.4 Deleting Namespaces

# Delete a namespace (deletes all resources within it)
kubectl delete namespace team-a

# Force delete a namespace stuck in Terminating state
kubectl delete namespace team-a --force --grace-period=0

2. ResourceQuota

ResourceQuota limits the total resource usage within a namespace.

2.1 Compute Resource Quota

apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: team-a
spec:
  hard:
    requests.cpu: "4"           # Total CPU requests upper limit
    requests.memory: "8Gi"      # Total memory requests upper limit
    limits.cpu: "8"             # Total CPU limits upper limit
    limits.memory: "16Gi"       # Total memory limits upper limit
# Imperative creation
kubectl create quota compute-quota -n team-a \
  --hard=requests.cpu=4,requests.memory=8Gi,limits.cpu=8,limits.memory=16Gi

# View
kubectl get quota -n team-a
kubectl describe quota compute-quota -n team-a

# View usage (Used / Hard)
kubectl get quota compute-quota -n team-a -o yaml

2.2 Object Count Quota

apiVersion: v1
kind: ResourceQuota
metadata:
  name: object-quota
  namespace: team-a
spec:
  hard:
    pods: "10"
    services: "5"
    configmaps: "5"
    secrets: "5"
    persistentvolumeclaims: "3"
    replicationcontrollers: "5"
    services.loadbalancers: "2"
    services.nodeports: "0"       # Disallow NodePort Services
# Imperative
kubectl create quota object-quota -n team-a \
  --hard=pods=10,services=5,configmaps=5,secrets=5

2.3 Quota Scopes

apiVersion: v1
kind: ResourceQuota
metadata:
  name: scoped-quota
  namespace: team-a
spec:
  hard:
    cpu: "2"
    memory: "2Gi"
  scopes:
  - BestEffort          # Only applies to BestEffort QoS Pods

Available Scopes:

ScopeDescription
BestEffortBestEffort QoS Pod
NotBestEffortNon-BestEffort QoS Pod
Terminatingspec.activeDeadlineSeconds is set
NotTerminatingspec.activeDeadlineSeconds is not set
PriorityClassSpecified PriorityClass
# Quota for a specific PriorityClass
apiVersion: v1
kind: ResourceQuota
metadata:
  name: priority-quota
  namespace: team-a
spec:
  hard:
    pods: "5"
  scopeSelector:
    matchExpressions:
    - operator: In
      scopeName: PriorityClass
      values:
      - high-priority

2.4 Relationship Between Quota and LimitRange

Important: When a ResourceQuota is set (e.g., requests.cpu), Pods must specify CPU requests when created. Therefore, a LimitRange must be used in conjunction to provide default values.

# Correct order:
# 1. Create LimitRange (provides default values)
# 2. Create ResourceQuota (limits total)
# 3. Create Pods (default to LimitRange values)

# LimitRange must exist before ResourceQuota, otherwise Pod creation will be rejected for lacking requests

3. LimitRange

LimitRange sets default resource limits for Pods/containers within a namespace.

3.1 Complete LimitRange Configuration

apiVersion: v1
kind: LimitRange
metadata:
  name: resource-limits
  namespace: team-a
spec:
  limits:
  - type: Pod
    max:
      cpu: "4"
      memory: "8Gi"
    min:
      cpu: 100m
      memory: 64Mi
  - type: Container
    default:                # Default limits
      cpu: 500m
      memory: 256Mi
    defaultRequest:         # Default requests
      cpu: 250m
      memory: 128Mi
    max:
      cpu: "2"
      memory: "4Gi"
    min:
      cpu: 50m
      memory: 32Mi
  - type: PersistentVolumeClaim
    max:
      storage: 100Gi
    min:
      storage: 1Gi
# Create LimitRange
kubectl apply -f limitrange.yaml

# View
kubectl get limitrange -n team-a
kubectl get limits -n team-a
kubectl describe limitrange resource-limits -n team-a

3.2 LimitRange Notes

  • Only affects Pods created after the LimitRange is applied; does not affect existing Pods
  • If a Pod's values exceed the LimitRange's max/min, the Pod will be rejected
  • Different types (Pod / Container / PVC) can be configured separately

4. Namespace-Level Resource Isolation

4.1 Network Isolation

By default, Pods in different namespaces can communicate with each other. NetworkPolicies can restrict cross-namespace communication.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-cross-ns
  namespace: team-a
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: team-a   # Only allow this namespace

NetworkPolicy is in CKA Domain 5; this is for awareness only.

4.2 Service Discovery Isolation

# Cross-namespace Service access
# Format: <service>.<namespace>.svc.cluster.local
curl http://web-service.team-b.svc.cluster.local

# Same namespace: use the service name directly
curl http://web-service

4.3 Resource Quota Isolation

# Create isolated environments for each team
kubectl create namespace team-a
kubectl create namespace team-b

# team-a: CPU-intensive
kubectl create quota -n team-a --hard=requests.cpu=8,limits.cpu=16,requests.memory=16Gi,pods=20

# team-b: Memory-intensive
kubectl create quota -n team-b --hard=requests.cpu=4,limits.cpu=8,requests.memory=32Gi,pods=10

5. Cross-Namespace Communication

5.1 DNS Format

<service-name>.<namespace>.svc.cluster.local
# Access a database in team-b from the team-a namespace
kubectl run -n team-a test --image=busybox --rm -it --restart=Never -- \
  wget -O- http://db-service.team-b.svc.cluster.local:3306

# Or use netshoot
kubectl run -n team-a netshoot --image=nicolaka/netshoot --rm -it --restart=Never -- \
  curl http://db-service.team-b:3306

5.2 Cross-Namespace Secret/ConfigMap Access

# By default, cross-namespace references are not allowed
# Incorrect example: a Pod in team-a cannot reference a ConfigMap in team-b

# Solution: copy the configuration to the target namespace
kubectl get secret db-secret -n team-b -o yaml | sed 's/namespace: team-b/namespace: team-a/' | kubectl apply -f -

6. Practical Exam Commands

# 1. Quickly create a namespace and quota
kubectl create ns development
kubectl create quota dev-quota -n development \
  --hard=requests.cpu=2,requests.memory=4Gi,limits.cpu=4,limits.memory=8Gi,pods=10

# 2. Simultaneously create a LimitRange (must exist, otherwise Pods will be rejected for lacking requests)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: LimitRange
metadata:
  name: dev-limits
  namespace: development
spec:
  limits:
  - type: Container
    default:
      cpu: 500m
      memory: 256Mi
    defaultRequest:
      cpu: 250m
      memory: 128Mi
EOF

# 3. Create resources in the namespace
kubectl run nginx -n development --image=nginx
kubectl create deployment web -n development --image=nginx --replicas=3

# 4. View resource usage in the namespace
kubectl get quota -n development
kubectl describe quota dev-quota -n development

# 5. List all Pods across all namespaces
kubectl get pods -A

# 6. Get resources from a specific namespace
kubectl get all -n team-a

# 7. Delete a namespace (and all its resources)
kubectl delete ns development

# 8. Restrict network port types in a namespace
kubectl create quota net-quota -n team-a \
  --hard=services.loadbalancers=0,services.nodeports=0

7. Exam Key Points Summary

ConceptCommand / SyntaxFrequency
Create namespacekubectl create ns <name>High
ResourceQuotakubectl create quota --hard=...Medium
LimitRangeYAML creation, kubectl apply -fMedium
Quota inspectionkubectl describe quotaMedium
Cross-namespace DNS<svc>.<ns>.svc.cluster.localLow
Delete namespacekubectl delete ns <name>Medium

Typical Scenario: Creating an Isolated Environment for a Team

# Full workflow
kubectl create ns team-green
kubectl create quota green-quota -n team-green \
  --hard=requests.cpu=4,requests.memory=8Gi,pods=15

kubectl apply -f - <<EOF
apiVersion: v1
kind: LimitRange
metadata:
  name: green-limits
  namespace: team-green
spec:
  limits:
  - type: Container
    default:
      cpu: 500m
      memory: 256Mi
    defaultRequest:
      cpu: 200m
      memory: 128Mi
EOF

# Verify
kubectl get quota -n team-green
kubectl run nginx -n team-green --image=nginx
kubectl get pods -n team-green

Exam Tip: Note that kubectl create quota may not support --dry-run=client -o yaml (CKA 1.29+). If the exam version does not support it, use kubectl create quota --help to confirm, or create directly via YAML.


🧪 Complete Hands-on Example: Setting ResourceQuota for a Namespace and Verifying Limits

Scenario

Create a namespace and set a ResourceQuota, then verify that Pod creation is rejected when the quota is exceeded.

Prerequisites

  • A working Kubernetes cluster
  • kubectl configured to connect to the cluster

Steps

Step 1: Create a Namespace and LimitRange

kubectl create namespace team-a
# Expected output: namespace/team-a created

# Create a LimitRange to provide default resource values (ResourceQuota requires Pods to set requests)
cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: LimitRange
metadata:
  name: default-limits
  namespace: team-a
spec:
  limits:
  - default:
      cpu: "500m"
      memory: "256Mi"
    defaultRequest:
      cpu: "250m"
      memory: "128Mi"
    type: Container
EOF
# Expected output: limitrange/default-limits created

Step 2: Create a ResourceQuota

kubectl create quota team-quota -n team-a \
  --hard=requests.cpu=1,requests.memory=1Gi,pods=3
# Expected output: resourcequota/team-quota created

# View the ResourceQuota
kubectl describe quota team-quota -n team-a
# Expected output:
# Name:            team-quota
# Namespace:       team-a
# Resource         Used  Hard
# ----             ---   ----
# pods             0     3
# requests.cpu      0     1
# requests.memory   0     1Gi

Step 3: Create Pods Within the Quota

# Create the 1st Pod
kubectl run nginx-1 -n team-a --image=nginx
# Expected output: pod/nginx-1 created

# Create the 2nd Pod (both --limits and --requests are set, ensuring the CPU quota is not exceeded)
kubectl run nginx-2 -n team-a --image=nginx
# Expected output: pod/nginx-2 created

# Check quota usage
kubectl describe quota team-quota -n team-a
# Expected output:
# Resource         Used  Hard
# ----             ---   ----
# pods             2     3
# requests.cpu      500m  1
# requests.memory   256Mi 1Gi

Step 4: Create a Pod Exceeding CPU Quota (Should Be Rejected)

kubectl run nginx-big -n team-a --image=nginx \
  --requests='cpu=1,memory=512Mi'
# Expected output: Error from server (Forbidden): pods "nginx-big" is forbidden: exceeded quota: team-quota, requested: requests.cpu=1, used: requests.cpu=500m, limited: requests.cpu=1
# CPU requests quota: used 500m + requested 1 = 1.5, exceeds the quota of 1

Step 5: Create the 3rd Pod, Reaching the Pod Count Limit

# Create the 3rd normal Pod
kubectl run nginx-3 -n team-a --image=nginx
# Expected output: pod/nginx-3 created

kubectl describe quota team-quota -n team-a
# Expected output: pods Used changes to 3/3

# Create the 4th Pod (exceeds the Pod count quota)
kubectl run nginx-4 -n team-a --image=nginx
# Expected output: Error from server (Forbidden): pods "nginx-4" is forbidden: exceeded quota: team-quota, requested: pods=1, used: pods=3, limited: pods=3

Verification

# Confirm only 3 Pods are running
kubectl get pods -n team-a
# Expected output: nginx-1, nginx-2, nginx-3 all in Running state; nginx-4 does not exist

# View final quota usage
kubectl get quota -n team-a
# Expected output:
# NAME         AGE   REQUEST
# team-quota   5m   pods: 3/3, requests.cpu: 750m/1, requests.memory: 384Mi/1Gi

# Clean up
kubectl delete namespace team-a
# Expected output: namespace "team-a" deleted

Exam Tips

  • After setting a ResourceQuota (e.g., requests.cpu), Pods must set CPU requests when created, otherwise the API Server rejects them
  • Therefore, ResourceQuota is usually used together with LimitRange, which provides default values
  • In the exam, if kubectl create quota errors on --dry-run, create via YAML directly
  • kubectl describe quota is the most commonly used command for checking quota usage, showing both Used and Hard
  • If Pod creation fails with exceeded quota, it means the namespace's resources have reached their upper limit
  • Deleting a namespace cleans up all resources within it (Pods, ConfigMaps, Secrets, Quotas, etc.), which is very convenient during the exam