Qingular

命名空间与多租户

·CKAk8s练习

命名空间管理、ResourceQuota、LimitRange、资源隔离与跨命名空间通信

← 返回 CKA 练习目录

概述

命名空间(Namespace)提供 Kubernetes 集群内的资源隔离机制。CKA 考试重点考察命名空间创建、ResourceQuota 和 LimitRange 配置,以及命名空间级别的资源管理。


一、命名空间创建与管理

1.1 创建命名空间

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

# 声明式 YAML
apiVersion: v1
kind: Namespace
metadata:
  name: team-a
# 生成 YAML
kubectl create namespace team-a --dry-run=client -o yaml

1.2 查看命名空间

# 查看所有命名空间
kubectl get namespaces
kubectl get ns

# 查看命名空间详情
kubectl describe namespace team-a

# 查看命名空间的资源配额
kubectl get quota -n team-a
kubectl describe quota -n team-a

# 查看命名空间中的资源
kubectl get all -n team-a
kubectl get pods,svc,deploy -n team-a

1.3 切换命名空间

# 在命令中指定命名空间
kubectl get pods -n team-a
kubectl get pods --namespace=team-a

# 所有命名空间
kubectl get pods --all-namespaces
kubectl get pods -A

# 设置 kubectl 上下文默认命名空间(考试不常用,API Server 侧不保存)
kubectl config set-context --current --namespace=team-a

1.4 删除命名空间

# 删除命名空间(会删除其下所有资源)
kubectl delete namespace team-a

# 强制删除 Terminating 状态的命名空间
kubectl delete namespace team-a --force --grace-period=0

二、ResourceQuota

ResourceQuota 限制命名空间内资源的总使用量。

2.1 计算资源配额

apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: team-a
spec:
  hard:
    requests.cpu: "4"           # CPU requests 总上限
    requests.memory: "8Gi"      # 内存 requests 总上限
    limits.cpu: "8"             # CPU limits 总上限
    limits.memory: "16Gi"       # 内存 limits 总上限
# 命令式创建
kubectl create quota compute-quota -n team-a \
  --hard=requests.cpu=4,requests.memory=8Gi,limits.cpu=8,limits.memory=16Gi

# 查看
kubectl get quota -n team-a
kubectl describe quota compute-quota -n team-a

# 查看使用情况(Used / Hard)
kubectl get quota compute-quota -n team-a -o yaml

2.2 对象数量配额

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"       # 禁止 NodePort Service
# 命令式
kubectl create quota object-quota -n team-a \
  --hard=pods=10,services=5,configmaps=5,secrets=5

2.3 配额范围(Scope)

apiVersion: v1
kind: ResourceQuota
metadata:
  name: scoped-quota
  namespace: team-a
spec:
  hard:
    cpu: "2"
    memory: "2Gi"
  scopes:
  - BestEffort          # 仅对 BestEffort QoS 的 Pod 生效

可用 Scope:

Scope说明
BestEffortBestEffort QoS Pod
NotBestEffort非 BestEffort QoS Pod
Terminatingspec.activeDeadlineSeconds 有值
NotTerminatingspec.activeDeadlineSeconds 无值
PriorityClass指定 PriorityClass
# 对指定 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 配额与 LimitRange 的关系

重要:当设置了 ResourceQuota(如 requests.cpu)后,创建 Pod 必须设置 CPU requests。因此必须配合 LimitRange 提供默认值。

# 正确顺序:
# 1. 创建 LimitRange(提供默认值)
# 2. 创建 ResourceQuota(限制总量)
# 3. 创建 Pod(默认使用 LimitRange 的值)

# LimitRange 必须在 ResourceQuota 之前存在,否则创建 Pod 会因没有 requests 被拒绝

三、LimitRange

LimitRange 设置命名空间内 Pod / 容器的默认资源限制。

3.1 完整的 LimitRange 配置

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:                # 默认 limits
      cpu: 500m
      memory: 256Mi
    defaultRequest:         # 默认 requests
      cpu: 250m
      memory: 128Mi
    max:
      cpu: "2"
      memory: "4Gi"
    min:
      cpu: 50m
      memory: 32Mi
  - type: PersistentVolumeClaim
    max:
      storage: 100Gi
    min:
      storage: 1Gi
# 创建 LimitRange
kubectl apply -f limitrange.yaml

# 查看
kubectl get limitrange -n team-a
kubectl get limits -n team-a
kubectl describe limitrange resource-limits -n team-a

3.2 LimitRange 注意事项

  • 只对创建后新提交的 Pod 生效,不影响已有 Pod
  • 如果 Pod 设置的值超过 LimitRange 的 max/min,Pod 会被拒绝
  • 可以为不同类型(Pod / Container / PVC)分别设置

四、命名空间级别的资源隔离

4.1 网络隔离

默认情况下,不同命名空间的 Pod 可以相互通信。网络策略(NetworkPolicy)可限制跨命名空间通信。

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   # 只允许本命名空间

CKA 考试 NetworkPolicy 在 Domain 5,这里只做了解。

4.2 服务发现隔离

# 跨命名空间访问 Service
# 格式:<service>.<namespace>.svc.cluster.local
curl http://web-service.team-b.svc.cluster.local

# 同一命名空间:直接使用服务名
curl http://web-service

4.3 资源配额隔离

# 为每个团队创建隔离环境
kubectl create namespace team-a
kubectl create namespace team-b

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

# team-b:内存密集型
kubectl create quota -n team-b --hard=requests.cpu=4,limits.cpu=8,requests.memory=32Gi,pods=10

五、跨命名空间通信

5.1 DNS 格式

