K8S集群Pod动态弹性扩缩容(HPA)部署实战:TaoToken统一API通道下的指标采集与扩缩容验证

发布时间:2026/10/8 12:10:47
K8S集群Pod动态弹性扩缩容(HPA)部署实战:TaoToken统一API通道下的指标采集与扩缩容验证 1. 从一次线上抖动说起为什么 HPA 装了却不动很多同学第一次在 K8S 集群里配 HPAHorizontal Pod AutoscalerPod 水平自动扩缩容都会遇到一个很尴尬的场景YAML 写完了kubectl get hpa也显示出来了但压测一上副本数纹丝不动TARGETS 那一列永远是unknown/50%。我最早在测试集群里折腾这套东西时就卡在这个状态整整一个下午最后发现根因是 metrics-server 没起来HPA 拿不到任何 CPU 指标自然没法算利用率。这篇文章要解决的就是这条完整链路K8S 集群里基于 CPU 指标让 Pod 真正实现弹性扩缩容。它适合三类人一是刚接触 K8S、想把 HPA 跑通的后端或运维同学二是已经在用 Deployment 但没做过自动扩缩容、想补上这块能力的开发者三是想把集群里的指标采集和外部 API 调用统一管理起来、减少散落 Key 的团队。核心检索词就是 K8S、Pod、HPA、弹性扩缩容、部署这几个全文围绕它们展开。整条链路其实分四段metrics-server 提供指标 → HPA 控制器读取指标并计算期望副本数 → Deployment 调整 replicas → 压测验证扩缩容是否真的触发。任何一段断了HPA 都不会动。下面我按可复制的顺序把每一步的命令、配置和判定标准都写清楚你照着敲就能复现。另外提一句场景里的 TaoToken它在这里的角色是统一 API 通道。当你的集群里跑着多个需要调用大模型的服务比如日志分析、告警摘要、代码审查 Agent每个服务各自维护一套 Key 和 Base URL 会很乱。用 TaoToken 的统一 Key 和 API 通道把这些调用收敛到一个入口配合 HPA 做弹性时扩出来的 Pod 读同一份配置即可不用为每个副本单独配凭证。官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 后面配置里会用到。2. 前置准备metrics-server 与 TaoToken 统一通道2.1 先确认 API Aggregator 已开启metrics-server 不是直接读 kubelet 就完事它是通过 Kubernetes 的 API 聚合层API Aggregator以metrics.k8s.io这个扩展 API 的形式对外提供指标的。所以第一步要确认 kube-apiserver 开了聚合路由。用 kubeadm 部署的集群编辑静态 Pod 清单vim /etc/kubernetes/manifests/kube-apiserver.yaml在command列表里加上这一行- --enable-aggregator-routingtrue保存后 kube-apiserver 这个静态 Pod 会自动重启。验证是否生效kubectl describe pod kube-apiserver-k8s-master -n kube-system | grep aggregator能看到--enable-aggregator-routingtrue就说明配置进去了。这一步不做后面kubectl top会直接报the server could not find the requested resource (get services http:metrics-server)。2.2 部署 metrics-server下载官方 components.yaml版本按你集群的兼容性选这里用 v0.8.1wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.8.1/components.yaml打开文件改两处。第一处是给 metrics-server 容器加跳过 kubelet 证书校验的参数自签证书集群不加会一直报 x509 错误- --kubelet-insecure-tls第二处是镜像地址国内环境换成可访问的源image: registry.aliyuncs.com/google_containers/metrics-server:v0.6.1然后应用kubectl apply -f components.yaml kubectl get pod -n kube-system | grep metrics-server等 Pod 变成 Running再验证指标是否真的出来了kubectl top nodes kubectl top pods -n kube-system两条命令都能返回 CPU/内存数值说明 metrics-server 这条链路通了。如果kubectl top nodes报error: Metrics API not available回到 2.1 检查聚合层。2.3 TaoToken 统一通道的接入位置集群里如果有服务要调用大模型建议把凭证收敛成一份 ConfigMap Secret所有副本共享。TaoToken 的 Base URL 固定为https://taotoken.net/apiKey 从控制台生成。你可以这样建一个 Secretkubectl create secret generic taotoken-cred \ --from-literalTAOTOKEN_API_KEYsk-你的Key \ -n default然后在 Deployment 里通过环境变量注入扩出来的每个 Pod 自动读到同一份配置。这样 HPA 扩容时不会因为凭证分散而出现某个副本调不通的情况。Key 的生成入口在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。3. 可复制配置php-apache 与 HPA YAML3.1 部署测试应用 php-apache用官方 HPA 示例应用它自带resources.requests.cpu这是 HPA 计算利用率的分母没有它 HPA 会报missing request for cpu。wget https://k8s.io/examples/application/php-apache.yaml sed -i s|registry.k8s.io/hpa-example|mirrorgooglecontainers/hpa-example| php-apache.yaml kubectl apply -f php-apache.yaml关键点在于 Deployment 里这段resources: requests: cpu: 200mHPA 的 CPU 利用率 实际用量 / requests所以 requests 必须设。验证一下kubectl get deploy/php-apache kubectl describe pod -l runphp-apache | grep -A5 Requests3.2 用声明式 YAML 创建 HPA命令行kubectl autoscale能快速建但生产里更推荐 YAML方便版本管理。下面这份可以直接复制apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: php-apache namespace: default spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: php-apache minReplicas: 1 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50 behavior: scaleDown: stabilizationWindowSeconds: 300 policies: - type: Percent value: 100 periodSeconds: 15几个参数说明averageUtilization: 50表示所有 Pod 的平均 CPU 利用率目标 50%minReplicas/maxReplicas限定副本范围behavior.scaleDown.stabilizationWindowSeconds: 300是缩容冷却窗口默认 5 分钟防止指标抖动导致频繁缩容。应用kubectl apply -f hpa.yaml kubectl get hpa php-apache正常输出里 TARGETS 应该显示cpu: 0%/50%或类似数值而不是unknown。3.3 如果服务要调 TaoToken配置片段假设你的应用需要调用大模型做推理Deployment 里这样注入env: - name: OPENAI_BASE_URL value: https://taotoken.net/api - name: OPENAI_API_KEY valueFrom: secretKeyRef: name: taotoken-cred key: TAOTOKEN_API_KEY - name: MODEL_ID value: claude-3-5-sonnetBase URL、Key、Model ID 三件套齐全副本扩到几个都读同一份。模型 ID 具体可选哪些可以在模型对话页确认https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。4. 验证请求压测触发扩缩容4.1 启动负载生成器开一个新终端跑一个 busybox 循环请求 php-apachekubectl run -i --tty load-generator --rm \ --imagebusybox:1.28 \ --restartNever \ -- /bin/sh -c while sleep 0.01; do wget -q -O- http://php-apache; done4.2 实时观察 HPA 行为另开终端 watchkubectl get hpa php-apache --watch几十秒内你会看到 TARGETS 从0%/50%涨到200%REPLICAS 从 1 逐步往上加。同时看 Podkubectl get pods -l runphp-apache -w典型过程是CPU 冲高 → HPA 计算期望副本数 → Deployment 扩容 → 新 Pod 起来分担流量 → 利用率回落到 50% 附近。扩容是秒级响应的因为 HPA 默认每 15 秒同步一次指标。4.3 停止压测与缩容观察在负载终端按Ctrl Cload-generator Pod 自动清理。此时 CPU 掉下来但副本不会立刻缩因为stabilizationWindowSeconds: 300会等 5 分钟确认指标持续低位然后才逐步缩回 minReplicas。这是防止抖动的设计不是 bug。判定扩缩容真正生效的标准有三条一是kubectl get hpa的 TARGETS 有真实百分比而非 unknown二是压测期间 REPLICAS 数值上升三是kubectl top pods能看到新 Pod 的 CPU 被分摊。三条都满足链路就是通的。5. 常见报错排查从 401 到 unknown 指标5.1 TARGETS 显示unknown/50%这是最高频的问题。原因通常两个metrics-server 没跑起来或者 Pod 没设resources.requests.cpu。排查顺序kubectl top pods # 报错说明 metrics-server 有问题 kubectl describe hpa php-apache # 看 Events 里的具体原因如果 Events 里写failed to get cpu utilization: missing request for cpu就是 requests 没配。如果写unable to get metrics回到第 2 节检查 metrics-server。5.2 metrics-server 报 x509 或 connection refused日志里出现x509: cannot validate certificate或dial tcp ... connection refused基本都是没加--kubelet-insecure-tls或者 kubelet 的 10250 端口不通。先确认参数加了再检查节点防火墙。5.3 调用外部 API 报 401 或 local proxy failed如果你的服务通过 TaoToken 调模型时报 401先确认 Secret 里的 Key 没写错、没多空格kubectl get secret taotoken-cred -o jsonpath{.data.TAOTOKEN_API_KEY} | base64 -d报local proxy failed或连接超时检查 Base URL 是不是写成了带路径的地址正确值是https://taotoken.net/api不要多加/v1之类后缀。如果报reading choices这类解析错误通常是返回体不是预期格式确认 Model ID 拼写正确可以在模型对话页对照可用模型列表。5.4 HPA 不缩容压测停了但副本一直不降先看是不是还在 5 分钟稳定窗口内。超过 10 分钟还不缩检查behavior.scaleDown配置以及是否有其他指标比如自定义指标仍在高位。另外kubectl describe hpa的 Events 会告诉你最近一次扩缩容决策的原因。5.5 OAuth 或鉴权类报错如果接入的是需要 OAuth 流程的服务报OAuth token expired之类说明凭证需要刷新。TaoToken 的 Key 是长期有效的一般不会遇到这个问题若确实遇到去控制台重新生成即可https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。6. 把统一通道用起来从验证到长期运行链路跑通之后下一步是把它用在实际业务里。如果你的集群里跑的是编码类 Agent 或长期任务型服务HPA 负责按负载扩缩副本TaoToken 负责统一 API 通道两者配合能省掉很多凭证管理的心智负担。长期编码或 Agent 场景可以看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 控制台在 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。一个实用技巧把 HPA 的averageUtilization设得比实际目标略低一点比如目标 60% 就设 50%给扩容留出提前量避免流量突增时 Pod 还没起来就被打满。另外minReplicas别设 0除非你用了 KEDA 这类支持缩到零的方案原生 HPA 缩到 0 会导致服务不可用。最后提醒一句压测验证完记得把 load-generator 停掉不然它会一直跑白白消耗集群资源。整套流程我在测试集群里反复跑过多次只要 metrics-server 正常、requests 配了、HPA YAML 没写错扩缩容就是稳定触发的。