拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Kubernetes性能测试实战:从环境搭建到瓶颈定位

开门见山说个事儿我在Kubernetes上做性能测试做了快三年最深的感触是——过去那套开台虚拟机、装上压测工具、跑个脚本出报告的玩法在容器化环境里基本行不通了。不是因为工具不好用而是被测对象变了。传统性能测试面对的是一个相对静态的系统而Kubernetes环境下你测的是一个会自愈、会扩缩容、会重新调度的活系统。你压测时Pod被重新调度了应用重启了网络路径变了这些在传统环境里都是事故在K8s里却是日常。所以我们需要一套新的范式既能测出系统性能上限又能搞清楚K8s本身的调度、资源限制、网络转发对性能的影响。这篇文章我用自己的实战经验把Kubernetes环境下的性能测试从环境搭建、工具选型、指标采集到瓶颈定位完整拆一遍。适合正在做容器化改造、准备把性能测试搬上K8s的运维和测试同学。文章里不会讲太多抽象理论更多的是我在项目中踩过的坑、验证过的方法、以及可以直接抄走的配置和步骤。1. 为什么Kubernetes让性能测试变了玩法1.1 传统性能测试的三个假设在K8s里全都不成立以前做性能测试我们默认三个前提第一被测系统的部署方式是固定的IP不变、端口不变、拓扑不变第二资源是独占的这台机器上的CPU、内存就是给这个应用用的第三故障是例外正常情况下系统不会自己重启、不会自己挪位置。这三个假设在Kubernetes里全部失效。K8s里的Pod IP是临时的Deployment滚动更新一次IP就全变了同一个Node上可能跑着十几个PodCPU争抢是常态而不是例外应用崩溃后Kubelet会自动重启容器这本来是K8s的亮点但对性能测试来说这意味着你看到的性能数据可能是容器重启后的数据而非稳态数据。我见过一个团队用传统方式给K8s里的服务做压测测出来的TPS一直不稳定忽高忽低。排查了三天最后发现是HPA水平Pod自动伸缩在压测过程中自动扩容了后端实例从3个变成了8个TPS当然会变化。传统性能测试里不存在被测系统自己变胖这种事情但在K8s里这就是默认行为。所以Kubernetes下的性能测试第一步不是选工具而是意识到你面对的是一个动态系统相应的测试设计、结果分析都得变。1.2 Kubernetes性能测试到底在测什么把这个问题拆开来看K8s环境下的性能测试实际上包含三个层面应用层性能代码本身有没有性能问题接口响应时间、吞吐量、并发处理能力这部分和传统性能测试一样。平台层性能K8s集群本身的性能包括API Server的处理能力、etcd的读写延迟、kubelet的调度效率、Service/Ingress的转发性能。很多团队忽略这一层结果出了问题到处找原因最后发现是集群自身扛不住了。协同层性能应用和平台的交互表现。比如Pod启动速度、滚动更新耗时、HPA扩容响应时间、故障恢复时间。这些指标在传统性能测试里根本没有但在K8s里它们直接影响用户体验和SLA。我自己的经验是一次完整的K8s性能测试至少需要覆盖应用层和平台层协同层的指标可以在专项测试里做。上次我们给一个核心交易系统做压测QPS压到2000的时候业务响应正常但API Server的CPU飙到85%etcd的fsync延迟超过了100ms。这说明瓶颈根本不在应用而在控制面。这种结论传统性能测试是给不出来的。2. 测试环境搭建不踩这些坑集群白建2.1 测试集群和生产集群必须分开这是我吃过亏才悟出来的事儿。K8s集群的资源隔离如果不做性能测试数据就废了。前期为了图省事直接在已有的开发集群上做压测结果压测流量把开发同事的业务全打挂了而且因为共享etcd我们自己测出来的数据也严重失真API Server响应时间忽高忽低。正确的做法是测试环境单独建集群至少保证以下三点。Worker节点和应用节点物理隔离标签加硬亲和性确保压测应用不会被调度到系统组件所在的节点。如果条件允许压测施压机单独用一台物理机或独立虚拟机不要和被测应用混部。保证测试集群的版本和生产集群一致。K8s版本差异可能导致调度策略、网络组件行为不同性能表现天差地别。2.2 用kubeadm还是二进制部署测试集群我见过不少用minikube跑性能测试的怎么说呢当demo可以出报告不行。minikube是单节点很多调度行为、网络行为和真实多节点集群完全不同。用kubeadm搭一个三节点集群是最低配置我之前常用的规格是3台4核8G的机器做MasterWorker混合节点跑小型压测足够如果是正式的性能基准测试建议至少5台3台Master、2~3台Worker。不过有一点要注意测试集群的规格不要比生产环境差太多。我见过团队拿3台低配机器搭测试集群压测时应用还没到瓶颈集群先崩了最后分不清到底测的是应用还是集群。如果你测的是应用瓶颈集群资源至少要比生产环境宽裕20%~30%这样排除了平台瓶颈应用问题才好暴露出来。2.3 监控链路一定要在压测前搭好性能测试的本质是给系统加压并观测系统行为观测不到压测就白做。K8s环境下的监控不能再像传统环境那样装个Zabbix看CPU内存就完事至少要覆盖四个维度节点维度CPU、内存、磁盘、网络用node-exporter采集。容器维度每个Pod的CPU、内存、网络IO、磁盘IO用cAdvisor采集它默认集成在kubelet里。K8s对象维度Pod状态变化、Deployment副本数、HPA伸缩事件、调度事件用kube-state-metrics采集。控制面维度API Server的请求延迟和错误率、etcd的读写延迟、kubelet的PLEG重试次数这些需要单独配置。我常用的组合是Prometheus Grafana Alertmanager配合kube-prometheus-stack这个Helm Chart一套装完。不过要注意Prometheus抓取数据本身也会消耗集群资源测试前要给Prometheus单独预留资源别让监控成为压测的瓶颈。2.4 etcd性能检查是容易被忽视的一步这里多说一句etcd。学K8s的时候老师讲过K8s所有的状态都存在etcd里但很多人做性能测试时根本没想过etcd会不会成为瓶颈。我踩过一个大坑压测过程中频繁创建和销毁Job对象结果etcd写入压力太大整个集群的响应都变慢了连kubectl get pods都要卡好几秒。后来我养成了一个习惯正式压测前先做一次etcd基准测试看看磁盘IOPS和延迟是否正常。etcd对磁盘延迟极其敏感普通机械盘根本扛不住SSD是标配有条件上NVMe。另外etcd的磁盘空间也要监控etcd的compact和defrag操作在高负载下会引发性能抖动这个后面在排查那块会细讲。3. 压测工具选型与部署容器化施压的正确姿势3.1 主流工具横评JMeter、Locust、k6、Vegeta怎么选先说结论K8s环境下的压测工具首选是k6其次JMeterLocust看场景。为什么k6适合K8s第一k6是Go写的单机并发能力非常强资源占用低跑在容器里很轻量第二k6支持通过Kubernetes Operator做分布式压测可以动态创建Pod来扩展施压能力第三k6的脚本是JavaScript写的生态丰富断言和指标系统都很完善。JMeter虽然老牌但它是Java写的吃内存单机并发到2000就需要相当大的堆内存。在K8s里跑JMeter不是不行就是要小心资源限制之前在K8s里部署JMeter InfluxDB模式踩了好几次堆内存溢出的坑。不过JMeter胜在生态插件多做复杂的业务流比k6方便所以团队里如果测试同学只会JMeter用它也没问题就是对资源要求高一些。Locust是Python写的脚本灵活但性能是真的一般单机并发几千就吃力了。适合做小规模的压力测试和场景复杂的测试不适合高并发场景。3.2 基于JMeter的K8s分布式压测部署方案虽然我推荐k6但考虑到JMeter在很多团队里的存量资产比较多我把自己验证过的JMeter部署方案分享出来。控制端和施压端分离控制端跑在单独的Pod里施压端通过Deployment动态调整副本数。我的JMeter镜像Dockerfile是这样的FROM openjdk:11-jre-slim ARG JMETER_VERSION5.6.3 RUN apt-get update apt-get install -y wget unzip \ wget https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-${JMETER_VERSION}.tgz \ tar -xzf apache-jmeter-${JMETER_VERSION}.tgz -C /opt \ rm apache-jmeter-${JMETER_VERSION}.tgz ENV JMETER_HOME/opt/apache-jmeter-${JMETER_VERSION} ENV PATH${JMETER_HOME}/bin:${PATH}Deployment的资源配置要特别注意。JMeter是CPU密集型的施压端Pod的CPU要保证充足内存也要给足。我踩过的坑是没给JMeter设堆内存限制JVM默认只用了物理内存的1/4导致压测时大量GC测试数据严重失真。解决办法是设置JVM参数JVM_ARGS-Xms1g -Xmx2g -XX:UseG1GC这个尺寸根据你需要的并发量调整。我一般给JMeter施压Pod分配2核4G单Pod可以跑到1000~1500并发具体取决于脚本复杂度。施压端的Deployment大概长这样apiVersion: apps/v1 kind: Deployment metadata: name: jmeter-slave spec: replicas: 3 selector: matchLabels: app: jmeter-slave template: metadata: labels: app: jmeter-slave spec: containers: - name: jmeter-slave image: myrepo/jmeter:5.6.3 args: [-s, -Jserver.rmi.localport50000] resources: requests: cpu: 2 memory: 4Gi limits: cpu: 2 memory: 4Gi控制端Pod执行压测时通过Service发现施压端。这里有个关键点JMeter的RMI通信在K8s里配置比较麻烦需要处理好网络策略和端口映射不然施压端收不到控制端的指令。3.3 施压端在K8s里跑的几个关键注意事项第一网络模式。施压Pod默认通过ClusterIP访问被测服务但如果你想压测Ingress或NodePort层施压流量要经过额外的转发路径这个瓶颈要提前想清楚。我一般会区分两种情况测应用性能就走ClusterIP测集群入口性能就压Ingress地址。第二施压端和被压端不要放在同一个Node上。如果施压端和被压端抢同一个Node的CPU结果就是谁也测不准。解决方法是给施压端和被压端分别打不同标签用PodAntiAffinity强制分开调度。第三避免压测工具自身成为瓶颈。我遇到过压测端Pod CPU打满导致发压数据不准确的情况。压测之前先只跑少量请求确认压测端的CPU和内存消耗在合理范围内再逐渐加压。我一直坚持的做法是施压端CPU使用率不要超过70%超过就加副本不然生成的压力曲线是畸形的。4. 指标采集与分析K8s环境下性能测试的魂4.1 从传统三大指标到黄金信号传统性能测试盯三个指标TPS、响应时间、错误率。这三个指标在K8s里依然重要但不够了。Google SRE提出的四大黄金信号——延迟、流量、错误、饱和度——更贴合K8s动态环境的分析逻辑。延迟服务的响应时间特别注意区分正常延迟和排队延迟。K8s环境里一个Pod CPU限流了应用的响应时间会呈指数级上升这就是饱和度影响延迟的典型例子。流量QPS、并发数、网络吞吐。在K8s里流量还要细化到Service级别的流量、Ingress流量、Pod间的东西向流量。错误HTTP错误码、应用异常、Pod重启次数。K8s里有个特殊指标是重启次数如果压测过程中Pod频繁重启说明应用有严重问题比如内存泄漏导致OOMKilled。饱和度CPU使用率、内存使用率、线程池利用率、连接池利用率。K8s里尤其要看CPU限流throttling因为limit设置不当会导致容器CPU被内核节流应用表面上看CPU不高实际性能已经受损。我强烈建议大家把这四个维度的指标全部接入Grafana做一个性能测试专用Dashboard。压测过程中实时盯着比事后分析日志高效太多。4.2 K8s特有的关键指标这些数据传统环境看不到K8s环境下有几个指标性能测试报告里如果缺了它们报告是不完整的CPU ThrottlingCPU节流。这个是K8s性能测试最容易踩的暗坑。CPU limits设置后内核用CFS配额来限制CPU使用容器超过配额就会被节流。问题是CFS的统计窗口是100ms如果应用在窗口内瞬时CPU冲高就会被节流即使平均CPU使用率很低。如何看节流情况# 进入容器后执行 cat /sys/fs/cgroup/cpu/cpu.stat看到nr_throttled数字持续增长说明容器被节流了应用的延迟可能会飙升。这个指标在传统环境里根本不存在但在K8s里必须检查。Pod调度延迟。从Pod创建到Pod运行的时间。这个指标在做容量评估和HPA测试时很关键。HPA扩容触发后新增Pod要经过调度、拉镜像、启动、就绪探测等多个环节这个延迟通常需要5~30秒不等。容器重启次数与原因。压测过程中如果容器被OOMKilled数据要重新测因为系统状态已经变了。通过kubectl describe pod可以查看Last State和Exit CodeExit Code 137表示被SIGKILL杀死通常就是OOM。节点资源水位。不仅是单个Pod的CPU内存还要看整个Node的Allocatable和已分配量。K8s调度器是根据requests来调度Pod的如果一个Node上所有Pod的requests已经把CPU占满即使实际使用率很低新Pod也无法调度到这个Node。4.3 性能测试指标收集的几个实用技巧Prometheus采集指标时几个查询建议直接存下来应用QPS和延迟如果是Java应用接Micrometer Prometheus Registry可以按接口维度统计如果是Go应用用官方prometheus client库。Pod CPU使用率rate(container_cpu_usage_seconds_total{container!POD}[1m])注意排除POD这个pause容器。Pod内存使用量container_memory_working_set_bytes这个比usage更接近实际占用。CPU节流rate(container_cpu_cfs_throttled_seconds_total[1m])。API Server延迟apiserver_request_duration_seconds的histogram。etcd磁盘延迟etcd_disk_wal_fsync_duration_seconds。我建议把上面这些指标固化到Grafana Dashboard里压测时切到对应页面比每次临时写PromQL高效太多。4.4 资源画像压测完最重要的产出物传统性能测试产出的是系统能扛多少QPS的结论。K8s环境下的性能测试应该更进一步给出每个服务的资源画像在某个QPS下单个Pod实际消耗多少CPU、多少内存延迟是多少副本数应该设置多少。这个资源画像直接指导容量规划。比如压测发现某个服务在1000 QPS下单Pod需要2核CPU和1.5G内存响应时间20ms那么根据业务预估的峰值流量可以算出需要几个副本以及每个Pod的requests和limits怎么设置。我习惯于生成一张资源画像表比单纯写一份报告有用得多。5. 瓶颈定位方法论从现象到根因的排查路径5.1 一个典型的K8s性能瓶颈分析案例拿一个真实案例来拆解。上次压测一个电商系统的订单服务现象是并发到500时响应时间从50ms飙升到2秒错误率从0涨到5%。按传统思路第一反应是查应用代码、查数据库慢查询。但换了K8s视角的排查路径完全不同。我先查了Pod的CPU Throttling发现nr_throttled在持续增长说明容器被CPU限制卡住了。再看Node上的其他Pod发现同Node上有一个日志采集的DaemonSet PodCPU占用高达80%和业务Pod抢CPU。根因就是这个日志采集Pod的CPU没有设置limits一直无限扩张。修复方式是给日志采集Pod加上CPU limits同时给业务Pod设置合理的CPU request确保优先调度。一次简单的资源配额调整性能就恢复到了正常水平。这类问题传统环境根本不会遇到但在K8s里非常常见。所以我把这个案例放在最前面想强调K8s性能瓶颈排查先看平台层再看应用层千万不要一上来就查代码。5.2 五步定位法我排查性能瓶颈的标准路径第一步看Pod状态。压测过程中持续观察kubectl get pods -o wide看有没有Pending、CrashLoopBackOff、OOMKilled状态的Pod。有就直接查事件kubectl describe pod xxx。第二步看节点状态。kubectl top nodes看整体资源水位如果某个Node的CPU或内存已经打满看是哪些Pod吃掉资源用kubectl top pods --sort-bycpu按使用量排序。第三步看网络层。Pod之间通信走的是CNI插件可能是Calico、Flannel或者Cilium。网络问题经常表现为应用间调用延迟高、丢包、连接超时。常用排查工具是kubectl exec进Pod里用ping、telnet、curl测试连通性必要时抓包。K8s里还有一个常见网络问题DNS解析失败导致连接超时尤其是在Pod频繁重建时CoreDNS的缓存失效会引发大量DNS查询。第四步看控制面。如果应用层和节点层都正常就要怀疑集群控制面了。查API Server的指标和日志查etcd的延迟。我遇到过的最奇葩问题etcd的磁盘使用超过80%虽然还没满但因为碎片太多导致延迟飙升影响了整个集群的调度连带着性能测试数据全部异常。第五步看应用本身。前面四步都排除了才回头查应用代码。数据库慢查询、连接池耗尽、代码阻塞、锁竞争这些传统性能测试的手段这时候才派上用场。这个排查路径保证了我95%以上的性能问题都能在半小时内定位到方向而不是像以前一样盲目地查代码。5.3 网络组件对性能的影响比你想象的大K8s环境的网络转发路径比传统虚拟机环境长得多。一个Service请求从Pod A到Pod B要经过Pod A的veth → Node A的cbr0/eth0 → CNI插件封装 → 实际网络 → Node B的cbr0/eth0 → Pod B的veth。如果用的是Calico并且开启了IPIP模式数据包还会多一层隧道封装性能损耗更大。我自己实测的数据在同一个集群里直接访问Pod IP比通过Service访问快10%~20%跨Node访问比同Node访问慢10%~15%如果开启了Calico的IPIP模式延时会额外增加0.2~0.5ms。网络层已经是K8s性能测试不能忽视的因素。所以在性能测试报告中一定要注明网络拓扑和CNI插件类型否则数据没法横向对比。我在多个团队都遇到过换了CNI组件后性能大幅下降/上升的情况最后发现是网络路径发生了变化应用本身没有改动。6. 从containerd到K8s性能测试运行时层面的几个隐藏因素6.1 K8s调用containerd的机制对性能测试意味着什么搜索热词里有个问题是Kubernetes是如何调用containerd的。这个问题放在性能测试场景下来回答会更有实际意义。K8s本身并不会直接操作容器它是通过**CRIContainer Runtime Interface**来调用容器运行时的。当前版本K8s默认用的运行时是containerd它们的调用链路是这样的Kubelet通过CRI的gRPC接口调用containerdcontainerd再通过containerd-shim进程启动和管理容器实例每个容器对应一个shim进程shim最终调用runc来真正创建和运行容器。这条链路对性能测试的影响有两个层面。第一Pod启动速度如果做了HPA扩容测试或滚动更新测试Pod启动的耗时包含了这个链路中的每一步——镜像拉取、容器创建、进程启动、就绪探测任何一个环节慢都会拖累扩容效率。我实测过对于一个小型Java应用从创建Pod到应用就绪通常需要15~45秒其中镜像拉取占了大头。所以在容量设计时HPA扩容的响应时间不能只算应用启动时间。第二如果运行时出现了异常比如containerd的日志量暴涨、shim进程异常退出直接会导致Pod重启或卡在ContainerCreating状态这类故障在压测过程中偶尔会发生测试时要留意监控告警否则数据又白测了。6.2 容器运行时层面的性能测试优化点再往下说一点运行时优化。既然底层是通过runc创建容器的那么容器本身的OCI配置就会影响性能。我踩过的坑是镜像里没有设置--oom-score-adj导致在内存压力下业务进程比shim进程更容易被OOM Killer杀死。另一个值得关注的是容器镜像大小。镜像越大Pod启动越慢这在性能测试里直接体现在扩容效率和故障恢复时间上。建议对镜像做瘦身能用distroless的别用带完整系统的镜像能合并层的就合并。不过要记住镜像层在多个Pod同时启动时如果没有开启P2P镜像分发Registry会成为瓶颈某次HPA扩容时镜像拉取直接把内部Registry打挂了那场景真的酸爽。6.3 性能测试中容器运行时的监控要点监控运行时层面几个命令和指标很有用# 查看容器运行时信息 kubectl get nodes -o wide # 进入容器查看cgroup信息 kubectl exec -it pod-name -c container-name -- cat /proc/1/cgroup # 查看containerd状态 systemctl status containerd核心指标方面我关注两个一个是etcd的磁盘延迟虽然它是控制面组件但和运行时协作者都是底层基础设施磁盘性能差会让所有操作都变慢另一个是容器进程的CPU调度延迟如果Node上跑的Pod太多CPU排队会导致应用性能下降即使单看CPU使用率并不高。这些都是传统性能测试完全不会涉及的维度。7. 常见问题和排查技巧实录7.1 问题速查表这部分我把实际项目中遇到过的问题整理成表方便大家对照排查。现象排查方向解决方案压测时TPS波动剧烈先看是否触发了HPA扩容压测前临时关闭HPA或固定副本数Pod频繁重启查看Exit Code137OOM调大内存limit排查内存泄漏CPU使用率不高但延迟高检查CPU Throttling调大CPU limit或调整CFS参数压测流量上不去检查施压端CPU和网络增加施压端副本或拆分为多个Deployment接口偶发超时检查CoreDNS和Service DNS解析排查DNS缓存策略检查CoreDNS副本数集群API响应变慢查etcd磁盘延迟和空间清理历史数据执行defrag迁移SSD扩容后性能反而下降检查新Pod所在节点的资源水位调整调度策略或增加节点资源压测影响同集群其他业务未做资源隔离用Namespace和ResourceQuota做隔离网络延迟忽高忽低检查CNI插件类型和模式切换网络模式或优化网络策略7.2 独家经验压测时关掉那些自动化的黑魔法这里要特别提醒一下K8s里很多自动化机制在常规运行中是保命符但在性能测试中就是捣蛋鬼。我自己踩过最痛的一次压测订单服务QPS接近预期峰值时HPA触发扩容新Pod启动后因为镜像拉取太慢迟迟不就绪老Pod被压得喘不过气结果响应时间急剧飙升测试直接失败。后续我总结了一套压测前的排除干扰清单HPA全部暂停固定副本数除非你专门做扩容性能测试。关闭Cluster Autoscaler避免压测时云厂商自动加节点导致计费和测试数据双重失控。如果有PodDisruptionBudget压测时不影响但如果有Node级维护任务比如云厂商自动升级内核提前安排好时间窗口。把日志采集的级别调到WARN或ERROR减少日志采集对CPU的占用。我记得有个项目压测时业务Pod的CPU有20%都被日志采集和fluentd转发吃掉了数据根本没法看。7.3 压测过程中Pod状态异常怎么办压测中间遇到Pod状态异常一定不要慌按照状态分类处理CrashLoopBackOff说明应用启动失败查看日志kubectl logs pod-name --previous。常见原因是配置错误、端口冲突、数据库连接不上先修应用再继续压测。PendingPod调度不上去kubectl describe pod看Event常见原因是资源不足、亲和性冲突、PV挂载失败。临时扩容节点或者调整资源配额。OOMKilled内存超限被杀死kubectl describe pod看Last State的Exit Code和kubectl logs看是否有OutOfMemory错误。调整内存limit但要区分是代码内存泄漏还是limit设置过小。ImagePullBackOff镜像拉取失败检查镜像仓库地址和认证信息。这个在压测扩容时最容易出现因为新Pod要拉镜像Registry突然被大量请求冲击。7.4 一个真实事故复盘etcd性能恶化引发的假性能瓶颈这个案例很有代表性。当时在压测一个消息推送服务QPS加到5000以后集群所有服务的响应时间集体飙到3秒以上。按常规思路查了业务代码、数据库、Redis全部正常。最后通过监控看到etcd的fsync延迟达到了300ms正常应该在2ms以内。在排查中发现etcd所在节点的磁盘是共享的云盘同一时间另一个项目组在做大量的数据导入磁盘IO被吃满。etcd的每次写入都要等fsync完成整个集群控制面的操作都变慢了业务Pod的健康检查超时被反复重启性能自然崩了。后来我们把etcd迁移到了独立的SSD云盘上问题彻底解决。这个案例里最重要的是结论在K8s里做性能测试控制面是不可忽略的组成部分。一个健康的集群是性能测试的前提压测前先确认集群控制面各项指标正常比什么工具选型都重要。8. 性能测试新范式的另外两个关键动作8.1 混沌工程和性能测试的融合K8s环境的动态性决定了只做理想状态下的性能测试是不够的。我在团队里推过一个实践性能测试和混沌工程结合在压测的同时注入故障比如随机杀掉Pod、给网络加延迟、让节点短暂不可用观察系统在性能压力和故障压力双重作用下的表现。具体执行时我推荐LitmusChaos这个工具它的Pod Chaos实验可以直接在K8s里注入不同类型的故障。一个典型的场景在QPS压到80%水位时杀一个Pod记录服务的错误率和恢复时间。这个故障注入性能压测的组合比单独做性能测试或单独做故障演练能发现更多真实问题。8.2 持续性能测试把压测集成进CI/CD性能测试不应该只在发版前做一次更应该在每次代码变更后做冒烟级的性能验证。我们团队的做法是在GitLab CI里加一个性能测试阶段用k6的Operator在测试集群里跑一个短暂的压测任务验证5分钟内的请求延迟和错误率是否在阈值内。这里给个建议持续性能测试的压测时间不用长5分钟足够并发量不用大日常正常流量的1.5倍就够了关键是建立一个基线库每次性能数据和历史基线做对比一旦延迟劣化超过20%流水线就会失败报警。这套机制跑下来很多性能回归在开发阶段就暴露了根本等不到大版本压测。配置方面k6 Operator的CRD大概是这样apiVersion: k6.io/v1alpha1 kind: K6 metadata: name: k6-smoke-test spec: parallelism: 4 script: configMap: name: k6-script runner: image: loadimpact/k6:latest arguments: --vus 50 --duration 5m多副本并行施压能撑到几千VU级别。关键操作是把测试脚本和压测配置都做成版本化的跟着代码库走而不是停留在测试同学的笔记本里。9. 最后的几点实操体会写了这么多最后再分享几点我个人的体会也是我在多个项目里反复验证过的结论。第一K8s性能测试的本质是测试平台与应用协同工作的性能而不是简单地在容器里跑传统性能测试。忽视平台因素你的测试数据再漂亮也代表不了生产环境的真实性能。第二监控体系一定要在压测前建设完毕。我从来没有见过一个监控不完善的团队能在K8s环境下顺利定位性能问题。宁可多花两天搭监控也不要为了赶进度跳过这一步。第三压测数据的可复现性和可对比性非常关键。你需要在报告里明确写出K8s版本、CNI插件及模式、运行时版本、节点规格、Pod资源Limit、副本数、HPA策略等。我见过太多团队压测数据保存了但环境信息不全过两个月再回头根本没法用。第四别迷信高并发这个说法。K8s里的性能问题往往不是并发量不够大而是系统在动态变化过程中的稳定性不足。与其追求极限QPS数字不如多做几轮稳定水位的测试找到系统能长期稳定运行的QPS区间这才是生产真正需要的数据。第五也是我想强调的一点多和其他角色协作沟通。性能测试工程师一定要拉上运维和开发一起看数据K8s的问题往往横跨多个层面只靠一个人的经验很难完整定位。我自己的经验是每次压测后拉个简短复盘会把Grafana截图、压测日志、K8s事件放在一起过一遍很多问题当场就能找到根因。如果这篇内容对你有帮助建议你直接在测试集群里动手搭一遍从环境搭建到压测执行再到监控分析跑通一轮之后你对K8s性能测试的理解会比看十篇文章都有用。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门