news 2026/7/17 2:26:23

14 · 集群实战:Metrics Server 部署与 HPA / Ingress 实测

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
14 · 集群实战:Metrics Server 部署与 HPA / Ingress 实测

系列专栏《深入剖析 Kubernetes》· 基于张磊极客时间专栏思想整理 · 适合 CSDN 发布

14 · 集群实战:Metrics Server 部署与 HPA / Ingress 实测

前两篇我们分别在「监控日志与 HPA 弹性伸缩」「容器网络」中建立了理论认知。本篇把理论搬到真实 4 节点集群(1 Master + 3 Worker,Kubernetes v1.28.2)上跑通三件最常被问到的事:

  1. kubectl top为什么一开始用不了?—— 部署Metrics Server
  2. HPA 到底能不能自动扩缩?—— 用 CPU 压测把它从 2 副本打到 10 副本;
  3. Ingress 七层路由怎么暴露业务?—— 用ingress-nginx把真实 nginx 通过域名nginx.local暴露出来。

所有输出均来自真实集群,踩坑一并记录。

┌──────────────────────────────────────────┐ │ K8s Cluster │ kubectl top ─────────▶ │ Metrics Server (Deployment, 1 replica) │ HPA 读取指标 ◀────────│ │ 请求 kubelet /stats/summary │ │ ▼ │ │ kubelet (每个节点, :10250) ◀── cAdvisor │ │ │ HPA 控制器 ── 监控 CPU% ─▶ Deployment/hpa-demo ── 扩/缩 ──▶ Pod×N │ │ │ 外部浏览器 ── Host:nginx.local ─▶ ingress-nginx(NodePort 30080) │ │ 七层路由 │ ▼ │ Service/nginx ──▶ Pod(nginx:1.25) │ └──────────────────────────────────────────┘

一、部署 Metrics Server:让kubectl top说话

Kubernetes 自身不采集资源指标。kubectl top的数据来自Metrics Server(metrics.k8s.io API),它周期性地从每个节点的 kubelet 拉取/stats/summary

1.1 镜像与参数改造(国内环境必做)

官方components.yaml默认从registry.k8s.io拉镜像,国内不可达。两处必改:

# 1) 镜像换成阿里云同步源sed-i's#registry.k8s.io/metrics-server/metrics-server:v0.7.2#registry.aliyuncs.com/google_containers/metrics-server:v0.7.2#g'components.yaml# 2) 自签证书 + 跳过 kubelet TLS 校验(演示环境最简方案)# 在 args 段追加:# - --kubelet-insecure-tls# - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname

踩坑 1:必须加--kubelet-insecure-tls。否则 Metrics Server 用 kubelet 的 API 证书做校验,而我们的 kubelet 证书 SAN 里只有内网 IP,校验会失败,日志报x509: certificate is valid for ... not ...

1.2 部署与验证(真实输出)

kubectl apply-fcomponents.yaml

等待约 1 分钟,APIService 变为AVAILABLE=True

NAME SERVICE AVAILABLE AGE v1beta1.metrics.k8s.io kube-system/metrics-server True 54s

此时kubectl top正式可用:

$ kubectltopnodes NAME CPU(cores)CPU% MEMORY(bytes)MEMORY% ecs-eb8a-0001 76m0% 1139Mi7% ecs-eb8a-0002 18m0% 714Mi4% ecs-eb8a-0003 16m0% 777Mi5% ecs-eb8a-0004 17m0% 692Mi4% $ kubectltoppods --all-namespaces --sort-by=cpu NAMESPACE NAME CPU(cores)MEMORY(bytes)kube-system kube-apiserver-ecs-eb8a-0001 32m 232Mi kube-system etcd-ecs-eb8a-0001 11m 36Mi kube-system kube-controller-manager-ecs-eb8a-0001 7m 45Mi kube-system metrics-server-5c5f7f897b-57wcz 5m 16Mi default nginx-6cbd46d475-5slfj 1m 7Mi

踩坑 2:刚apply完立刻kubectl top会报Metrics API not available。这是正常的——APIService 聚合注册 + Metrics Server 首次拉取需要几十秒,等它AVAILABLE即可。


二、HPA 自动伸缩实测:2 副本 → 10 副本

HPA(HorizontalPodAutoscaler,水平Pod自动伸缩器)是「声明式 API + 控制器模式」最直观的落地:你声明「CPU 平均利用率不超过 50%」,控制器持续比对实际值并调谐副本数。

2.1 工作负载 + HPA 定义

