跨Kubernetes集群:如何用Prometheus采集JMeter指标?
问题根源
你配置的Prometheus采集目标localhost:9270指向Prometheus集群内部Pod的本地地址,完全无法访问另一个myapp集群中的JMeter Pod,这是目标始终显示Down的核心原因。需要解决跨集群网络可达性与JMeter指标暴露两个核心问题。
步骤1:在myapp集群中暴露JMeter指标端口
JMeter Pod由job-executor-service动态创建,需通过Kubernetes Service将其9270指标端口暴露出来:
1.1 确认JMeter Pod的标签
先获取运行中JMeter Pod的标签,用于Service的选择器匹配:
# 切换到myapp集群的kubeconfig上下文 kubectl config use-context k3d-myapp # 查看keptn命名空间下JMeter Pod的标签 kubectl describe pod <你的JMeter Pod名称> -n keptn | grep Labels
示例标签:app=jmeter-loadtest
1.2 创建Service暴露指标端口
创建jmeter-metrics-service.yaml文件:
apiVersion: v1 kind: Service metadata: name: jmeter-metrics namespace: keptn spec: selector: # 替换为你查到的JMeter Pod标签 app: jmeter-loadtest ports: - name: metrics port: 9270 targetPort: 9270 # 使用NodePort类型,方便映射到宿主机 type: NodePort
执行创建命令:
kubectl apply -f jmeter-metrics-service.yaml -n keptn
1.3 查看分配的NodePort端口
获取Service映射到集群节点的端口:
kubectl get svc jmeter-metrics -n keptn
输出示例:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE jmeter-metrics NodePort 10.43.123.45 <none> 9270:30927/TCP 2m
这里的30927就是可通过宿主机访问的端口。
1.4 (可选)固定端口并映射到宿主机
若需要固定端口,修改Service的ports字段添加nodePort:
ports: - name: metrics port: 9270 targetPort: 9270 nodePort: 30927
重新创建Service后,可在myapp集群创建命令中添加宿主机端口映射规则:
sudo k3d cluster create myapp -p "8080:80@loadbalancer" -p "9270:30927@server:*" --k3s-arg "--no-deploy=traefik@server:*"
此时直接通过宿主机IP:9270即可访问JMeter指标。
步骤2:修改Prometheus采集配置
2.1 切换到Prometheus集群的kubeconfig上下文
kubectl config use-context k3d-prometheus
2.2 编辑Helm values.yaml
找到Prometheus的scrape配置段,修改或添加JMeter采集任务:
prometheus: scrapeConfigs: - job_name: 'jmeter' static_configs: - targets: ['<宿主机实际IP>:30927'] # 替换为你的宿主机IP+步骤1.3得到的NodePort
若已完成步骤1.4的宿主机端口映射,可直接写'<宿主机实际IP>:9270'。
2.3 重新部署Prometheus
执行Helm升级命令使配置生效:
helm upgrade prometheus prometheus-community/prometheus -f values.yaml
步骤3:验证采集状态
- 访问Prometheus UI(
宿主机IP:9090),进入Status > Targets页面,查看jmeter任务状态是否为Up。 - 若仍显示Down,检查以下项:
- 宿主机防火墙是否开放了对应端口(如30927或9270)
- JMeter Pod是否处于Running状态(仅测试期间运行)
- Service的selector是否与JMeter Pod的标签完全匹配
- 进入Prometheus Pod执行
ping <宿主机IP>,验证网络可达性
进阶方案:跨集群服务发现(可选)
若需动态发现JMeter Pod(避免固定端口),可配置Prometheus通过Kubernetes API访问myapp集群:
- 导出
myapp集群的kubeconfig文件:k3d kubeconfig get myapp > myapp-kubeconfig.yaml - 在Prometheus集群中创建Secret存储该kubeconfig:
kubectl create secret generic myapp-kubeconfig --from-file=kubeconfig=myapp-kubeconfig.yaml -n prometheus - 修改Prometheus的scrape配置,添加Kubernetes服务发现:
prometheus: scrapeConfigs: - job_name: 'jmeter-k8s' kubernetes_sd_configs: - api_server: 'https://k3d-myapp-server-0:6443' # 从myapp的kubeconfig中获取API地址 kubeconfig_file: '/etc/prometheus/myapp-kubeconfig' role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_label_app] regex: jmeter-loadtest # 匹配JMeter Pod的标签 action: keep - source_labels: [__meta_kubernetes_pod_container_port_number] regex: 9270 action: keep extraVolumes: - name: myapp-kubeconfig secret: secretName: myapp-kubeconfig extraVolumeMounts: - name: myapp-kubeconfig mountPath: /etc/prometheus/myapp-kubeconfig readOnly: true
该方式会自动发现myapp集群中符合标签的JMeter Pod,无需手动维护目标地址。
内容的提问来源于stack exchange,提问作者J Jena

