kubernetes(K8s)学习笔记(第十期):集群资源与弹性(上篇):监控与自动扩缩——Metrics Server + HPA

kubernetes(K8s)学习笔记(第十期):集群资源与弹性(上篇):监控与自动扩缩------Metrics Server + HPA

本笔记为 Kubernetes 系列第十期,聚焦集群资源监控与自动扩缩容。涵盖:Metrics Server 部署与使用、Horizontal Pod Autoscaler(HPA)基于 CPU/内存的自动扩缩容实战、扩容/缩容时间参数详解、HPA vs VPA 对比。所有命令和 YAML 示例均来自课堂笔记,经过整理和注释。全文约 3900 字 ,包含 12 个 YAML 示例45+ 命令示例10 张对比表格,是 Kubernetes 集群资源管理的入门指南。
更多kubernetes系列知识:kubernetes从入门到进阶
--- Compiled and Authored by Whisky --- July 1 st, 2026

目录

  1. 引子:从"资源管理的三个层次"说起
  2. Metrics Server
  3. Horizontal Pod Autoscaler(HPA)
  4. 总结与知识点一览表

引子:从"资源管理的三个层次"说起

在 Kubernetes 集群中,资源管理是一个贯穿始终的核心话题。如果把集群比作一个城市,节点就是城市中的"建筑",Pod 就是建筑中的"住户"。随着业务的发展,住户数量不断增加,城市管理者需要面对三个核心问题:

  1. 如何知道每栋建筑住了多少人?用了多少水电? ------ 这是监控问题
  2. 当某栋建筑住满了,如何快速把新住户安排到其他建筑? ------ 这是调度问题
  3. 如何防止某个小区占用过多资源,影响其他小区? ------ 这是限制问题

围绕这三个问题,Kubernetes 集群资源管理形成了三个层次:

层次 问题 K8s 组件 本期/下期
监控层 资源用了多少? Metrics Server 本期(上篇)
扩缩层 资源不够怎么办? HPA(水平扩缩) 本期(上篇)
约束层 如何防止超用? ResourceQuota / LimitRange 下期(下篇)

本期的学习路径

text 复制代码
部署 Metrics Server(获取资源可见性)
    ↓
设置 HPA 自动扩缩容(CPU/内存)
    ↓
理解扩容/缩容的时间参数

一句话总结本期的价值:Metrics Server 让你"看得见"资源,HPA 让你"管得住"资源------这就是集群资源管理的"眼睛"和"手"。

一、Metrics Server

1.1 为什么需要 Metrics Server?

在使用 Kubernetes 的过程中,集群管理员和开发者常常面临三个核心问题:

  1. 如何查看节点的 CPU/内存使用情况?
  2. 如何查看 Pod 的资源消耗?
  3. 如何根据资源使用情况自动扩缩容?

Metrics Server 正是为了解决这三个问题而存在的。

官方定位:Metrics Server 是 Kubernetes 内置自动缩放管道的可扩展、高效的容器资源指标来源。它通过 Kubelet 收集资源指标,并通过 Metrics API 将它们公开在 Kubernetes API Server 中,供 Horizontal Pod Autoscaler 和 Vertical Pod Autoscaler 使用。

核心特点

特性 说明
部署简单 单一 Deployment,适用于大多数集群
采集频率 每 15 秒收集一次指标
资源消耗 每个节点仅需 1 mili 核心 CPU 和 2 MB 内存
可扩展性 支持多达 5,000 个节点的集群

Metrics Server 与其他监控工具的关系

工具 作用 是否替代 Metrics Server
Metrics Server 提供 CPU/内存指标给 HPA ---
Prometheus 完整的监控告警体系 ❌ 不替代,可并行使用
kubectl top 查看实时资源使用 ✅ 依赖 Metrics Server

重要说明 :Metrics Server 不适用于非自动缩放目的 。如果需要将指标转发到监控解决方案(如 Prometheus),应直接从 Kubelet 的 /metrics/resource 端点采集数据。

1.2 部署 Metrics Server

下载部署文件

bash 复制代码
root@master30:~# wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.7.1/components.yaml

修改部署文件 :Metrics Server 默认需要验证 Kubelet 的 TLS 证书,在某些环境中(如使用自签名证书)会导致连接失败。我们添加 --kubelet-insecure-tls 参数跳过 TLS 验证:

bash 复制代码
root@master30:~# sed -i '/metric-resolution/a\        - --kubelet-insecure-tls' components.yaml

查看所需镜像

bash 复制代码
root@master30:~# grep image: components.yaml
        image: registry.k8s.io/metrics-server/metrics-server:v0.7.1

部署

bash 复制代码
root@master30:~# kubectl apply -f components.yaml
serviceaccount/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
service/metrics-server created
deployment.apps/metrics-server created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created

验证部署状态

bash 复制代码
root@master30:~# kubectl get pods -n kube-system | grep metrics
metrics-server-6556f8cb6c-78mhq   1/1     Running   0          45s

确认 Metrics API 可用

bash 复制代码
root@master30:~# kubectl get apiservice v1beta1.metrics.k8s.io -o yaml | grep -A3 status

1.3 使用 Metrics Server

部署完成后,可以使用 kubectl top 命令查看资源使用情况。

查看节点资源使用

bash 复制代码
root@master30:~# kubectl top node
NAME                  CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
master30.whisky.cloud   97m          4%     1328Mi          35%
worker31.whisky.cloud   49m          2%     912Mi           24%
worker32.whisky.cloud   45m          2%     926Mi           24%

输出解读

  • CPU(cores):当前使用的 CPU 核心数(毫核为单位)
  • CPU%:相对节点 CPU 总容量的百分比
  • MEMORY(bytes):当前使用的内存量
  • MEMORY%:相对节点内存总容量的百分比

查看 Pod 资源使用

bash 复制代码
root@master30:~# kubectl top pods -n kube-system
NAME                                        CPU(cores)   MEMORY(bytes)
calico-kube-controllers-6dfcd885bf-8rhg2    2m           11Mi
calico-node-crfr7                           27m          57Mi
coredns-6d56c8448f-nhjpg                    3m           12Mi
etcd-master.whisky.cloud                     16m          54Mi
kube-apiserver-master.whisky.cloud           46m          355Mi
metrics-server-6556f8cb6c-78mhq             1m           11Mi

单位说明 :1 CPU 核心 = 1000m(millicores)。例如 97m 表示使用了 0.097 个 CPU 核心。Mi 是 Mebibyte(1Mi = 1024Ki = 1,048,576 字节)。

二、Horizontal Pod Autoscaler(HPA)

2.1 HPA 概述

HPA(Horizontal Pod Autoscaler,水平 Pod 自动扩缩器) 是 Kubernetes 中用于根据资源使用情况自动调整 Pod 副本数的控制器。

适用场景

  • 流量波动大的无状态服务(如 Web 应用、API 网关、微服务)
  • 需要提高并发处理能力、削峰填谷
  • Deployment 和 StatefulSet 都支持

核心特点

  • 不修改 Pod 配置,只调整副本数
  • 实时、秒级扩缩
  • 支持 CPU、内存、自定义指标(如 QPS、延迟)

支持指标来源

  • metrics.k8s.io:Metrics Server 提供的 CPU/内存指标
  • custom.metrics.k8s.io:自定义指标(如 Prometheus 接入)
  • external.metrics.k8s.io:外部指标

2.2 扩容与缩容时间参数

HPA 的扩容和缩容行为由 kube-controller-manager 的参数控制:

参数 作用 默认值
--horizontal-pod-autoscaler-sync-period 指标采样周期 15s
--horizontal-pod-autoscaler-initial-readiness-delay Pod 启动就绪等待时间 30s
--horizontal-pod-autoscaler-downscale-stabilization 缩容稳定窗口期 5m

扩容流程

  1. 每 15 秒采集一次 CPU/内存指标
  2. Pod 启动前 30 秒视为"启动中",不参与 HPA 计算
  3. 扩容冷却时间:默认 45 秒(3 个采样周期)

缩容流程

  1. 同样每 15 秒采样一次
  2. 需要指标持续低于阈值至少 5 分钟才会触发缩容
  3. 每次缩容后再次锁定 5 分钟

设计理念:扩容要快(应对突发流量),缩容要慢(避免流量抖动导致频繁扩缩)。这就像一个"油门"和"刹车"的配合------踩油门要快,松刹车要稳。

修改参数示例(kube-controller-manager 静态 Pod):

