pod Scheduler调度

Metric Server

学习参考:Metric Server

Metrics-Server 概述

我们在使用 Kubernetes 中过程中面临的问题:

  • 如何监控 node 计算资源使用情况?

  • 如何监控 pod 计算资源使用情况?

  • 如何根据 pod 计算资源使用情况,自动扩展?

我们可以使用 Metrics-Server监控:

  1. node 和 pod 计算资源使用情况。
  2. Metrics Server 是 Kubernetes 内置自动缩放管道的可扩展、高效的容器资源指标来源。
  3. Metrics Server 通过 Kubelet 收集资源指标,并通过 Metrics API 将它们公开在 Kubernetes apiserver 中,供 Horizontal Pod Autoscaler 和 Vertical Pod Autoscaler 使用。
  4. Metrics API 还可以通过 kubectl top 访问,从而更轻松地调试自动缩放管道。

Metrics Server 不适用于非自动缩放目的。 请勿将其用于将指标转发到监控解决方案,或作为监控解决方案指标的来源。 在这种情况下,请直接从 Kubelet /metrics/resource 端点收集指标。

指标服务器提供:

  • 适用于大多数集群的单一部署(请参阅要求)。
  • 快速自动缩放,每 15 秒收集一次指标。
  • 资源效率,集群中每个节点使用 1 mili 核心 CPU 和 2 MB 内存。
  • 可扩展支持多达 5,000 个节点集群。

Metrics-Server 部署

项目地址 kubernetes-sigs/metrics-server

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

# 修改 Metrics-Server,不校验tls
[root@master30 ~]# sed -i '/metric-resolution/a\        - --kubelet-insecure-tls' components.yaml

# 下载镜像
[root@master30 ~]# grep image: components.yaml
        image: registry.k8s.io/metrics-server/metrics-server:v0.7.1

# 部署 Metrics-Server
[root@master30 ~]# kubectl apply -f components.yaml
bash 复制代码
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 复制代码
# 查看 Metrics-Server 状态
[root@master30 ~]# kubectl get pods -n kube-system |grep metrics
metrics-server-6556f8cb6c-78mhq             1/1     Running   0          45s

Metrics-Server 使用

查看node状态

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

查看 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           
calico-node-sbmjt                           22m          57Mi           
calico-node-z9dvd                           24m          56Mi           
coredns-6d56c8448f-nhjpg                    3m           12Mi           
coredns-6d56c8448f-w2f48                    2m           10Mi           
etcd-master.laoma.cloud                      16m          54Mi           
kube-apiserver-master.laoma.cloud            46m          355Mi           
kube-controller-manager-master.laoma.cloud   11m          50Mi           
kube-proxy-hx566                            1m           18Mi           
kube-proxy-t2r4x                            1m           18Mi           
kube-proxy-x6k8h                            1m           18Mi           
kube-scheduler-master.laoma.cloud            4m           22Mi           
metrics-server-6556f8cb6c-78mhq             1m           11Mi    

单位:1cpu=1000m

扩容和减容控制

扩容和缩容时间参数

1. 指标采样周期
  • --horizontal-pod-autoscaler-sync-period duration
  • 默认:15s,HPA 每 15 秒拉取一次 metrics-server 指标。
2. 启动就绪窗口期
  • --horizontal-pod-autoscaler-initial-readiness-delay duration
  • 默认:30s,Pod 刚启动前 30 秒,视为 "启动中",不参与 HPA 计算
3. 缩容稳定窗口期
  • --horizontal-pod-autoscaler-downscale-stabilization duration
  • 默认:5m0s(5 分钟),缩容冷却时间。

持续高负载 → 扩容

  1. 15s 采集一次 CPU/内存指标
  2. Pod 刚启动前 30 秒,视为 "启动中",不参与 HPA 计算。
  3. 一次扩容动作完成后,再次等待 45s 冷却 才能下一次扩容

👉 结论:K8s 1.30 扩容最小间隔 = 45s

持续低负载 → 缩容

  1. 同样 15s 采样
  2. 指标长期低于阈值
  3. 需要满足 300s(5分钟)稳定低位 才会触发缩容
  4. 每次缩容后,再次锁定 5 分钟

设置扩容和减容时间参数

