
K8s命名空间与资源配额实验完整详解这是K8s集群多租户管理和资源管控的核心实验也是生产环境中必须掌握的技能。当多个团队或项目共享同一个K8s集群时命名空间和资源配额是实现环境隔离和资源公平分配的基础。一、实验核心目标通过亲手操作彻底搞懂命名空间(Namespace)到底是什么它能隔离什么不能隔离什么为什么需要命名空间什么时候应该使用命名空间资源配额(ResourceQuota)的工作原理如何限制命名空间的资源使用requests和limits的本质区别这是K8s资源管理的核心如何验证资源配额是否生效以及常见的错误排查方法二、实验前置准备✅ 已经完成K8s集群搭建1个master2个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-systemK8s系统组件所在的命名空间如kube-apiserver、etcd、Calico等kube-public公共命名空间所有用户都可以读取通常用于存放集群公共信息kube-node-lease节点租约命名空间用于节点心跳检测# 2. 创建命名空间命令行方式kubectl create namespacetest# 简写kubectl create nstest# 3. 创建命名空间YAML方式推荐生产环境使用catnamespace-test.yamlEOF apiVersion: v1 kind: Namespace metadata: name: test labels: environment: test team: backend EOFkubectl apply-fnamespace-test.yaml# 4. 查看指定命名空间的详细信息kubectl describe nstest# 5. 删除命名空间⚠️ 非常危险会删除该命名空间下的所有资源kubectl delete nstest⚠️ 重要警告删除命名空间会级联删除该命名空间下的所有资源Pod、Service、Deployment、ConfigMap等而且无法恢复生产环境中删除命名空间一定要非常谨慎。4. 在指定命名空间中操作资源# 在test命名空间中创建Podkubectl apply-fpod-test.yaml-ntest# 查看test命名空间中的Podkubectl get pods-ntest# 查看所有命名空间中的Podkubectl get pods-A# 删除test命名空间中的Podkubectl delete pods pod-test-ntest实验2资源配额(ResourceQuota)配置1. 什么是资源配额大白话解释资源配额就是给每个楼层(命名空间)分配的资源上限。比如给3楼(开发环境)分配2个CPU和4GB内存给5楼(生产环境)分配8个CPU和16GB内存这样就不会出现开发环境占用太多资源导致生产环境无法运行的情况官方定义ResourceQuota是K8s提供的一种资源限制机制它可以限制某个命名空间中所有资源的总使用量。2. 编写资源配额YAML文件创建namespace-quota.yaml文件apiVersion:v1kind:ResourceQuotametadata:name:mem-cpu-quota# 资源配额的名字namespace:test# 这个配额应用到哪个命名空间spec:hard:# 硬限制绝对不能超过requests.cpu:2# 所有容器的CPU请求总和不能超过2核requests.memory:2Gi# 所有容器的内存请求总和不能超过2GBlimits.cpu:4# 所有容器的CPU上限总和不能超过4核limits.memory:4Gi# 所有容器的内存上限总和不能超过4GB3. 核心概念requests vs limits这是K8s资源管理中最容易混淆也是最重要的概念一定要搞懂概念含义作用类比requests容器申请的资源量1. 调度器根据requests来调度Pod2. 保证容器至少能获得这么多资源你订机票时选的座位保证你有位置坐limits容器最多能使用的资源量1. 限制容器的最大资源使用量2. 超过limits的CPU会被节流3. 超过limits的内存会被OOM杀死飞机的最大载客量绝对不能超过单位说明CPU单位是核也可以用毫核(m)表示。1000m 1核500m 0.5核内存单位是字节也可以用Ki、Mi、Gi表示。1Gi 1024Mi1Mi 1024Ki4. 应用资源配额kubectl apply-fnamespace-quota.yaml查看资源配额是否生效kubectl describequotamem-cpu-quota-ntest正常输出示例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. 验证不设置资源限制会怎样创建一个不设置资源限制的PodapiVersion:v1kind:Podmetadata:name:pod-no-resourcenamespace:testspec:containers:-name:tomcatimage:xianchao/tomcat-8.5-jre8:v1imagePullPolicy:IfNotPresentports:-containerPort:8080应用这个YAMLkubectl apply-fpod-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. 验证设置正确的资源限制创建一个设置了资源限制的PodapiVersion:v1kind:Podmetadata:name:pod-testnamespace:testlabels:app:tomcat-pod-testspec:containers:-name:tomcat-testports:-containerPort:8080image:xianchao/tomcat-8.5-jre8:v1imagePullPolicy:IfNotPresentresources:requests:memory:100Mi# 申请100MB内存cpu:500m# 申请0.5核CPUlimits:memory:2Gi# 最多使用2GB内存cpu:2# 最多使用2核CPU应用这个YAMLkubectl apply-fpod-test.yaml查看Pod状态kubectl get pods-ntest正常输出NAME READY STATUS RESTARTS AGE pod-test 1/1 Running 0 10s再次查看资源配额使用情况kubectl describequotamem-cpu-quota-ntest输出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-fpod-test.yaml你会看到报错Error from server (Forbidden): error when creating pod-test.yaml: pods pod-test is forbidden: exceeded quota: mem-cpu-quota, requested: limits.cpu2,limits.memory2Gi, used: limits.cpu2, limited: limits.cpu4报错原因虽然CPU limits的总配额是4核已经使用了2核还剩2核但是这个Pod的limits.cpu是2核加起来正好是4核为什么会报错呢⚠️ 重要知识点资源配额的检查是原子性的。也就是说K8s会先检查如果创建这个Pod总使用量会不会超过配额如果会就直接拒绝而不是先创建一部分。在这个例子中我们已经有一个Pod使用了2核CPU limits现在要创建第二个Pod也需要2核CPU limits。虽然224正好等于配额但是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:v1kind:ResourceQuotametadata:name:object-quotanamespace:testspec:hard:pods:10# 最多10个Podservices:5# 最多5个Serviceconfigmaps:10# 最多10个ConfigMapsecrets:10# 最多10个Secretpersistentvolumeclaims:4# 最多4个PVC4. 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 nstest--force--grace-period0六、实验总结通过这个实验你应该掌握了以下核心知识点命名空间是K8s的逻辑隔离机制用于将集群划分为多个虚拟集群资源配额用于限制命名空间的总资源使用量防止资源滥用requests是容器申请的资源用于调度limits是容器最多能使用的资源用于限制在设置了资源配额的命名空间中所有Pod都必须设置requests和limits命名空间只能隔离逻辑资源不能隔离物理资源命名空间和资源配额是K8s多租户管理的基础在生产环境中你应该为每个环境、每个团队创建独立的命名空间并设置合理的资源配额以确保集群的稳定运行和资源的公平分配。