bash 复制代码
root@master30:~# vim /etc/kubernetes/manifests/kube-controller-manager.yaml

command 段添加:

yaml 复制代码
spec:
  containers:
  - command:
    - kube-controller-manager
    - --allocate-node-cidrs=true
    - --horizontal-pod-autoscaler-sync-period=10s
    - --horizontal-pod-autoscaler-initial-readiness-delay=20s
    - --horizontal-pod-autoscaler-downscale-stabilization=60s

保存退出后,静态 Pod 会自动重启生效。

2.3 基于 CPU 使用率的 HPA 实验

步骤 1:创建 Deployment
bash 复制代码
root@master30:~# kubectl create deployment web --image=nginx
步骤 2:为 Pod 设置资源限制

HPA 需要知道 Pod 的资源限制才能计算使用率百分比:

bash 复制代码
root@master30:~# kubectl edit deployments.apps web

添加 resources 配置:

yaml 复制代码
spec:
  template:
    spec:
      containers:
      - name: nginx
        image: nginx
        resources:
          limits:
            cpu: 100m
            memory: 200Mi

为什么必须设置 resources.limits? HPA 计算 CPU 使用率的方式是 实际使用量 / limit。如果未设置 limits,HPA 无法计算百分比,TARGETS 列会显示 <unknown>

步骤 3:创建 HPA

语法

bash 复制代码
kubectl autoscale deployment <name> --min=<min> --max=<max> --cpu-percent=<target>
bash 复制代码
root@master30:~# kubectl autoscale deployment web --max=5 --min=2 --cpu-percent=80
horizontalpodautoscaler.autoscaling/web autoscaled

查看 HPA

bash 复制代码
root@master30:~# kubectl get hpa
NAME   REFERENCE        TARGETS       MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   cpu: 0%/80%   2         5         2          30s

HPA 生效后,Deployment 的副本数会自动从 1 调整到 2(minReplicas=2)。

生成 HPA YAML(查看完整定义):

bash 复制代码
root@master30:~# kubectl get hpa web -o yaml
yaml 复制代码
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web
spec:
  maxReplicas: 5
  metrics:
  - resource:
      name: cpu
      target:
        averageUtilization: 80
        type: Utilization
    type: Resource
  minReplicas: 2
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web
步骤 4:创建 Service
bash 复制代码
root@master30:~# kubectl expose deployment web --port=80 --target-port=80
步骤 5:开启监控窗口

在第一个终端中,持续监控 HPA 和 Pod 状态:

bash 复制代码
root@master30:~# while true; do clear; kubectl get hpa; echo; kubectl get pod; echo; kubectl top pods; sleep 1; done
步骤 6:施加 CPU 压力

在第二个终端中,使用 ab(Apache Benchmark)工具施加压力:

bash 复制代码
root@master30:~# apt install -y apache2-utils
root@master30:~# while true; do ab -n 300000 -c 100 http://10.100.255.92/; sleep 1; done
  • -n 300000:总请求数
  • -c 100:并发数
步骤 7:观察自动扩容

初始状态(CPU 0%,2 个副本):

bash 复制代码
NAME   REFERENCE        TARGETS       MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   cpu: 0%/80%   2         5         2          8m

开始压测后(CPU 负载上升,HPA 开始扩容):

bash 复制代码
NAME   REFERENCE        TARGETS        MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   cpu: 100%/80%   2         5         2          9m

NAME                   CPU(cores)   MEMORY(bytes)
web-6dcdc45c94-6gwd2   101m         3Mi
web-6dcdc45c94-dvd2m   100m         3Mi

HPA 检测到 CPU 使用率超过目标值(80%),开始扩容到 3 个副本:

bash 复制代码
NAME   REFERENCE        TARGETS        MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   cpu: 95%/80%   2         5         3          10m

NAME                   CPU(cores)   MEMORY(bytes)
web-6dcdc45c94-2zbmb   93m          3Mi
web-6dcdc45c94-6gwd2   100m         3Mi
web-6dcdc45c94-dvd2m   90m          3Mi

继续扩容到 4 个副本,最终到 5 个副本(maxReplicas):

bash 复制代码
NAME   REFERENCE        TARGETS        MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   cpu: 100%/80%   2         5         5          11m