扩容和减容pod数量由kube-controller-manager管理,如需调快/调慢,直接修改 controller-manager 启动参数即可。

扩容和缩容pod是有冷却时间的,目的是防止流量抖动、瞬间峰值导致频繁炸裂扩容。

为了演示扩容和缩容效果,这里设置扩容冷却时间为30s(10+20),缩容冷却时间为60秒。

bash 复制代码
[root@master30 ~]# vim /etc/kubernetes/manifests/kube-controller-manager.yaml 
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 会自动重启生效

Horizontal Pod Autoscaler

学习参考:hpa

HPA 作用

控制器将从一系列API(metrics.k8s.iocustom.metrics.k8s.ioexternal.metrics.k8s.io)中获取度量值。 metrics.k8s.io API 通常由Metrics Server提供。根据 HPA 中定义的指标动态实现控制器中pod伸缩,支持replication controller、deployment和replicaset。

适用场景

  • 流量波动大的无状态服务(nginx、api、网关、微服务)
  • 需要提高并发削峰填谷
  • Deployment/StatefulSet 都支持

核心特点

  • 不修改 Pod 配置,只改副本数
  • 实时、秒级扩缩
  • 最常用、最稳定

支持指标

  • CPU 使用率
  • 内存使用率
  • 自定义指标(Prometheus 对接)
  • QPS、延迟等

基于 CPU 使用率伸缩

准备资源
bash 复制代码
[root@master30 ~]# kubectl create deployment web --image=docker.io/library/nginx
创建 hpa
bash 复制代码
Usage:  kubectl autoscale (-f FILENAME | TYPE NAME | TYPE/NAME) [--min=MINPODS]--max=MAXPODS [--cpu-percent=CPU] [options]

[root@master30 ~]# kubectl autoscale deployment web --max=5 --min=2 --cpu-percent=80
[root@master30 ~]# kubectl get hpa web -o yaml |tee hpa-cpu.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
bash 复制代码
[root@master30 ~]# kubectl get hpa
NAME   REFERENCE        TARGETS              MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   cpu: <unknown>/80%   2         5         2          2m28s
# CPU目标为unknown

# 稍等片刻,创建一个新的pod
[root@master30 ~]# kubectl get pod
NAME                  READY   STATUS    RESTARTS   AGE
web-96d5df5c8-4ztct   1/1     Running   0          30s
web-96d5df5c8-fq5kd   1/1     Running   0          41s

要想看到 HPA 的 TARGETS 值必须满足2个条件:

  1. 安装 metric server。
  2. 为 pod 设定资源限制。
bash 复制代码
[root@master30 ~]# kubectl edit deployments.apps web
# 修改spec.template.spec.containers.[N].resources属性,添加limit属性,如下:
        resources:
          limits: 
            cpu: 100m
            memory: 200Mi

# 再次查看hpa
[root@master30 ~]# kubectl get hpa
NAME   REFERENCE        TARGETS       MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   cpu: 0%/80%   2         5         2          5m3s

[root@master30 ~]# kubectl expose deployment web --port=80 --target-port=80
[root@master30 ~]# kubectl get svc
NAME   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
web    ClusterIP   10.100.255.92   <none>        80/TCP    2m4s
压力测试
bash 复制代码
# 打开一个监控窗口
[root@master30 ~]# watch 'kubectl get hpa;echo;kubectl top pods'

# 上 CPU 压力
[root@master30 ~]# apt install -y apache2-utils
[root@master30 ~]# while true ;do ab -n 300000 -c 100 http://10.99.129.137/;sleep 1;done
#  -n 300000,总请求数
#  -c 100,每次并发数

CPU负载 cpu: 98%

bash 复制代码
Every 2.0s: kubectl get hpa;echo;kubectl top pods                     master30.laoma.cloud: Sun Apr 19 09:57:22 2026

NAME   REFERENCE        TARGETS        MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   cpu: 98%/80%   2         5         2          8m32s

NAME                   CPU(cores)   MEMORY(bytes)
web-6dcdc45c94-277r9   99m          3Mi
web-6dcdc45c94-8xdn8   97m          3Mi

超过目标值后,HPA 新建了一个pod

复制代码
Every 2.0s: kubectl get hpa;echo;kubectl top pods                     master30.laoma.cloud: Sun Apr 19 09:58:04 2026

