根据我们的稳定性承诺,Prometheus 3.0 版本包含了一些不向后兼容的变更。本文档提供从 Prometheus 2.x 迁移到 Prometheus 3.0 及更新版本的指南。
标志
以下功能标志已被移除,它们已被添加到 Prometheus v3 的默认行为中:
promql-at-modifierpromql-negative-offsetnew-service-discovery-managerexpand-external-labels- 外部标签值中的环境变量引用
${var}或$var将根据当前环境变量的值进行替换。 - 未定义变量的引用将被替换为空字符串。
$字符可以使用$$进行转义。
- 外部标签值中的环境变量引用
no-default-scrape-port- Prometheus v3 将不再根据指定的协议向抓取目标添加端口。目标现在将按配置原样显示在标签中。
- 如果你依赖于如
https://example.com/metrics或http://example.com/metrics这样的抓取目标被分别表示为https://example.com/metrics:443和http://example.com/metrics:80,请将它们添加到你的目标 URL 中
agent- 请改用专用的
--agentCLI 标志。
- 请改用专用的
remote-write-receiver- 请改用专用的
--web.enable-remote-write-receiverCLI 标志来启用 remote write 接收器。
- 请改用专用的
auto-gomemlimit- Prometheus v3 将自动设置
GOMEMLIMIT以匹配 Linux 容器内存限制。如果没有容器限制,或进程在容器外运行,则使用系统总内存。要禁用此功能,可使用--no-auto-gomemlimit。
- Prometheus v3 将自动设置
auto-gomaxprocs- Prometheus v3 将自动设置
GOMAXPROCS以匹配 Linux 容器 CPU 配额。要禁用此功能,可使用--no-auto-gomaxprocs。
- Prometheus v3 将自动设置
如果你继续将这些传递给
--enable-feature,Prometheus v3 将记录一条警告日志。从 v3.9 开始,功能标志
native-histograms不再生效。原生直方图现在是稳定功能,但需要通过scrape_native_histograms全局或每个抓取配置选项来启用抓取(在 v3.8 中添加)。
配置
- 抓取作业级别的配置选项
scrape_classic_histograms已重命名为always_scrape_classic_histograms。如果你使用scrape_native_histograms抓取配置选项来采集原生直方图,并且还想采集端点可能同时暴露的经典直方图,请确保添加此配置或将旧名称更改为新名称。 remote_write中的http_config.enable_http2默认值已更改为false。在 Prometheus v2 中,remote write HTTP 客户端默认使用 http2。为了在多个套接字上并行化多个 remote write 队列,最好不默认使用 http2。如果你希望为 remote write 使用 http2,现在必须在你的remote_write配置部分中设置http_config.enable_http2: true。
PromQL
正则表达式匹配换行符
PromQL 中正则表达式的 . 模式现在匹配换行符。通过此变更,.* 等正则表达式可以匹配包含 \n 的字符串。这适用于查询和 relabel 配置中的匹配器。
例如,以下正则表达式现在可以匹配相应的字符串,而在 Prometheus v2 中这些组合不会匹配。
- .* 额外匹配 foo\n 和 Foo\nBar
- foo.?bar 额外匹配 foo\nbar
- foo.+bar 额外匹配 foo\nbar
如果你想让 Prometheus v3 的行为与 v2 相同,你需要更改正则表达式,将所有 . 模式替换为 [^\n],例如 foo[^\n]*。
范围选择器和回溯排除与左边界重合的样本
回溯和范围选择器现在是左开右闭的(之前是左闭右闭),这使它们的行为更加一致。此变更影响范围或回溯增量的左边界与一个或多个样本的时间戳重合的查询。
例如,假设我们正在查询一个具有精确间隔 1 分钟均匀分布样本的时间序列。在 Prometheus v3 之前,使用 5m 的范围查询通常会返回 5 个样本。但如果查询评估与抓取完美对齐,则会返回 6 个样本。在 Prometheus v3 中,这样的查询在均匀间隔下将始终返回 5 个样本。
此变更通常会影响子查询,因为它们的评估时间自然是完美均匀间隔的,并与步长大小的倍数时间戳对齐。此外,查询前端通常将子查询对齐到步长大小的倍数。综合来看,这很容易造成完美的相互对齐情况,通常是用户无意的和不知道的,因此新行为可能会令人意外。在 Prometheus V3 之前,这样的系统上 foo[1m:1m] 的子查询可能总是返回两个点,允许速率计算。然而在 Prometheus V3 中,这样的子查询将只返回一个点,这不足以进行 rate 或 increase 计算,导致返回 No Data。
这类查询需要重写以扩展窗口以正确覆盖多个点。在此示例中,foo[2m:1m] 将始终返回两个点,无论查询对齐如何。重写查询的确切形式可能取决于预期结果,并且对于行为已更改的查询没有通用的直接替代方案。
测试同样更可能受到影响。要修复这些问题,请调整预期的样本数量或扩展范围。
holt_winters 函数重命名
holt_winters 函数已重命名为 double_exponential_smoothing,现在受 promql-experimental-functions 功能标志保护。如果你想继续使用 holt_winters,你必须同时做以下两件事:
- 在查询中将
holt_winters重命名为double_exponential_smoothing。 - 在 Prometheus CLI 调用中传递
--enable-feature=promql-experimental-functions。
抓取协议
Prometheus v3 对抓取时接收的 Content-Type 头更加严格。Prometheus v2 如果被抓取的目标未指定 Content-Type 头或头无法解析或无法识别,将默认使用标准 Prometheus 文本协议。这可能导致抓取中解析到不正确的数据。Prometheus v3 现在将在这种情况下使抓取失败。
如果抓取目标未提供正确的 Content-Type 头,可以使用 fallback_scrape_protocol 参数指定回退协议。参见 Prometheus scrape_config 文档。
这是一个破坏性变更,因为在 Prometheus v2 中可能成功的抓取,如果未指定此回退协议,现在可能会失败。
其他
TSDB 格式和降级
TSDB 格式已在 Prometheus v2.55 中略有更改,为索引格式的变更做准备。因此,Prometheus v3 的 TSDB 只能由 Prometheus v2.55 或更新版本读取。升级到 v3 时请记住这一点 — 你只能降级到 v2.55,而不能更低版本,否则将丢失 TSDB 持久化数据。
作为额外的安全措施,你可以选择先升级到 v2.55 并确认 Prometheus 按预期工作,然后再升级到 v3。
TSDB 存储契约
兼容 TSDB 的存储现在应该返回与指定选择器匹配的结果。这可能会影响一些第三方实现,最有可能是实现 remote_read 的实现。
此契约并非强制执行,但可能导致未定义行为。
UTF-8 名称
Prometheus v3 支持指标和标签名称中的 UTF-8。这意味着升级后指标和标签名称可能会根据端点暴露的内容而发生变化。此外,之前会被标记为无效的指标和标签名称将不再被标记。
希望保留原始验证行为的用户可以更新 Prometheus yaml 配置以指定旧的验证方案:
global:
metric_name_validation_scheme: legacy
或按抓取基础设置:
scrape_configs:
- job_name: job1
metric_name_validation_scheme: utf8
- job_name: job2
metric_name_validation_scheme: legacy
日志消息格式
Prometheus v3 采用了 log/slog 替代之前的 go-kit/log。这导致日志消息格式发生变化。旧日志格式示例:
ts=2024-10-23T22:01:06.074Z caller=main.go:627 level=info msg="No time or size retention was set so using the default time retention" duration=15d
ts=2024-10-23T22:01:06.074Z caller=main.go:671 level=info msg="Starting Prometheus Server" mode=server version="(version=, branch=, revision=91d80252c3e528728b0f88d254dd720f6be07cb8-modified)"
ts=2024-10-23T22:01:06.074Z caller=main.go:676 level=info build_context="(go=go1.23.0, platform=linux/amd64, user=, date=, tags=unknown)"
ts=2024-10-23T22:01:06.074Z caller=main.go:677 level=info host_details="(Linux 5.15.0-124-generic #134-Ubuntu SMP Fri Sep 27 20:20:17 UTC 2024 x86_64 gigafips (none))"
新日志格式的类似序列如下:
time=2024-10-24T00:03:07.542+02:00 level=INFO source=/home/user/go/src/github.com/prometheus/prometheus/cmd/prometheus/main.go:640 msg="No time or size retention was set so using the default time retention" duration=15d
time=2024-10-24T00:03:07.542+02:00 level=INFO source=/home/user/go/src/github.com/prometheus/prometheus/cmd/prometheus/main.go:681 msg="Starting Prometheus Server" mode=server version="(version=, branch=, revision=7c7116fea8343795cae6da42960cacd0207a2af8)"
time=2024-10-24T00:03:07.542+02:00 level=INFO source=/home/user/go/src/github.com/prometheus/prometheus/cmd/prometheus/main.go:686 msg="operational information" build_context="(go=go1.23.0, platform=linux/amd64, user=, date=, tags=unknown)" host_details="(Linux 5.15.0-124-generic #134-Ubuntu SMP Fri Sep 27 20:20:17 UTC 2024 x86_64 gigafips (none))" fd_limits="(soft=1048576, hard=1048576)" vm_limits="(soft=unlimited, hard=unlimited)"
`le` 和 `quantile` 标签值
在 Prometheus v3 中,经典直方图的 le 标签值和 summary 的 quantile 标签值在采集时会被标准化。在 Prometheus v2 中,这些标签的值在某些情况下取决于抓取协议(protobuf vs 文本格式)。这导致标签值根据抓取协议而变化。例如,暴露为 my_classic_hist{le="1"} 的指标通过文本格式会被采集为 my_classic_hist{le="1"},但通过 protobuf 会变为 my_classic_hist{le="1.0"}。这改变了指标的标识并在查询指标时造成问题。在 Prometheus v3 中,这些标签值将始终被标准化为浮点数表示。即上面的示例将始终导致 my_classic_hist{le="1.0"} 被采集到 Prometheus 中,无论通过哪种协议。此变更的影响是,直接引用整数标签值(如 le="1")的告警、记录规则和仪表盘将停止工作。
处理此变更的方式(全局或按指标):
- 修复对整数
le、quantile标签值的引用,但不做其他操作,接受跨越过渡时间的一些查询会产生不准确或意外的结果。这是推荐的解决方案。 - 使用
metric_relabel_config在抓取目标时保留旧标签。这应仅应用于当前产生此类标签的指标。
metric_relabel_configs:
- source_labels:
- quantile
target_label: quantile
regex: (\d+)\.0+
- source_labels:
- le
- __name__
target_label: le
regex: (\d+)\.0+;.*_bucket
禁止使用 v1 API 配置 Alertmanager
Prometheus 3 不再支持 Alertmanager 的 v1 API。实际上 Prometheus 3 需要 Alertmanager 0.16.0 或更高版本。使用旧版 Alertmanager 或配置了 alerting: alertmanagers: [api_version: v1] 的用户需要升级 Alertmanager 并将配置更改为使用 api_version: v2。
Prometheus 2.0 迁移指南
关于从 Prometheus 1.8 到 2.0 的迁移指南,请参阅 Prometheus v2.55 文档。