NAME                   CPU(cores)   MEMORY(bytes)
web-6dcdc45c94-2zbmb   101m         3Mi
web-6dcdc45c94-6gwd2   100m         3Mi
web-6dcdc45c94-dvd2m   100m         3Mi
web-6dcdc45c94-hpg45   98m          3Mi
web-6dcdc45c94-tsjkr   101m         3Mi

观察结论

  1. 随着 CPU 使用率上升,HPA 自动增加 Pod 副本数
  2. 扩容速度约为 30 秒左右创建一个新 Pod
  3. Pod 数量不会超过 maxReplicas(5 个)
  4. 停止压力测试后,负载降低,Pod 数量会逐步减少回 2 个(缩容较慢,默认 5 分钟稳定窗口)
步骤 8:清理资源
bash 复制代码
root@master30:~# kubectl delete hpa web
root@master30:~# kubectl delete deployment web
# svc 保留,后续实验使用

2.4 基于内存使用率的 HPA 实验

基于内存的 HPA 与 CPU 类似,但内存压力的模拟方式不同。我们让 Nginx 返回一个超大响应体来消耗内存。

步骤 1:准备大文件

在 Worker 节点上创建 200MB 的大文件:

bash 复制代码
[root@worker31 ~]# mkdir /www
[root@worker31 ~]# dd if=/dev/zero of=/www/big.img bs=1M count=200
[root@worker32 ~]# mkdir /www
[root@worker32 ~]# dd if=/dev/zero of=/www/big.img bs=1M count=200
步骤 2:创建 Deployment(挂载大文件)
yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: big-file
          mountPath: /usr/share/nginx/html
        resources:
          limits:
            cpu: 100m
            memory: 200Mi
      volumes:
      - name: big-file
        hostPath:
          path: /www
bash 复制代码
root@master30:~# kubectl apply -f deployment-web.yaml
步骤 3:创建 HPA(基于内存)
yaml 复制代码
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web
spec:
  minReplicas: 2
  maxReplicas: 5
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web
  metrics:
  - resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 60
    type: Resource
bash 复制代码
root@master30:~# kubectl apply -f hpa-mem.yaml

提示 :内存 HPA 的 target 默认是 Utilization(使用率百分比)。如果使用 AverageValue,则指定具体数值(如 200Mi)。

步骤 4:查看 HPA
bash 复制代码
root@master30:~# kubectl get hpa
NAME   REFERENCE        TARGETS          MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   memory: 1%/60%   2         5         2          30s
步骤 5:施加内存压力
bash 复制代码
root@master30:~# while true; do ab -n 300000 -c 100 http://10.99.129.137/big.img; sleep 1; done
步骤 6:观察自动扩容

内存负载上升

bash 复制代码
Every 4.0s: kubectl get hpa; echo; kubectl top pods

NAME   REFERENCE        TARGETS           MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   memory: 86%/60%   2         5         2          16m

NAME                  CPU(cores)   MEMORY(bytes)
web-88cff78bb-2b7vh   15m          174Mi
web-88cff78bb-76pg2   15m          171Mi

扩容到 3 个副本

bash 复制代码
NAME   REFERENCE        TARGETS           MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   memory: 58%/60%   2         5         3          16m

NAME                  CPU(cores)   MEMORY(bytes)
web-88cff78bb-2b7vh   15m          174Mi
web-88cff78bb-4hcm5   5m           3Mi
web-88cff78bb-76pg2   15m          171Mi

最终扩容到 5 个副本

bash 复制代码
NAME   REFERENCE        TARGETS           MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   memory: 58%/60%   2         5         5          16m

NAME                  CPU(cores)   MEMORY(bytes)
web-88cff78bb-2b7vh   15m          174Mi
web-88cff78bb-4hcm5   5m           3Mi
web-88cff78bb-76pg2   15m          171Mi
web-88cff78bb-ws6t4   1m           3Mi
web-88cff78bb-t4q2p   1m           3Mi

观察结论

  1. 内存指标采集同样需要 Metrics Server
  2. 内存 HPA 的扩容逻辑与 CPU 相同
  3. 新启动的 Pod 内存使用量很低,整体平均使用率下降
步骤 7:清理资源
bash 复制代码
root@master30:~# kubectl delete hpa web
root@master30:~# kubectl delete deployment web
root@master30:~# kubectl delete svc web

