在 Kubernetes 的世界里,集群资源永远是稀缺的。CPU、内存、存储,都是有限的算力,而集群上运行着成百上千个 Pod。如果没有一套清晰的资源管理机制,某个失控的应用可能瞬间吃掉整台节点的内存,把其他无辜的服务一起拖垮。今天这一篇,我们就来彻底搞懂 K8s 资源管理的三大核心:Request(资源请求)、Limit(资源上限),以及基于这两者之上的 HPA(Horizontal Pod Autoscaler,水平 Pod 自动伸缩)。

核心概念:Request 与 Limit 的区别
在深入之前,必须先把两个容易混淆的概念掰开揉碎。它们是资源管理的基石,理解偏差会直接导致生产事故。
Request:调度与预留的依据
Request 表示容器「期望获得」的资源量,也就是容器被调度时,K8s 调度器用来判断「这个 Pod 应该落在哪台节点上」的关键依据。调度器会把 Pod 中所有容器的 Request 加起来,寻找一台剩余可用资源足以容纳它的节点。如果一个 Pod 的 Request 总量超过了集群里任何一台节点的可用资源,这个 Pod 就会一直处于 Pending 状态,无法被调度。
需要特别注意的是:Request 并不是一个硬性的「配额锁」,而是一个「预留承诺」。K8s 保证容器至少能拿到 Request 声明的资源,但并不阻止它在节点空闲时使用更多。
Limit:容器资源的天花板
Limit 则是容器资源使用的「硬上限」。对于 CPU,当容器尝试使用超过 Limit 的 CPU 时,K8s 会通过 Cgroup 机制对 CPU 进行限流(throttle),容器不会被杀死,只是被压住速度。而对于内存则完全不同:一旦容器内存使用超过 Limit,K8s 会直接判定为 OOMKilled,杀掉容器并触发重启。
这也就是为什么内存的 Request 和 Limit 通常建议设置为相等——因为内存不像 CPU 那样可以「平滑限流」,超了就死,与其留一个危险区间,不如干脆锁死。
资源单位与 QoS 等级
CPU 的单位是「核」,可以写小数,例如 0.5 等价于 500m(m 代表毫核,1000m = 1 核)。内存的单位是字节,常用 Mi(兆)和 Gi(吉)。K8s 会根据 Request 与 Limit 的设置情况,自动把 Pod 划分到三种 QoS(服务质量)等级之一:Guaranteed、Burstable、BestEffort。当节点资源紧张时,驱逐(Evict)的优先级顺序就是 BestEffort > Burstable > Guaranteed,即「越守规矩越安全」。
下面是一个标准的资源配置示例:
apiVersion: v1
kind: Pod
metadata:
name: demo-app
spec:
containers:
- name: app
image: nginx:1.24
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
实战步骤:从资源配置到 HPA 伸缩
掌握了概念,接下来动手。我们会分三步走:先为 Deployment 配置合理的资源,再部署 Metrics Server(HPA 的数据来源),最后创建 HPA 并压测验证。
第一步:给工作负载声明资源
先把业务封装成一个 Deployment,并显式声明 resources 字段。这一步看似简单,却是整个资源管理体系的地基:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 2
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web
image: nginx:1.24
ports:
- containerPort: 80
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "200m"
memory: "256Mi"
用下面的命令把配置应用到集群,并查看 Pod 是否正常调度:
kubectl apply -f web-app.yaml
kubectl get pods -l app=web-app -o wide
kubectl describe pod -l app=web-app | grep -A6 Requests
第二步:部署 Metrics Server 提供指标
HPA 需要从 Metrics API 读取 Pod 的实时 CPU 和内存使用率。默认集群往往没有安装 Metrics Server,需要先部署。以官方仓库为例:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
kubectl get deployment metrics-server -n kube-system
部署完成后,稍等片刻,验证指标是否已经采集上来:
kubectl top nodes
kubectl top pods -l app=web-app
如果 kubectl top 能正常输出数字,说明 Metrics Server 工作正常,可以进入下一步了。
第三步:创建 HPA 并验证伸缩
HPA 的核心参数是目标使用率:当 Pod 的平均 CPU 使用率超过设定阈值(如 50%)时,HPA 会扩充副本;低于阈值则缩容。下面创建一个 HPA,让副本数在 2 到 10 之间弹性浮动:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
应用之后,查看 HPA 状态:
kubectl apply -f web-app-hpa.yaml
kubectl get hpa web-app-hpa
要验证它真的会伸缩,可以临时用压测工具给服务加压。这里用一个简单的循环请求制造 CPU 负载:
while true; do curl -s http://<service-ip>/ > /dev/null; done
几分钟后再次查看 HPA 状态,你会看到 TARGETS 列的使用率上升,REPLICAS 逐步增加;停止压测后,副本又会慢慢降回最小值。
常见问题与避坑指南
在实际运维中,资源管理和 HPA 的坑大多藏在细节里。下面几个是最高频的。
问题一:为什么设置了 HPA 却不生效? 绝大多数情况是 Metrics Server 没装好,或 kubectl top 读不到数据。HPA 完全依赖指标来源,没有指标就没有伸缩。先用 kubectl get apiservices | grep metrics 确认 metrics API 是否可用。
问题二:CPU 都打满了,Pod 还是不扩容? 检查 Deployment 是否声明了 resources.requests。HPA 计算的是「实际用量 / Request」的百分比,没有 Request 的容器无法计算使用率,HPA 会一直显示 <unknown>。
问题三:内存能不能用 HPA 伸缩? 可以,但内存型伸缩要谨慎。CPU 负载是「弹性」的,短时尖峰可以通过扩容缓解;而内存一旦吃满往往是泄漏或固定占用,扩容不一定能解决问题,反而容易引发频繁抖动。
问题四:Request 设太小会怎样? Request 是调度依据,设得太小会导致节点超卖严重,多个 Pod 挤在一台节点上,资源竞争时互相拖慢,QoS 也会降级为 Burstable,节点压力大时容易被优先驱逐。
总结
资源管理是 Kubernetes 运维的「分水岭」:不懂它之前,集群是一个随时可能崩溃的黑盒;掌握了 Request、Limit 和 HPA 之后,你就拥有了对资源分配、调度、伸缩的完整掌控力。记住三条核心原则:Request 决定 Pod 落在哪里,Limit 决定容器能用到多少,HPA 决定副本该有几个。给所有生产工作负载显式声明资源,是每一个严肃运维团队的基本功。
下期预告:第 10 天我们将进入 K8s 最复杂的部分之一——网络模型,深入 CNI、Calico 与 NetworkPolicy,搞懂 Pod 之间的流量是如何流转、又如何被安全隔离的。敬请期待。


















暂无评论内容