apiVersion:apps/v1kind:Deploymentmetadata:{name:hpa-demo}spec:replicas:2template:spec:containers:-name:hpa-demoimage:nginx:1.25# 已离线分发到所有节点resources:requests:{cpu:100m,memory:64Mi}# 不设 limit,压测时可真实冲高---apiVersion:autoscaling/v2kind:HorizontalPodAutoscalermetadata:{name:hpa-demo}spec:scaleTargetRef:apiVersion:apps/v1kind:Deploymentname:hpa-demominReplicas:2maxReplicas:10metrics:-type:Resourceresource:name:cputarget:{type:Utilization,averageUtilization:50}# 目标:每副本 CPU ≈ 50mbehavior:scaleDown:stabilizationWindowSeconds:60# 缩容稳定窗口,避免抖动

HPA 计算的分母是你声明的 requests.cpu。所以requests.cpu不写,HPA 就无法算利用率——这是新手最常见的「HPA 不生效」原因。

2.2 压测:在两个 Pod 里制造 CPU 忙循环

forpin$(kubectl get pods-lapp=hpa-demo-ojsonpath='{.items[*].metadata.name}');dokubectlexec$p--sh-c'nohup sh -c "while true; do : ; done" >/dev/null 2>&1 &'done

2.3 真实结果:自动扩容到上限

负载施加约 100 秒后:

NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE hpa-demo Deployment/hpa-demo 200%/50% 2 10 10 2m44s $ kubectl get pods -l app=hpa-demo -o wide NAME READY STATUS NODE hpa-demo-dcd8589df-6dzrn 1/1 Running ecs-eb8a-0003 hpa-demo-dcd8589df-qgsq9 1/1 Running ecs-eb8a-0004 hpa-demo-dcd8589df-bp7tz 1/1 Running ecs-eb8a-0004 hpa-demo-dcd8589df-c9vt4 1/1 Running ecs-eb8a-0003 hpa-demo-dcd8589df-mcrdw 1/1 Running ecs-eb8a-0003 hpa-demo-dcd8589df-rh76r 1/1 Running ecs-eb8a-0002 hpa-demo-dcd8589df-rl97d 1/1 Running ecs-eb8a-0004 hpa-demo-dcd8589df-s2nmw 1/1 Running ecs-eb8a-0002 hpa-demo-dcd8589df-vjp4t 1/1 Running ecs-eb8a-0004 hpa-demo-dcd8589df-wjjjf 1/1 Running ecs-eb8a-0002

TARGETS 从0%/50%升到200%/50%,副本数从 2 自动扩到 10(命中maxReplicas),且均衡散落到 3 个 Worker 节点。这正是「控制器调谐循环」:

┌────────────┐ 读取 ┌──────────────────┐ 实际状态 ──▶│ HPA 控制器 │◀────────│ Metrics Server │ (CPU 200%) └─────┬──────┘ └──────────────────┘ │ 调谐(Reconcile) ▼ ┌────────────┐ 计算 desired = current/target × replicas │ Deployment │──▶ 副本 2 → 10 └────────────┘

停掉负载、等待缩容稳定窗口(60s)后,副本自动回缩到minReplicas=2扩容快、缩容稳,这就是 HPA 的设计哲学。


三、Ingress 七层路由实测:用域名暴露真实 nginx

ClusterIP / NodePort 只能做四层(IP+端口)暴露。要在80 端口用不同域名/路径路由到不同服务,必须靠Ingress(七层)。

3.1 部署 ingress-nginx(精简版,规避 webhook 复杂度)

采用旧版 controller(v1.10.1,阿里云镜像),以 NodePort 30080/30443 暴露,便于从节点公网 IP 直接验证:

apiVersion:apps/v1kind:Deploymentmetadata:{name:nginx-ingress-controller,namespace:ingress-nginx}spec:template:spec:containers:-name:nginx-ingress-controllerimage:registry.aliyuncs.com/google_containers/nginx-ingress-controller:v1.10.1args:-/nginx-ingress-controller---default-backend-service=default/nginx# 复用 default/nginx 作默认后端---ingress-class=nginx

后端应用与 Ingress 规则:

apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:nginxannotations:kubernetes.io/ingress.class:nginxnginx.ingress.kubernetes.io/rewrite-target:/spec:ingressClassName:nginxrules:-host:nginx.localhttp:paths:-path:/pathType:Prefixbackend:{service:{name:nginx,number:80}}

3.2 验证外部访问(真实输出)

# 经 ingress-nginx 的 NodePort(30080)+ Host 头访问curl-H'Host: nginx.local'http://<节点公网IP>:30080/

返回真实 nginx 默认页:

<!DOCTYPEhtml><html><head><title>Welcome to nginx!</title></head><body><h1>Welcome to nginx!</h1></body></html>