<service-name>.<namespace>.svc.cluster.local
# 从 team-a 命名空间访问 team-b 中的数据库
kubectl run -n team-a test --image=busybox --rm -it --restart=Never -- \
  wget -O- http://db-service.team-b.svc.cluster.local:3306

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

5.2 跨命名空间访问 Secret/ConfigMap

# 默认情况下不能跨命名空间引用
# 错误示例:team-a 的 Pod 不能引用 team-b 的 ConfigMap

# 解决方案:将配置复制到目标命名空间
kubectl get secret db-secret -n team-b -o yaml | sed 's/namespace: team-b/namespace: team-a/' | kubectl apply -f -

六、考试实用命令

# 1. 快速创建命名空间和配额
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. 同时创建 LimitRange(必须要有,否则 Pod 因无 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. 在命名空间中创建资源
kubectl run nginx -n development --image=nginx
kubectl create deployment web -n development --image=nginx --replicas=3

# 4. 查看命名空间的资源使用情况
kubectl get quota -n development
kubectl describe quota dev-quota -n development

# 5. 列出所有命名空间中的所有 Pod
kubectl get pods -A

# 6. 从指定命名空间获取资源
kubectl get all -n team-a

# 7. 删除命名空间(及其所有资源)
kubectl delete ns development

# 8. 在命名空间中限制网络端口类型
kubectl create quota net-quota -n team-a \
  --hard=services.loadbalancers=0,services.nodeports=0

七、考试重点总结

概念命令 / 语法频率
创建命名空间kubectl create ns <name>
ResourceQuotakubectl create quota --hard=...
LimitRangeYAML 创建,kubectl apply -f
配额检查kubectl describe quota
跨命名空间 DNS<svc>.<ns>.svc.cluster.local
删除命名空间kubectl delete ns <name>

典型场景:为团队创建隔离环境

# 完整流程
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

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

考试技巧:注意 kubectl create quota 不支持 --dry-run=client -o yaml(CKA 1.29 +)。如果考试版本不支持,使用 kubectl create quota --help 确认,或者直接用 YAML 创建。


🧪 完整操作实例:为命名空间设置 ResourceQuota 并验证限制

场景描述

创建一个命名空间并设置 ResourceQuota,验证超配额时创建 Pod 被拒绝。

前置条件

  • 可用的 Kubernetes 集群
  • kubectl 已配置连接集群

操作步骤

Step 1: 创建命名空间和 LimitRange

kubectl create namespace team-a
# 预期输出:namespace/team-a created

# 创建 LimitRange 提供默认资源值(ResourceQuota 要求 Pod 必须设置 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
# 预期输出:limitrange/default-limits created

Step 2: 创建 ResourceQuota

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

# 查看 ResourceQuota
kubectl describe quota team-quota -n team-a
# 预期输出:
# Name:            team-quota
# Namespace:       team-a
# Resource         Used  Hard
# ----             ---   ----
# pods             0     3
# requests.cpu      0     1
# requests.memory   0     1Gi

Step 3: 创建配额内的 Pod

# 创建第 1 个 Pod
kubectl run nginx-1 -n team-a --image=nginx
# 预期输出:pod/nginx-1 created

# 创建第 2 个 Pod(--limits 和 --requests 同时设置,保证不超过 CPU 配额)
kubectl run nginx-2 -n team-a --image=nginx
# 预期输出:pod/nginx-2 created

# 查看配额使用情况
kubectl describe quota team-quota -n team-a
# 预期输出:
# Resource         Used  Hard
# ----             ---   ----
# pods             2     3
# requests.cpu      500m  1
# requests.memory   256Mi 1Gi

Step 4: 创建超出 CPU 配额的 Pod(应被拒绝)

kubectl run nginx-big -n team-a --image=nginx \
  --requests='cpu=1,memory=512Mi'
# 预期输出: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 配额:已用 500m + 请求 1 = 1.5,超过配额 1

Step 5: 创建第 3 个 Pod 达到 Pod 数上限

# 创建第 3 个正常 Pod
kubectl run nginx-3 -n team-a --image=nginx
# 预期输出:pod/nginx-3 created

kubectl describe quota team-quota -n team-a
# 预期输出:pods Used 变为 3/3

# 创建第 4 个 Pod(超过 Pod 数量配额)
kubectl run nginx-4 -n team-a --image=nginx
# 预期输出:Error from server (Forbidden): pods "nginx-4" is forbidden: exceeded quota: team-quota, requested: pods=1, used: pods=3, limited: pods=3

验证结果

# 确认只有 3 个 Pod 运行
kubectl get pods -n team-a
# 预期输出:nginx-1, nginx-2, nginx-3 均为 Running 状态,nginx-4 不存在

# 查看最终配额使用
kubectl get quota -n team-a
# 预期输出:
# NAME         AGE   REQUEST
# team-quota   5m   pods: 3/3, requests.cpu: 750m/1, requests.memory: 384Mi/1Gi

# 清理
kubectl delete namespace team-a
# 预期输出:namespace "team-a" deleted

考试提示

  • 设置了 ResourceQuota(如 requests.cpu)后,创建 Pod 必须设置 CPU requests,否则 API Server 拒绝
  • 因此 ResourceQuota 通常与 LimitRange 配合使用,由 LimitRange 提供默认值
  • 考试中 kubectl create quota 如果报错不支持 --dry-run,直接用 YAML 创建
  • kubectl describe quota 是最常用的检查配额使用情况的命令,同时显示 Used 和 Hard
  • 如果 Pod 创建失败并显示 exceeded quota,说明命名空间资源已达上限
  • 删除命名空间会清理其下所有资源(Pod、ConfigMap、Secret、Quota 等),考试中很方便

官方文档链接