NAME   REFERENCE        TARGETS        MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   cpu: 95%/80%   2         5         3          9m14s

NAME                   CPU(cores)   MEMORY(bytes)
web-6dcdc45c94-277r9   99m          3Mi
web-6dcdc45c94-8xdn8   95m          3Mi
web-6dcdc45c94-t4q2p   100m         3Mi

HPA又新建了一个pod

bash 复制代码
Every 2.0s: kubectl get hpa;echo;kubectl top pods                     master30.laoma.cloud: Sun Apr 19 09:58:59 2026

NAME   REFERENCE        TARGETS        MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   cpu: 45%/80%   2         5         5          11m

NAME                   CPU(cores)   MEMORY(bytes)
web-6dcdc45c94-277r9   55m          3Mi
web-6dcdc45c94-2zj8s   100m         3Mi
web-6dcdc45c94-8xdn8   98m          3Mi
web-6dcdc45c94-sxvbb   100m         3Mi

HPA又新建了一个pod

bash 复制代码
Every 2.0s: kubectl get hpa;echo;kubectl top pods                     master30.laoma.cloud: Sun Apr 19 09:59:59 2026

NAME   REFERENCE        TARGETS        MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   cpu: 45%/80%   2         5         5          11m

NAME                   CPU(cores)   MEMORY(bytes)
web-6dcdc45c94-277r9   55m          3Mi
web-6dcdc45c94-2zj8s   100m         3Mi
web-6dcdc45c94-8xdn8   98m          3Mi
web-6dcdc45c94-sxvbb   100m         3Mi
web-6dcdc45c94-t4q2p   100m         3Mi

观察过程:

  1. 随着pod CPU使用率上升,自动扩展pod数量。

  2. 即使pod CPU使用率超过阈值,但pod数量不会超过5。

  3. 压力测试完成后,pod数量逐渐减少为2。

清理资源
bash 复制代码
# 删除 hpa
[root@master30 ~]# kubectl delete hpa web 

# 删除 deployment
[root@master30 ~]# kubectl delete deployment web

# 保留 svc,后续使用

基于 Mem 使用率伸缩

我们仍然以nginx应用实践。想要Nginx 内存涨,要访问会占用内存的页面 。最简单方法:让 Nginx 返回一个超大响应体