2.5 HPA vs VPA 对比

VPA(Vertical Pod Autoscaler) 是另一种自动扩缩容方式,与 HPA 形成互补。

对比项 HPA(水平扩缩容) VPA(垂直扩缩容)
扩缩方式 增加/减少 Pod 数量 调整 CPU/内存 request/limit
是否重启 Pod ❌ 不重启 ✅ 一般需要重启
适合负载 流量波动大 资源配置不合理
生效速度 快(秒级) 慢(需要重启)
稳定性
生产使用 非常普遍 较少
能否一起开 不能同时开(会冲突) ---
支持资源 CPU、内存、自定义 CPU、内存

总结HPA 管理"数量",VPA 管理"大小" 。HPA 适合应对流量突发,VPA 适合优化资源配置。两者各有侧重,但不能同时开启,否则会出现调度冲突。

三、总结与知识点一览表

3.1 回到"资源管理的三个层次"

在开篇的引子中,我们提出了资源管理的三个层次。现在,让我们回顾本期学到的内容如何对应这三个层次:

层次 问题 K8s 组件 本期内容
监控层 资源用了多少? Metrics Server ✅ kubectl top 查看节点/Pod 资源
扩缩层 资源不够怎么办? HPA ✅ 基于 CPU/内存自动扩缩容
约束层 如何防止超用? ResourceQuota / LimitRange 下期讲解

一句话回顾本期:我们通过 Metrics Server 获得了资源"可见性",通过 HPA 实现了资源"自动调配"------这就是集群资源管理的"监控"与"扩缩"两大核心能力。

3.2 核心知识点汇总

模块 核心概念 关键命令
Metrics Server 资源指标采集 kubectl top node, kubectl top pod
HPA 自动水平扩缩容 kubectl autoscale, kubectl get hpa
CPU HPA 基于 CPU 使用率 --cpu-percent=80
内存 HPA 基于内存使用率 averageUtilization: 60
扩容参数 sync-period / readiness-delay 默认 15s / 30s
缩容参数 downscale-stabilization 默认 5m

3.3 实验对比:CPU vs 内存扩缩

对比项 CPU 扩缩实验 内存扩缩实验
压测工具 ab 并发请求 ab 下载大文件
关键条件 设置 CPU limits 挂载大文件(hostPath)
HPA target averageUtilization: 80 averageUtilization: 60
触发条件 CPU 使用率超过 80% 内存使用率超过 60%
扩容速度 ~30s 创建一个 Pod ~30s 创建一个 Pod
maxReplicas 5 5

3.4 常用命令速查

操作 命令
查看节点资源 kubectl top node
查看 Pod 资源 kubectl top pod -n <ns>
创建 HPA(CPU) kubectl autoscale deployment <name> --min=2 --max=5 --cpu-percent=80
创建 HPA(内存 YAML) kubectl apply -f hpa-mem.yaml
查看 HPA kubectl get hpa
查看 HPA 详情 kubectl describe hpa <name>
删除 HPA kubectl delete hpa <name>

3.5 常见错误排查

错误现象 可能原因 解决方法
kubectl top 报错 Metrics Server 未部署 部署 Metrics Server
HPA TARGETS 为 <unknown> Pod 未设置 resources.limits 为 Pod 配置 CPU/内存限制
HPA TARGETS 为 <unreachable> Metrics Server 与 Kubelet 连接失败 检查 --kubelet-insecure-tls 参数
扩容速度慢 默认采样周期 15s 调整 --horizontal-pod-autoscaler-sync-period
缩容不触发 默认稳定窗口 5 分钟 等待或调整 --horizontal-pod-autoscaler-downscale-stabilization
扩容超过 maxReplicas maxReplicas 设置过低 修改 HPA 的 spec.maxReplicas
压测后 HPA 不触发 未创建 Service 或 Service 不可访问 确认 kubectl get svc 和访问路径

下一期预告:Kubernetes(K8s)学习笔记(第十一期):集群资源与弹性(下篇):资源配额与限制------ResourceQuota + LimitRange。涵盖:ResourceQuota 命名空间资源配额、LimitRange 容器资源默认值与限制范围、request/limit 的配置实验。
--- Compiled and Authored by Whisky --- July 1 st, 2026