3.3 踩坑合集(本篇最值钱的部分)

踩坑 3(404):缺 IngressClass。
只写ingressClassName: nginx但集群里没有对应的 IngressClass 资源,controller 不接纳该 Ingress,请求落到 controller 内部默认 404。解决:补一个IngressClass(见deploy/ingress-class.yamlcontroller: k8s.io/ingress-nginx)。

踩坑 4(503):RBAC 缺endpointslices
旧版 controller 通过EndpointSlices(discovery.k8s.io)获取后端端点。若 ClusterRole 只授权了老endpoints,日志会报Service "default/nginx" does not have any active Endpoint,外部访问得到 503。必须补:

-apiGroups:["discovery.k8s.io"]resources:["endpointslices"]verbs:["list","watch"]-apiGroups:["coordination.k8s.io"]# 领导者选举需要resources:["leases"]verbs:["get","list","watch","create","update","patch"]

踩坑 5(镜像拉取):演示镜像走离线分发。
公共镜像在 Worker 上拉取不稳。本集群把nginx:1.25在 Master 用ctr images export导出为 tar,经内网 HTTP 分发到 3 个 Worker 后ctr images import并打标准 tagdocker.io/library/nginx:1.25,Pod 用标准名即可命中本地镜像,彻底绕开公网拉取。


四、小结 / 核心要点

  1. Metrics Server 是kubectl top与 HPA 的前置依赖,国内部署务必改镜像源 + 加--kubelet-insecure-tls
  2. HPA 玩的是「声明式期望 vs 实际状态」的调谐:本实测把 2 副本在 CPU 压测下自动扩到 10,停载后回缩到 2。
  3. HPA 生效前提是 Pod 声明了requests.cpu,否则无法计算利用率。
  4. Ingress 提供七层路由,但旧版 ingress-nginx 对IngressClassendpointslicesRBAC 有硬性要求,漏掉任何一个都会以 404/503 形式坑你。
  5. 镜像分发是国内部署第一痛点:离线export/import+ 打标准 tag 是最稳妥的兜底方案。

配套部署脚本与 YAML 见仓库deploy/metrics-components.yamlhpa-demo.yamlingress-nginx-legacy.yamlingress-class.yamlnginx-app-ingress.yaml

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/17 2:25:18

ima.copilot:面向工业工作流的垂直领域AI协作者

1. 项目概述&#xff1a;这不是AI助手&#xff0c;是嵌入工作流的“第二大脑”“ima.copilot 初体验”这个标题乍看像一句轻描淡写的社交平台打卡&#xff0c;但如果你最近在技术社区、设计群或产品团队的晨会里听到过这个词&#xff0c;大概率不是在聊某个新出的聊天机器人。我…

作者头像 李华
网站建设 2026/7/17 2:24:45

苹果M7 Ultra芯片:1.5TB统一内存如何重塑本地AI开发与高性能计算

苹果正在研发的M7 Ultra芯片最近引起了广泛关注&#xff0c;特别是其高达1.5TB的统一内存配置&#xff0c;这在消费级计算设备中堪称革命性突破。作为苹果M系列芯片路线图的重要调整&#xff0c;M7 Ultra直接跳过了M6 Pro和M6 Max版本&#xff0c;计划在2028年推出&#xff0c;…

作者头像 李华
网站建设 2026/7/17 2:24:31

量化交易在熊市折磨阶段的策略实现与TACOing模式识别

最近不少量化交易者都在关注一个现象&#xff1a;当前市场似乎进入了"折磨阶段"&#xff0c;各种指标显示熊市进度已接近80%。这种市场环境下&#xff0c;传统的技术分析工具往往失灵&#xff0c;而"川普震荡TACOing"这样的新概念开始进入量化圈的视野。作…

作者头像 李华
网站建设 2026/7/17 2:23:42

Vue+Spring Boot实现的智能办公毕设项目(含AI表单识别与会议摘要)

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;一套开箱即用的毕业设计级智能办公系统&#xff0c;前后端分离&#xff0c;后端用Spring Boot开发&#xff0c;前端基于Vue.js构建&#xff0c;数据库脚本齐全&#xff0c;部署文档详细。系统支持用户注册登录、…

作者头像 李华
网站建设 2026/7/17 2:23:28

Windows系统PIN不可用问题排查与修复指南

1. 问题现象与背景解析当你在Windows 10/11系统开机或唤醒时看到"PIN不可用"的提示&#xff0c;这通常意味着系统无法验证你设置的登录PIN码。这种情况多发生在以下场景&#xff1a;系统更新后首次启动硬件配置发生变化&#xff08;如更换主板&#xff09;微软账户同…

作者头像 李华