准备资源
bash 复制代码
# worker节点创建big.img
[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

[root@master30 ~]# vim deployment-web.yaml
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
创建 hpa
bash 复制代码
[root@master30 ~]# vim hpa-mem.yaml
yaml 复制代码
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web
spec:
  maxReplicas: 5
  metrics:
  - resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 60
    type: Resource
  minReplicas: 2
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web
bash 复制代码
[root@master30 ~]# kubectl apply -f hpa-mem.yaml
[root@master30 ~]# kubectl get hpa
NAME   REFERENCE        TARGETS                 MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   memory: <unknown>/60%   2         5         1          13m

# 目标值为空

# 稍等片刻,创建一个新的pod
[root@master30 ~]# kubectl get pods
NAME                   READY   STATUS    RESTARTS   AGE
web-6dcdc45c94-2zj8s   1/1     Running   0          13m
web-6dcdc45c94-w62pr   1/1     Running   0          13s

# 稍等一会,再次查看
[root@master30 ~]# kubectl get hpa
NAME   REFERENCE        TARGETS          MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   memory: 1%/60%   2         5         2          53s
压力测试
bash 复制代码
# 打开一个监控窗口
[root@master30 ~]# watch -n 4 'kubectl get hpa;echo;kubectl top pods'

# 上 MEM 压力
[root@master30 ~]# while true ;do ab -n 300000 -c 100 http://10.99.129.137/big.img;sleep 1;done

负载上来了

bash 复制代码
Every 4.0s: kubectl get hpa;echo;kubectl top pods                     master30.laoma.cloud: Sun Apr 19 11:13:29 2026

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

新建了一个pods

复制代码
Every 4.0s: kubectl get hpa;echo;kubectl top pods                     master30.laoma.cloud: Sun Apr 19 11:13:46 2026

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

又新建了一个pods

bash 复制代码
Every 4.0s: kubectl get hpa;echo;kubectl top pods                     master30.laoma.cloud: Sun Apr 19 11:15:46 2026

NAME   REFERENCE        TARGETS           MINPODS   MAXPODS   REPLICAS   AGE
web    Deployment/web   memory: 58%/60%   2         5         4          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  

又新建了一个pods

bash 复制代码
Every 4.0s: kubectl get hpa;echo;kubectl top pods                     master30.laoma.cloud: Sun Apr 19 11:17:46 2026

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   100m         3Mi

观察过程:

  1. 随着pod MEM使用率上升,自动扩展pod数量。
  2. 即使pod MEM使用率超过阈值,但pod数量不会超过5。
清理资源
bash 复制代码
# 删除 hpa
[root@master30 ~]# kubectl delete hpa web 

# 删除 deployment
[root@master30 ~]# kubectl delete deployment web

# 删除 svc
[root@master30 ~]# kubectl delete svc web 

控制扩容和减容

示例:

yaml 复制代码
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web
spec:
###############################
  behavior:
    # 缩容
    scaleDown:
      policies:
      - periodSeconds: 60
        type: Percent
        value: 20
      - periodSeconds: 60
        type: Pods
        value: 1
      selectPolicy: Min
      #每次减容时间,默认值为300
      stabilizationWindowSeconds: 30
    # 扩容
    scaleUp:
      policies:
      - periodSeconds: 60
        type: Percent
        value: 50
      - periodSeconds: 60
        type: Pods
        value: 2
      selectPolicy: Max
      # 每次扩容时间,默认值为0
      stabilizationWindowSeconds: 30
############################
  maxReplicas: 10
  metrics:
  - resource:
      name: cpu
      target:
        averageUtilization: 80
        type: Utilization
    type: Resource
  minReplicas: 2
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web

Vertical Pod Autoscaler

VPA 使用场景不多,这里不做实践演示。

VPA 作用

控制器将从一系列API(metrics.k8s.iocustom.metrics.k8s.ioexternal.metrics.k8s.io)中获取度量值,metrics.k8s.io API 通常由Metrics Server提供。根据 VPA 中定义的指标动态调整 Pod 的 requests 和 limits

VPA 适用场景

  • 资源配置不合理的服务
  • 长期运行、流量稳定的服务
  • Java、Go 等内存占用固定的应用
  • 不适合频繁扩缩的服务

VPA 核心特点

  • 不改变 Pod 数量
  • 自动给 Pod 推荐 / 设置 CPU / 内存
  • 生效需要重启 Pod(默认)
  • 比 HPA 少用,因为有侵入性

HPA 与 VPA 对比

项目 HPA 横向扩缩容 VPA 纵向扩缩容
全称 Horizontal Vertical
扩缩方式 增加 / 减少 Pod 数量 调整 CPU / 内存 request/limit
是否重启 Pod ❌ 不重启 ✅ 一般需要重启
适合负载 流量波动大 资源配置不合理
生效速度
稳定性
生产使用 非常普遍 较少
能否一起开 不能同时开(会冲突) -
支持资源 CPU、内存、自定义 CPU、内存
相关推荐
此生决int1 小时前
算法从入门到精通——双指针
算法
普马萨特1 小时前
Uber H3:地理网格索引在空间数据分析中的应用
数据结构·算法
alphaTao1 小时前
LeetCode 每日一题 2026/5/11-2026/5/17
算法·leetcode
洛水水1 小时前
【力扣100题】45.零钱兑换
算法·leetcode·职场和发展
Aaron15882 小时前
全频段 SDR干扰源模块解决方案(星链干扰、LORA无人机干扰)
人工智能·算法·fpga开发·硬件架构·硬件工程·无人机·信息与通信
AI科技星2 小时前
全域数学·球面拓扑微扰标准系数η=0.01 应用详解(典籍正式版)
人工智能·算法·数学建模·数据挖掘·机器人
逻辑君2 小时前
物理学研究报告【20260001】
人工智能·算法
AI科技星2 小时前
算法联盟·全域数学公理体系下黑洞标量毛发与LVK引力波O4全维理论、求导、证明、计算、验证、分析
人工智能·线性代数·算法·架构·学习方法·量子计算
谙弆悕博士2 小时前
【附C语言源码】C语言 栈结构 实现及其扩展操作
c语言·开发语言·数据结构·算法·链表·指针·