命名空间与多租户
命名空间管理、ResourceQuota、LimitRange、资源隔离与跨命名空间通信
概述
命名空间(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 | 说明 |
|---|---|
BestEffort | BestEffort QoS Pod |
NotBestEffort | 非 BestEffort QoS Pod |
Terminating | spec.activeDeadlineSeconds 有值 |
NotTerminating | spec.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> | 高 |
| ResourceQuota | kubectl create quota --hard=... | 中 |
| LimitRange | YAML 创建,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 等),考试中很方便