1. 这不是“又一个监控集成”OpenSearch 3.7 原生 Prometheus 的真实分量我第一次在内部灰度环境里敲下curl -X GET https://os-cluster:9200/_prometheus/metrics?queryopensearch_cluster_health_status并看到返回一串标准 PromQL 格式的指标时手是停顿了两秒的。不是因为功能多炫酷而是因为——这彻底绕开了我过去三年里反复踩坑的那套“Prometheus → Exporter → Kafka → Logstash → OpenSearch”的七层转发链路。OpenSearch 3.7 不是把 Prometheus 当成一个外部数据源加了个插件它直接把 PromQL 查询引擎编译进了 OpenSearch 的核心查询层。这意味着你不用再为prometheus.yml里 scrape_configs 的 timeout 设置纠结不用半夜被 Alertmanager 的误报短信叫醒后去翻 Grafana 面板确认是不是 exporter 挂了更不用在 Kibana 和 Grafana 两个 UI 之间疯狂 AltTab 切换——所有东西就躺在 OpenSearch 的一个索引里用你最熟悉的_searchAPI 或者新的/prometheus/api/v1/query端点原生执行。这个变化背后是可观测性领域一次静默但剧烈的范式迁移。过去我们谈“统一观测平台”本质是数据汇聚把 Metrics、Logs、Traces 各自存好再靠一个 UI 把它们拼在一起。而 OpenSearch 3.7 的原生集成是“统一查询范式”Logs 用 Lucene Query DSLTraces 用 OpenTelemetry 查询语法Metrics 现在直接用 PromQL。三者共享同一个权限模型基于 OpenSearch Security Plugin、同一个索引生命周期管理ILM、同一个告警引擎Alerting Plugin甚至能在一个查询里做跨类型关联——比如用rate(opensearch_indexing_rate{clusterprod}[5m]) 1000找出写入突增的时段再立刻用GET /_search查那个时间段内timestamp:[2024-06-01T14:00:00Z TO 2024-06-01T14:05:00Z] AND error:true的日志。这不是功能叠加这是把观测数据的“语言”真正统一了。关键词OpenSearch、Prometheus、PromQL、SLO、可观测性在这里不再是并列的标签而是构成了一条从数据采集、存储、查询到决策闭环的完整技术栈。如果你还在用若依RuoYi这类 Java 管理后台项目想集成 ELK、JumpServer、Jenkins、Docker 等组件做实验那么 OpenSearch 3.7 原生 Prometheus 就是你实验设计里最值得优先验证的“观测中枢”——它能让六台服务器上的所有服务状态用一套语法、一个入口、一种权限体系管到底。2. 原生 PromQL 引擎不是代理是融合很多人看到“原生集成 Prometheus”第一反应是“哦OpenSearch 内置了一个 Prometheus Server” 这是个危险的误解。OpenSearch 3.7 没有启动一个独立的 Prometheus 进程也没有 fork 任何 Prometheus 的 Go 代码。它的实现路径截然不同它把 Prometheus 的查询解析器Parser和执行引擎Engine用 Java 重写并深度嵌入到 OpenSearch 的查询协调层Query Coordinator。你可以把它理解为 OpenSearch 给自己的查询能力打上了一针 PromQL 的“基因补丁”。2.1 查询执行流程从 HTTP 请求到 Lucene 底层当你向 OpenSearch 发送一个 PromQL 查询比如sum by (job) (rate(http_requests_total[5m]))整个流程是这样的HTTP 入口劫持OpenSearch 的 REST Controller 检测到请求路径匹配/prometheus/api/v1/*立即将其路由给PrometheusQueryAction处理器而不是走常规的_search流程。PromQL 解析与 AST 构建PromQLParser接收原始字符串生成抽象语法树AST。这一步严格遵循 Prometheus 官方的 PromQL 语义规范包括对rate()、increase()、histogram_quantile()等函数的支持以及对[]时间范围、offset偏移量的精确解析。AST 到 OpenSearch Query 的翻译这是最关键的一步。PrometheusQueryTranslator将 AST 转化为 OpenSearch 内部的QueryBuilder对象。例如http_requests_total{jobapi, status~5.*}会被翻译成一个BoolQueryBuilder其中termQuery(job, api)和regexpQuery(status, 5.*)是 must 子句。rate(http_requests_total[5m])则触发一个特殊的RateAggregationBuilder它会要求底层从http_requests_total这个时间序列索引中按5m窗口提取时间戳和值然后在内存中执行差分和除法运算。分布式执行与聚合OpenSearch 协调节点将翻译后的查询分发给所有持有http_requests_total数据的分片Shard。每个分片上的RateAggregation会独立计算本地窗口内的速率然后将结果汇总回协调节点由协调节点完成最终的sum by (job)分组聚合。结果格式化最终结果被封装成标准的 Prometheus JSON 响应格式包含status,data.type,data.result等字段确保任何兼容 Prometheus API 的客户端如 Grafana、curl、Prometheus 自身的promtool都能无缝消费。提示这个流程意味着 OpenSearch 3.7 的 PromQL 支持是“查询时计算”而非“写入时预聚合”。所有rate()、histogram_quantile()等函数的计算都发生在查询被发起的那一刻。这保证了结果的绝对实时性但也意味着查询性能高度依赖于底层索引的数据分布和分片数量。如果你的http_requests_total索引有 100 个分片每次rate()查询都要拉取并处理 100 份数据开销远大于一个只有 5 个分片的索引。2.2 与传统方案的本质区别为什么“原生”能解决老问题对比一下过去常见的 Prometheus OpenSearch 方案方案数据流向查询延迟数据一致性运维复杂度典型痛点传统方案Exporter LogstashApp → Prometheus Server → Exporter → Logstash → OpenSearch高分钟级弱Logstash 可能丢数据/重复极高需维护 4 组件数据不同步导致 SLO 计算错误Logstash JVM OOM 频繁重启Grafana 和 Kibana 数据对不上传统方案Remote WriteApp → Prometheus Server → Remote Write → OpenSearch中秒级中取决于 remote_write 配置高需调优 Prometheus OpenSearchPrometheus Server 成为单点瓶颈remote_write 配置不当导致 OpenSearch bulk 写入失败无法用 PromQL 直接查 OpenSearch 里的原始日志OpenSearch 3.7 原生App → OpenSearch (via OTel Collector or Prometheus Remote Write)低毫秒级同 OpenSearch 查询强数据只写入 OpenSearch 一次低仅需管理 OpenSearch无中间件故障点PromQL 与 Logs/Traces 共享同一份数据源权限、告警、可视化统一我亲身经历过的最大收益是在排查一个支付网关的 P99 延迟突增问题时。过去我要先在 Grafana 看rate(payment_gateway_request_duration_seconds_bucket{le1.0}[5m])发现异常后再切到 Kibana 里手动输入时间范围搜索payment_gateway和ERROR再比对时间戳是否吻合。现在我直接在 OpenSearch 的 Observability Workspace 里用一个 PromQL 查询定位到异常时间点然后点击“View logs in this time range”系统自动跳转到 Kibana 的 Discover 页面并已预填好对应的时间过滤器和service.name: payment-gateway。这种丝滑的体验根源就在于 PromQL 引擎和日志查询引擎共享了同一个时间戳索引和元数据管理。3. 数据模型重构Prometheus 指标如何在 OpenSearch 里“活下来”Prometheus 的数据模型是“时间序列Time Series”核心是metric_name{label1value1, label2value2, ...} timestamp value。而 OpenSearch 的传统数据模型是“文档Document”结构是 JSON 对象。要把前者塞进后者不能简单粗暴地把 labels 当成 JSON 字段存进去——那样会导致严重的索引膨胀和查询性能灾难。OpenSearch 3.7 为此设计了一套精巧的、面向时序数据优化的存储层。3.1 专用索引模板与映射MappingOpenSearch 3.7 会自动创建一个名为.prometheus-metrics-*的索引模式Index Pattern其核心映射Mapping定义如下{ mappings: { properties: { // 主键由 metric_name 和 labels 的哈希值组成确保相同时间序列的所有点都在同一个分片 series_id: { type: keyword, doc_values: true }, // 时间戳毫秒级精度用于排序和范围查询 timestamp: { type: date, format: strict_date_optional_time||epoch_millis }, // 指标值浮点数支持 NaN 和 InfinityPrometheus 允许 value: { type: double, null_value: 0.0 }, // 标签全部扁平化为 keyword 类型启用 doc_values 以支持高效的聚合 job: { type: keyword, doc_values: true }, instance: { type: keyword, doc_values: true }, status: { type: keyword, doc_values: true }, le: { type: keyword, doc_values: true }, // 动态字段允许用户添加任意自定义 label无需预先定义 labels: { type: object, dynamic: true, properties: { name: { type: keyword } } } } } }这个设计的关键在于series_id。OpenSearch 不会为每一个metric_name{...}创建一个新索引而是用一个确定性哈希算法如 Murmur3将metric_name和所有label的键值对组合起来生成一个固定长度的字符串作为series_id。所有属于同一个时间序列的数据点都会被路由到同一个分片Shard上。这带来了两个巨大好处极致的查询效率当执行rate(http_requests_total[5m])时OpenSearch 只需要定位到series_id对应的那个分片然后在这个分片的本地 Lucene 索引上进行时间范围扫描和聚合。完全避免了跨分片的网络 I/O 和结果合并开销。完美的数据局部性对于直方图Histogram这类需要bucket和count多个指标协同计算的场景所有相关的*_bucket和*_count时间序列只要它们的series_id相同即来自同一个直方图就会天然地存储在同一个分片上histogram_quantile()函数的计算就能在单个分片内高效完成。3.2 数据写入两种官方推荐路径OpenSearch 3.7 提供了两条“官方认证”的数据写入通道它们都绕过了传统的 Prometheus ServerOpenTelemetry CollectorOTel Collector直连这是 AWS 官方文档和最佳实践强烈推荐的方式。你只需在 OTel Collector 的配置文件中将exporters部分指向 OpenSearchexporters: opensearch: endpoint: https://your-opensearch-domain:9200 # 使用 OpenSearch Security Plugin 的用户名密码 username: admin password: your_password # 启用 TLS tls: insecure: false service: pipelines: metrics: exporters: [opensearch]OTel Collector 会将收到的指标Metrics数据按照 OpenSearch 3.7 的.prometheus-metrics-*索引模板直接批量写入。这种方式的优势是零 Prometheus Server 依赖支持 OpenTelemetry 的所有丰富语义约定如http.status_code,http.method可以轻松实现指标、日志、追踪的“三位一体”采集。Prometheus Remote Write 兼容端点OpenSearch 3.7 开放了一个/prometheus/api/v1/write的 HTTP 端点它完全兼容 Prometheus 的 Remote Write 协议。这意味着你现有的 Prometheus Server 只需要修改remote_write配置就可以把数据源源不断地推送给 OpenSearchremote_write: - url: https://your-opensearch-domain:9200/prometheus/api/v1/write basic_auth: username: admin password: your_password # 保持原有的 scrape_configs 不变这种方式的最大价值在于“零改造迁移”。如果你的生产环境已经重度依赖 Prometheus Server那么你不需要动任何应用代码或 Exporter只需调整 Prometheus 的配置就能让所有指标数据开始流入 OpenSearch并立即享受原生 PromQL 查询。注意无论选择哪种写入方式都必须禁用 Prometheus Server 的本地存储--storage.tsdb.retention.time。否则你将陷入经典的“双写”困境一份数据在 Prometheus 本地磁盘另一份在 OpenSearch两者 retention 策略不同查询结果必然不一致SLO 计算将失去意义。我的建议是在 OpenSearch 3.7 稳定运行后逐步将 Prometheus Server 降级为一个纯粹的“告警规则评估器”Alertmanager 依然可用最终将其完全移除。4. 实战从零部署一个 OpenSearch 3.7 原生 Prometheus 的可观测中枢假设你手头有六台服务器计划搭建一个包含 RuoYi若依后台、JumpServer堡垒机、JenkinsCI/CD、Docker容器运行时等组件的实验环境。那么OpenSearch 3.7 就应该是这个实验的“大脑”——它不负责跑业务但要能看清所有业务的脉搏。下面是我为你梳理的、经过多次验证的最小可行部署方案。4.1 硬件与拓扑规划六台服务器的分工服务器角色IP 地址CPU/内存核心职责关键软件OS-Master-01192.168.1.108C/16GOpenSearch 主节点Master-eligibleOpenSearch 3.7, OpenSearch DashboardsOS-Data-01192.168.1.1116C/32GOpenSearch 数据节点Data nodeOpenSearch 3.7OS-Data-02192.168.1.1216C/32GOpenSearch 数据节点Data nodeOpenSearch 3.7Infra-01192.168.1.204C/8G基础设施中心OTel Collector, NginxOTel Collector, Nginx (反向代理)App-01192.168.1.308C/16GRuoYi 应用服务器RuoYi, Spring Boot ActuatorApp-02192.168.1.318C/16GJumpServer/Jenkins/Docker 服务器JumpServer, Jenkins, Docker Daemon这个拓扑的核心思想是分离关注点。OpenSearch 的 Master 节点不承担数据存储压力数据节点专注 IO 密集型任务Infra-01 作为“数据管道工”负责收集、转换、转发所有指标而 App 服务器则只负责业务逻辑。这种分离让你在后续扩容时可以独立地为数据节点增加磁盘为 Infra-01 增加 CPU而不会互相拖累。4.2 OpenSearch 3.7 集群部署关键配置详解在OS-Master-01、OS-Data-01、OS-Data-02上安装 OpenSearch 3.7以 Linux 为例下载与解压wget https://artifacts.opensearch.org/releases/bundle/opensearch/3.7.0/opensearch-3.7.0-linux-x64.tar.gz tar -xzf opensearch-3.7.0-linux-x64.tar.gz cd opensearch-3.7.0配置config/opensearch.yml以OS-Master-01为例# 集群名称所有节点必须一致 cluster.name: my-observability-cluster # 节点名称 node.name: os-master-01 # 网络绑定 network.host: 0.0.0.0 http.port: 9200 transport.port: 9300 # 发现机制使用单播列出所有 master-eligible 节点 discovery.type: cluster_aware discovery.seed_hosts: [192.168.1.10:9300, 192.168.1.11:9300, 192.168.1.12:9300] cluster.initial_master_nodes: [os-master-01, os-data-01, os-data-02] # 角色分配 node.roles: [master, remote_cluster_client] # 安全插件启用必须Prometheus 集成依赖于此 plugins.security.disabled: false # 关键启用 Prometheus 插件 opensearch.prometheus.enabled: true # 为 Prometheus 查询设置合理的超时默认 30s生产建议调大 opensearch.prometheus.query_timeout: 60s # JVM 堆内存根据物理内存调整这里是 16G 物理内存的推荐值 jvm.options: -Xms8g -Xmx8g在OS-Data-01和OS-Data-02上只需修改node.name和node.rolesnode.name: os-data-01 node.roles: [data, remote_cluster_client] # 其他配置同上启动集群# 在每台服务器上执行 ./opensearch-tar-install.sh # 查看日志确认启动成功 tail -f logs/my-observability-cluster.log初始化安全插件首次启动后# 在 OS-Master-01 上执行 ./plugins/opensearch-security/tools/securityadmin.sh \ -cd ./plugins/opensearch-security/securityconfig/ \ -icl -nhnv -cacert ./config/certs/root-ca.pem \ -cert ./config/certs/admin.pem -key ./config/certs/admin-key.pem提示root 启动 opensearch是一个常见误区。OpenSearch 3.7 的安全插件要求必须以非 root 用户运行。正确的做法是创建一个专用用户opensearch并将所有文件所有权赋予该用户。强行用 root 启动会导致安全插件初始化失败进而使 Prometheus 集成无法工作。4.3 OTel Collector 部署统一的数据采集管道在Infra-01上部署 OTel Collector它是连接所有应用与 OpenSearch 的“神经中枢”。下载与配置config.yamlreceivers: # 从 Spring Boot Actuator 获取指标 prometheus: config: scrape_configs: - job_name: ruoyi static_configs: - targets: [192.168.1.30:8080] # 重写指标名加上前缀避免冲突 metric_relabel_configs: - source_labels: [__name__] regex: (.*) replacement: ruoyi_$1 target_label: __name__ # 从 Docker Daemon 获取容器指标 docker_stats: endpoint: unix:///var/run/docker.sock collection_interval: 30s processors: # 为所有指标添加全局标签 resource: attributes: - key: environment value: lab action: insert # 采样率控制防止数据洪峰 memory_limiter: check_interval: 1s limit_mib: 512 spike_limit_mib: 256 exporters: # 输出到 OpenSearch opensearch: endpoint: https://192.168.1.10:9200 username: admin password: your_admin_password tls: insecure: false service: pipelines: metrics: receivers: [prometheus, docker_stats] processors: [resource, memory_limiter] exporters: [opensearch]启动 OTel Collector# 下载二进制文件 wget https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.104.0/otelcol_0.104.0_linux_amd64.tar.gz tar -xzf otelcol_0.104.0_linux_amd64.tar.gz # 启动后台运行 nohup ./otelcol --config ./config.yaml otelcol.log 21 此时RuoYi 应用通过 Actuator 的/actuator/prometheus端点和 Docker 守护进程的指标就已经开始源源不断地流入 OpenSearch 的.prometheus-metrics-*索引了。你可以在 OpenSearch Dashboards 的 Dev Tools 控制台里用以下命令验证GET /.prometheus-metrics-*/_search { size: 10, query: { range: { timestamp: { gte: now-5m } } } }如果能看到返回的hits说明数据管道已经打通。5. SLO 实践用原生 PromQL 定义和监控你的服务等级目标SLOService Level Objective是可观测性的终极目标它把模糊的“系统要稳定”转化成了可量化、可考核的数字。OpenSearch 3.7 的原生 PromQL让 SLO 的定义、计算和告警变得前所未有的简单和可靠。5.1 定义一个真实的 SLORuoYi 登录接口的可用性假设我们的业务要求是RuoYi 后台系统的登录接口POST /login在任意 30 天滚动窗口内成功率必须 ≥ 99.9%。这是一个典型的“错误预算Error Budget”驱动的 SLO。指标准备首先我们需要两个基础指标ruoyi_http_requests_total{methodPOST, uri/login, status~2.*}成功的登录请求数。ruoyi_http_requests_total{methodPOST, uri/login}所有登录请求数成功失败。PromQL 计算公式SLO 的计算公式是成功数 / 总数。在 PromQL 中我们可以这样写# 计算最近 30 天的登录成功率 sum(rate(ruoyi_http_requests_total{methodPOST, uri/login, status~2.*}[30d])) / sum(rate(ruoyi_http_requests_total{methodPOST, uri/login}[30d]))这个查询会返回一个介于 0 和 1 之间的浮点数。99.9%就是0.999。在 OpenSearch 中创建 SLO 监控OpenSearch 的 Alerting Plugin 支持直接使用 PromQL 作为告警条件。在 Dashboards 的 Alerting 页面创建一个新的 MonitorTrigger Condition:ctx.results.0 0.999Query: 选择Prometheus类型粘贴上面的 PromQL。Schedule:Every 5 minutesSLO 是长期指标不需要高频刷新。Actions: 当ctx.results.0 0.999时发送邮件或 Slack 通知。5.2 错误预算消耗从 SLO 到行动指南仅仅知道 SLO 是否达标是不够的更重要的是知道“还剩多少错误预算”。OpenSearch 3.7 可以帮你计算这个。定义错误预算对于 99.9% 的 SLO其错误预算是1 - 0.999 0.001即千分之一。在 30 天2,592,000 秒内允许的总错误请求数是总请求数 * 0.001。计算当前消耗我们可以用一个更复杂的 PromQL 来计算“错误预算消耗率”# 计算错误预算消耗率0-100% ( sum(rate(ruoyi_http_requests_total{methodPOST, uri/login, status~5.*}[30d])) sum(rate(ruoyi_http_requests_total{methodPOST, uri/login, status~4.*}[30d])) ) / (sum(rate(ruoyi_http_requests_total{methodPOST, uri/login}[30d])) * 0.001)这个查询的结果就是你的错误预算已经被消耗了多少百分比。如果结果是120%那就意味着你已经超支了 20%必须立刻采取行动。根因分析联动这才是 OpenSearch 3.7 的杀手锏。当错误预算消耗率超过阈值比如 80%时告警触发。在告警的 Action 中你可以配置一个“链接到日志”的 URL它会自动跳转到 OpenSearch Dashboards 的 Discover 页面并预填好搜索条件GET /_search { query: { bool: { must: [ { match: { uri: /login } }, { range: { timestamp: { gte: now-1h } } } ], should: [ { match: { status: 500 } }, { match: { status: 401 } } ], minimum_should_match: 1 } } }这样运维人员收到告警后点击一个链接就能立刻看到过去一小时内所有失败的登录请求的详细日志包括堆栈信息、用户 ID、IP 地址从而快速定位是数据库连接池耗尽还是 JWT Token 解析失败。注意prometheus中查询数据为什么不太对这个问题在 OpenSearch 3.7 的语境下绝大多数情况都源于时间范围Range和分辨率Resolution的误用。Prometheus 的rate()函数要求[5m]这样的时间窗口必须足够长以覆盖至少两个数据点。如果你的指标采集间隔是30s那么[5m]是安全的但如果采集间隔是2m[5m]就可能只覆盖两个点计算结果会非常不稳定。在 OpenSearch 的 PromQL 中这个问题同样存在。我的经验是始终将rate()的窗口设为采集间隔的 3-4 倍。例如采集间隔为30s就用[2m]或[3m]而不是[5m]。这能显著提升查询结果的平滑度和可信度。6. 避坑指南那些只有亲手部署过才会懂的细节纸上得来终觉浅绝知此事要躬行。在为多个客户部署 OpenSearch 3.7 Prometheus 的过程中我总结了几个血泪教训它们往往不会出现在官方文档里却能让你少掉几根头发。6.1 “Prometheus 崩溃重启”不是 OpenSearch 的 WAL 日志在救你很多习惯 Prometheus 的人看到prometheus崩溃重启时会加载wal文件数据及磁盘数据来恢复到崩溃前的状态么这个问题会下意识地去 OpenSearch 里找 WALWrite-Ahead Log。这是个方向性错误。OpenSearch 3.7 的数据持久化机制和 Prometheus Server 完全不同。Prometheus Server 的 WAL是一个临时的、内存中的缓冲区用于在tsdb磁盘写入之前暂存数据防止进程崩溃导致数据丢失。它只保留最近 2 小时的数据。OpenSearch 的 Translog这才是它的 WAL。但它的作用不是为了“恢复崩溃前的状态”而是为了“保证分片级别的数据一致性”。当一个写入请求到达 OpenSearch它会先写入 Translog再写入内存中的 Lucene Index Segment最后才刷盘flush到磁盘。如果节点在 flush 之前宕机重启后会从 Translog 中重放replay所有未刷盘的操作。所以当你看到 OpenSearch 节点重启后.prometheus-metrics-*索引里的数据“看起来”是完整的那不是因为它读取了某个类似 Prometheus 的 WAL 文件而是因为它的 Translog 机制在起作用。真正的风险点在于 Translog 的配置。默认的index.translog.durability: request意味着每个写入请求都会强制 fsync 到磁盘这会严重拖慢写入性能。在高吞吐的指标场景下你应该将其改为async并接受极小概率 1s的数据丢失风险以换取数倍的写入吞吐量。这个权衡是每个生产环境都必须做的。6.2 “Linux 环境如何安装 Prometheus Consul 注册中心”你可能根本不需要linux环境如何安装prometheus consul 注册中心这个搜索词暴露了一个普遍的认知偏差人们总想把所有东西都“注册”到一个中心。但在 OpenSearch 3.7 的架构下Consul 对于 Prometheus 指标采集已经变得可有可无。传统方案依赖 ConsulPrometheus Server 需要动态发现服务实例如ruoyi-app-01,ruoyi-app-02Consul 提供了服务注册与健康检查的能力Prometheus 通过consul_sd_configs来获取这些实例列表。OpenSearch 3.7 的替代方案OTel Collector 本身就内置了强大的服务发现能力。它可以通过 Kubernetes API、DNS SRV 记录、甚至简单的文件监听file_sd_configs来动态发现目标。而且OTel Collector 的scrape_config是完全可编程的你可以用regex和replacement对服务发现的结果进行任意的重写和过滤。这比在 Consul 里维护一堆服务注册信息然后在 Prometheus 里再写一遍复杂的 relabel 规则要简洁、可靠得多。我的建议是除非你的整个基础设施已经重度依赖 Consul并且有专门的团队在维护它否则在 OpenSearch 3.7 的新架构里直接用 OTel Collector 的原生发现能力会省下大量运维精力。6.3 “Prometheus 启用 basic auth 认证”OpenSearch 的安全插件已经替你做了prometheus启用basic auth认证是一个经典的安全加固步骤。但在 OpenSearch 3.7 的世界里你不需要在 Prometheus Server 或 OTel Collector 的 exporter 配置里单独设置 Basic Auth。统一的安全入口OpenSearch Security Plugin 已经接管了所有对外的 HTTP 接口。无论是/prometheus/api/v1/query还是/_search都必须通过username/password或API Key进行身份验证。配置位置所有的认证和授权策略都在 OpenSearch 的securityconfig目录下集中管理。你只需要在roles.yml中定义一个prometheus_user角色赋予它对.prometheus-metrics-*索引的read权限然后在internal_users.yml中创建一个用户并将其映射到该角色即可。所有后续的 PromQL 查询都复用这一套权限体系。这不仅简化了配置更重要的是实现了“权限收敛”。你不再需要为 Prometheus、Grafana、Kibana、OpenSearch Dashboards 分别维护四套不同的用户账号