K8s命名空间与资源配额实验完整详解
K8s命名空间与资源配额实验完整详解
这是K8s集群多租户管理和资源管控的核心实验,也是生产环境中必须掌握的技能。当多个团队或项目共享同一个K8s集群时,命名空间和资源配额是实现环境隔离和资源公平分配的基础。
一、实验核心目标
通过亲手操作,彻底搞懂:
- 命名空间(Namespace) 到底是什么,它能隔离什么,不能隔离什么
- 为什么需要命名空间,什么时候应该使用命名空间
- 资源配额(ResourceQuota) 的工作原理,如何限制命名空间的资源使用
requests和limits的本质区别,这是K8s资源管理的核心- 如何验证资源配额是否生效,以及常见的错误排查方法
二、实验前置准备
✅ 已经完成K8s集群搭建(1个master+2个worker节点)
✅ 所有节点状态为Ready
✅ Calico网络插件正常运行
✅ 已经导入xianchao/tomcat-8.5-jre8:v1镜像到所有worker节点
三、实验分步详解
实验1:命名空间的基本操作
1. 什么是命名空间?
大白话解释:
把K8s集群想象成一个大型办公楼,命名空间就是楼里的不同楼层。
- 每个楼层(命名空间)都有自己的办公室(Pod)、会议室(Service)、储物间(ConfigMap)
- 不同楼层的房间号可以重复(比如3楼301和5楼301是不同的房间)
- 不同楼层之间默认是隔离的,不能直接互相访问
- 但是整栋楼的电梯(节点)、水电(持久卷)是公共资源,所有楼层共享
官方定义:
命名空间是K8s提供的一种集群级别的资源隔离机制,它将一个物理集群划分为多个逻辑上的虚拟集群。每个虚拟集群都有自己的资源范围和访问控制。
2. 什么时候需要使用命名空间?
✅ 需要隔离不同环境:开发环境(dev)、测试环境(test)、生产环境(prod)
✅ 需要隔离不同团队/项目:前端团队、后端团队、大数据团队
✅ 需要隔离不同客户:SaaS平台中不同的租户
❌ 集群规模很小:只有几个用户和几十个Pod,不需要使用命名空间
3. 命名空间的基本操作
# 1. 查看所有命名空间
kubectl get namespaces
# 简写
kubectl get ns
默认命名空间说明:
default:默认命名空间,没有指定命名空间的资源都会创建在这里kube-system:K8s系统组件所在的命名空间(如kube-apiserver、etcd、Calico等)kube-public:公共命名空间,所有用户都可以读取,通常用于存放集群公共信息kube-node-lease:节点租约命名空间,用于节点心跳检测
# 2. 创建命名空间(命令行方式)
kubectl create namespace test
# 简写
kubectl create ns test
# 3. 创建命名空间(YAML方式,推荐生产环境使用)
cat > namespace-test.yaml << EOF
apiVersion: v1
kind: Namespace
metadata:
name: test
labels:
environment: test
team: backend
EOF
kubectl apply -f namespace-test.yaml
# 4. 查看指定命名空间的详细信息
kubectl describe ns test
# 5. 删除命名空间(⚠️ 非常危险!会删除该命名空间下的所有资源)
kubectl delete ns test
⚠️ 重要警告:
删除命名空间会级联删除该命名空间下的所有资源(Pod、Service、Deployment、ConfigMap等),而且无法恢复!生产环境中删除命名空间一定要非常谨慎。
4. 在指定命名空间中操作资源
# 在test命名空间中创建Pod
kubectl apply -f pod-test.yaml -n test
# 查看test命名空间中的Pod
kubectl get pods -n test
# 查看所有命名空间中的Pod
kubectl get pods -A
# 删除test命名空间中的Pod
kubectl delete pods pod-test -n test
实验2:资源配额(ResourceQuota)配置
1. 什么是资源配额?
大白话解释:
资源配额就是给每个楼层(命名空间)分配的资源上限。
- 比如给3楼(开发环境)分配2个CPU和4GB内存
- 给5楼(生产环境)分配8个CPU和16GB内存
- 这样就不会出现开发环境占用太多资源,导致生产环境无法运行的情况
官方定义:
ResourceQuota是K8s提供的一种资源限制机制,它可以限制某个命名空间中所有资源的总使用量。
2. 编写资源配额YAML文件
创建namespace-quota.yaml文件:
apiVersion: v1
kind: ResourceQuota
metadata:
name: mem-cpu-quota # 资源配额的名字
namespace: test # 这个配额应用到哪个命名空间
spec:
hard: # 硬限制,绝对不能超过
requests.cpu: "2" # 所有容器的CPU请求总和不能超过2核
requests.memory: 2Gi # 所有容器的内存请求总和不能超过2GB
limits.cpu: "4" # 所有容器的CPU上限总和不能超过4核
limits.memory: 4Gi # 所有容器的内存上限总和不能超过4GB
3. 核心概念:requests vs limits
这是K8s资源管理中最容易混淆也是最重要的概念,一定要搞懂!
| 概念 | 含义 | 作用 | 类比 |
|---|---|---|---|
| requests | 容器申请的资源量 | 1. 调度器根据requests来调度Pod 2. 保证容器至少能获得这么多资源 | 你订机票时选的座位,保证你有位置坐 |
| limits | 容器最多能使用的资源量 | 1. 限制容器的最大资源使用量 2. 超过limits的CPU会被节流 3. 超过limits的内存会被OOM杀死 | 飞机的最大载客量,绝对不能超过 |
单位说明:
- CPU:单位是核,也可以用毫核(m)表示。
1000m = 1核,500m = 0.5核 - 内存:单位是字节,也可以用Ki、Mi、Gi表示。
1Gi = 1024Mi,1Mi = 1024Ki
4. 应用资源配额
kubectl apply -f namespace-quota.yaml
查看资源配额是否生效:
kubectl describe quota mem-cpu-quota -n test
正常输出示例:
Name: mem-cpu-quota
Namespace: test
Resource Used Hard
-------- ---- ----
limits.cpu 0 4
limits.memory 0 4Gi
requests.cpu 0 2
requests.memory 0 2Gi
可以看到,目前test命名空间的资源使用量都是0,还没有任何资源被使用。
实验3:验证资源配额
1. 资源配额的限制规则
当你在一个设置了资源配额的命名空间中创建Pod时,必须满足以下条件:
- Pod中的每个容器都必须同时设置requests和limits
- 所有容器的requests总和不能超过命名空间的requests配额
- 所有容器的limits总和不能超过命名空间的limits配额
如果不满足这些条件,Pod创建会失败!
2. 验证:不设置资源限制会怎样?
创建一个不设置资源限制的Pod:
apiVersion: v1
kind: Pod
metadata:
name: pod-no-resource
namespace: test
spec:
containers:
- name: tomcat
image: xianchao/tomcat-8.5-jre8:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
应用这个YAML:
kubectl apply -f pod-no-resource.yaml
你会看到报错:
Error from server (Forbidden): error when creating "pod-no-resource.yaml": pods "pod-no-resource" is forbidden: failed quota: mem-cpu-quota: must specify limits.cpu,limits.memory,requests.cpu,requests.memory
报错原因:
因为test命名空间设置了资源配额,所以所有Pod都必须设置requests和limits,否则会被拒绝创建。
3. 验证:设置正确的资源限制
创建一个设置了资源限制的Pod:
apiVersion: v1
kind: Pod
metadata:
name: pod-test
namespace: test
labels:
app: tomcat-pod-test
spec:
containers:
- name: tomcat-test
ports:
- containerPort: 8080
image: xianchao/tomcat-8.5-jre8:v1
imagePullPolicy: IfNotPresent
resources:
requests:
memory: "100Mi" # 申请100MB内存
cpu: "500m" # 申请0.5核CPU
limits:
memory: "2Gi" # 最多使用2GB内存
cpu: "2" # 最多使用2核CPU
应用这个YAML:
kubectl apply -f pod-test.yaml
查看Pod状态:
kubectl get pods -n test
正常输出:
NAME READY STATUS RESTARTS AGE
pod-test 1/1 Running 0 10s
再次查看资源配额使用情况:
kubectl describe quota mem-cpu-quota -n test
输出:
Name: mem-cpu-quota
Namespace: test
Resource Used Hard
-------- ---- ----
limits.cpu 2 4
limits.memory 2Gi 4Gi
requests.cpu 500m 2
requests.memory 100Mi 2Gi
可以看到,资源配额的使用量已经更新了,现在已经使用了500m CPU和100Mi内存的requests,以及2核CPU和2Gi内存的limits。
4. 验证:超过资源配额会怎样?
现在我们再创建一个同样的Pod,看看会发生什么:
kubectl apply -f pod-test.yaml
你会看到报错:
Error from server (Forbidden): error when creating "pod-test.yaml": pods "pod-test" is forbidden: exceeded quota: mem-cpu-quota, requested: limits.cpu=2,limits.memory=2Gi, used: limits.cpu=2, limited: limits.cpu=4
报错原因:
虽然CPU limits的总配额是4核,已经使用了2核,还剩2核,但是这个Pod的limits.cpu是2核,加起来正好是4核,为什么会报错呢?
⚠️ 重要知识点:
资源配额的检查是原子性的。也就是说,K8s会先检查如果创建这个Pod,总使用量会不会超过配额,如果会,就直接拒绝,而不是先创建一部分。
在这个例子中,我们已经有一个Pod使用了2核CPU limits,现在要创建第二个Pod,也需要2核CPU limits。虽然2+2=4正好等于配额,但是K8s会认为如果创建这个Pod,总使用量就会达到4核,已经没有剩余资源了,所以会拒绝创建。
四、实验核心原理深度解析
1. 命名空间的隔离性
命名空间能隔离的资源:
- 工作负载:Pod、Deployment、StatefulSet、DaemonSet等
- 服务发现:Service、Endpoint
- 配置:ConfigMap、Secret
- 存储:PersistentVolumeClaim
- 访问控制:Role、RoleBinding
命名空间不能隔离的资源:
- 节点(Node)
- 持久卷(PersistentVolume)
- 命名空间(Namespace)本身
- 集群级别的访问控制:ClusterRole、ClusterRoleBinding
- 存储类(StorageClass)
重要结论:
命名空间是逻辑隔离,不是物理隔离。不同命名空间的Pod仍然运行在同一个节点上,共享节点的CPU、内存和网络资源。
2. 资源配额的工作原理
资源配额是由kube-apiserver强制执行的。当你创建或更新资源时,kube-apiserver会先检查这个操作是否会导致命名空间的资源使用量超过配额,如果会,就直接拒绝这个请求。
资源配额的检查时机:
- 创建资源时
- 更新资源时
- 删除资源时(更新已使用量)
3. 资源配额的其他类型
除了CPU和内存,资源配额还可以限制其他类型的资源:
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-quota
namespace: test
spec:
hard:
pods: "10" # 最多10个Pod
services: "5" # 最多5个Service
configmaps: "10" # 最多10个ConfigMap
secrets: "10" # 最多10个Secret
persistentvolumeclaims: "4" # 最多4个PVC
4. ResourceQuota vs LimitRange
很多初学者会混淆这两个概念,它们的区别是:
| 概念 | 作用范围 | 作用 |
|---|---|---|
| ResourceQuota | 命名空间级别 | 限制命名空间中所有资源的总使用量 |
| LimitRange | 命名空间级别 | 限制命名空间中单个Pod或容器的默认资源和最大/最小资源 |
LimitRange的典型应用:
- 给没有设置资源的Pod设置默认的requests和limits
- 限制单个Pod或容器的最大资源使用量
- 限制单个Pod或容器的最小资源使用量
五、实验常见问题及解决方法
问题1:创建Pod时提示"must specify limits.cpu,limits.memory,requests.cpu,requests.memory"
原因:命名空间设置了资源配额,但是Pod没有设置requests和limits。
解决方法:在Pod的YAML文件中添加resources字段,设置requests和limits。
问题2:创建Pod时提示"exceeded quota"
原因:创建这个Pod会导致命名空间的资源使用量超过配额。
解决方法:
- 减少Pod的资源请求
- 删除一些不需要的Pod,释放资源
- 增加命名空间的资源配额
问题3:删除命名空间时一直处于Terminating状态
原因:命名空间下还有一些资源没有被完全删除,或者有finalizer没有被处理。
解决方法:
# 强制删除命名空间(⚠️ 非常危险!)
kubectl delete ns test --force --grace-period=0
六、实验总结
通过这个实验,你应该掌握了以下核心知识点:
- 命名空间是K8s的逻辑隔离机制,用于将集群划分为多个虚拟集群
- 资源配额用于限制命名空间的总资源使用量,防止资源滥用
- requests是容器申请的资源,用于调度;limits是容器最多能使用的资源,用于限制
- 在设置了资源配额的命名空间中,所有Pod都必须设置requests和limits
- 命名空间只能隔离逻辑资源,不能隔离物理资源
命名空间和资源配额是K8s多租户管理的基础,在生产环境中,你应该为每个环境、每个团队创建独立的命名空间,并设置合理的资源配额,以确保集群的稳定运行和资源的公平分配。
更多推荐


所有评论(0)