当前位置: 首页 > news >正文

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

http://www.cnnetsun.cn/news/3441243.html

相关文章:

  • ima.copilot:面向工业工作流的垂直领域AI协作者
  • 苹果M7 Ultra芯片:1.5TB统一内存如何重塑本地AI开发与高性能计算
  • 量化交易在熊市折磨阶段的策略实现与TACOing模式识别
  • Vue+Spring Boot实现的智能办公毕设项目(含AI表单识别与会议摘要)
  • Windows系统PIN不可用问题排查与修复指南
  • 5分钟快速上手:GBFR Logs - 碧蓝幻想Relink免费战斗数据分析神器
  • VC6.0编译的纯C++2048游戏,双击test.exe即玩,WASD操作+图形界面
  • Java毕设实战包:SSM+Redis高并发秒杀系统(含环境配置与全流程演示)
  • iKuai软路由IPv6配置指南:实现内网设备直连公网
  • Windows 11下VirtualBox安装与优化全指南
  • Tina Linux下glibc交叉编译与优化指南
  • 汉服租赁微信小程序全套开发资源:SSM后端+小程序前端+操作视频+设计文档
  • Claude for Teachers:教育AI的数据安全承诺与技术实现
  • C/C++不定参技术详解:从宏函数到可变参数模板的实战指南
  • 2026 年 7 月解读:北京金三科技 合资 ICP 代办综合实力与合作参考
  • C++高并发服务器Connection模块设计:基于muduo的事件驱动与线程安全实现
  • 手写C++ SMO算法实现SVM:从数学推导到工程实践详解
  • 广州程序员注意:键盘全部失灵?5 步自查不用花钱换新
  • 抖音批量下载工具实战手册:三步搞定无水印视频批量采集
  • AI模型安全:对抗攻击与防御技术全景
  • 3分钟上手:用开源AI视频分析工具让视频内容自动生成文字描述
  • Unity 3D 基础笔记(六)UGUI 基础画布与自适应
  • Vibe Coding:AI辅助编程的新范式与实践指南
  • WSL2环境搭建与生产力工具链配置指南
  • 二手iMac 5K内存升级与性能优化指南
  • C语言跨平台路径处理实战:统一抽象层与核心函数实现
  • Linux内核随机数池初始化与日志级别配置详解
  • C++酒店管理系统实战:从面向对象设计到文件持久化完整实现
  • JUnit5综合进阶:构建高效可维护的Java单元测试体系
  • 50Hz灯具频闪问题解析:从原理到解决方案的完整指南