Prometheus 3.0 마이그레이션 가이드
Prometheus 3.0 마이그레이션 가이드 (Prometheus 3.0 migration guide)
우리의 안정성 약속에 부합하게, Prometheus 3.0 릴리스에는 여러 하위 호환되지 않는 변경이 포함돼요. 이 문서는 Prometheus 2.x에서 Prometheus 3.0 및 이후 버전으로 마이그레이션하는 데 대한 지침을 제공해요. 업그레이드 전에 반드시 확인해야 할 사항을 정리했어요.
주요 변경은 플래그 제거, 구성 변경(특히 보존 설정이 구성 파일로 이동), PromQL 정규식과 범위 셀렉터 동작 변화, TSDB 형식 변경 등이에요. 하나씩 차근차근 확인해 보세요.
출처: 문서
본문
우리의 안정성 약속에 부합하게, Prometheus 3.0 릴리스에는 여러 하위 호환되지 않는 변경이 포함돼요. 이 문서는 Prometheus 2.x에서 Prometheus 3.0 및 이후 버전으로 마이그레이션하는 데 대한 지침을 제공해요.
플래그 (Flags)
다음 기능 플래그들이 제거되었고 Prometheus v3의 기본 동작에 추가되었어요:
-
promql-at-modifier -
promql-negative-offset -
new-service-discovery-manager -
expand-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 receiver를 활성화하세요. -
auto-gomemlimit -
Prometheus v3는
GOMEMLIMIT을 Linux 컨테이너 메모리 한도에 맞춰 자동으로 설정해요. 컨테이너 한도가 없거나 프로세스가 컨테이너 밖에서 실행되면 시스템 메모리 총량이 사용돼요. 비활성화하려면--no-auto-gomemlimit을 사용할 수 있어요. -
auto-gomaxprocs -
Prometheus v3는
GOMAXPROCS를 Linux 컨테이너 CPU 쿼터에 맞춰 자동으로 설정해요. 비활성화하려면--no-auto-gomaxprocs를 사용할 수 있어요.
이것들을 계속 --enable-feature로 전달하면 Prometheus v3는 경고를 로그로 남겨요.
v3.9부터 기능 플래그 native-histograms는 no-op이에요. 네이티브 히스토그램은 이제 안정적인 기능이지만, 스크랩하려면 scrape_native_histograms 전역 또는 스크랩별 구성 옵션(v3.8에서 추가)으로 활성화해야 해요.
구성 (Configuration)
-
스크랩 잡 수준 구성 옵션
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
정규식이 줄바꿈과 일치 (Regular expressions match newlines)
PromQL 정규식의 . 패턴이 줄바꿈 문자와 일치해요. 이 변경으로 .* 같은 정규식은 \n을 포함하는 문자열과 일치해요. 이것은 쿼리의 매처와 relabel 구성에 적용돼요.
예를 들어 다음 정규식은 이제 해당 문자열과 일치하지만, Prometheus v2에서는 이 조합이 일치하지 않았어요.
.*는 추가로foo\n과Foo\nBar와 일치foo.?bar는 추가로foo\nbar와 일치foo.+bar는 추가로foo\nbar와 일치
Prometheus v3를 v2처럼 동작하게 하려면, 모든 . 패턴을 [^\n]로 바꿔 정규식을 변경해야 해요. 예: foo[^\n]*.
범위 셀렉터와 lookback이 왼쪽 경계와 일치하는 샘플을 제외 (Range selectors and lookback exclude samples coinciding with the left boundary)
Lookback와 범위 셀렉터는 이제 왼쪽-열림(left-open)과 오른쪽-닫힘(right-closed)이 돼요(이전에는 왼쪽-닫힘과 오른쪽-닫힘). 이것은 그들의 동작을 더 일관되게 만들어요. 이 변경은 범위의 왼쪽 경계나 lookback 델타가 하나 이상의 샘플의 타임스탬프와 일치하는 쿼리에 영향을 줘요.
예를 들어 정확히 1분 간격으로 균등하게 배치된 샘플이 있는 타임시리즈를 쿼리한다고 가정해 봐요. Prometheus v3 이전에는 5m을 가진 범위 쿼리가 보통 5개의 샘플을 반환했어요. 하지만 쿼리 평가가 스크랩과 완벽히 정렬되면 6개의 샘플을 반환했어요. Prometheus v3에서는 이런 쿼리가 균등한 간격이 주어지면 항상 5개의 샘플을 반환할 거예요.
이 변경은 보통 서브쿼리에 영향을 줘요. 서브쿼리의 평가 타이밍이 자연스럽게 완벽히 균등하고 서브쿼리 해상도의 배수인 타임스탬프와 정렬되기 때문이에요. 게다가 쿼리 프론트엔드는 종종 서브쿼리를 스텝 크기의 배수로 정렬해요. 결합하면 완벽한 상호 정렬 상황을 쉽게 만들어 내는데, 종종 사용자가 의도하지 않고 알지 못한 채로, 새 동작이 놀라움으로 다가올 수 있어요. Prometheus V3 이전에는 그런 시스템의 foo[1m:1m] 서브쿼리가 항상 두 개의 포인트를 반환해 rate 계산을 허용했을 수 있어요. 하지만 Prometheus V3에서는 그런 서브쿼리가 하나의 포인트만 반환할 거고, 이는 rate나 increase 계산에 불충분해서 No Data를 반환하게 돼요.
그런 쿼리는 창을 확장해 둘 이상의 포인트를 제대로 덮도록 다시 작성해야 해요. 이 예에서 foo[2m:1m]은 쿼리 정렬과 무관하게 항상 두 개의 포인트를 반환할 거예요. 다시 작성된 쿼리의 정확한 형태는 의도한 결과에 따라 달라질 수 있으며, 동작이 바뀐 쿼리에 대한 보편적인 드롭인 대체품은 없어요.
테스트도 비슷하게 더 많이 영향받을 가능성이 있어요. 그것들을 고치려면 기대 샘플 수를 조정하거나 범위를 확장하세요.
holt_winters 함수 이름 변경 (holt_winters function renamed)
holt_winters 함수는 double_exponential_smoothing으로 이름이 바뀌었고 이제 promql-experimental-functions 기능 플래그로 보호돼요.
holt_winters를 계속 사용하려면 두 가지를 모두 해야 해요.
-
쿼리에서
holt_winters를double_exponential_smoothing으로 이름을 바꾸세요. -
Prometheus CLI 호출에
--enable-feature=promql-experimental-functions를 전달하세요.
스크랩 프로토콜 (Scrape protocols)
Prometheus v3는 스크랩할 때 받는 Content-Type 헤더에 대해 더 엄격해요. Prometheus v2는 스크랩되는 타깃이 Content-Type 헤더를 지정하지 않거나 헤더가 파싱 불가능하거나 인식할 수 없는 경우 표준 Prometheus 텍스트 프로토콜을 기본값으로 사용했어요. 이것은 스크랩에서 잘못된 데이터가 파싱될 수 있었어요. Prometheus v3는 그런 경우 스크랩을 실패시킬 거예요.
스크랩 타깃이 올바른 Content-Type 헤더를 제공하지 않으면 fallback_scrape_protocol 파라미터로 폴백 프로토콜을 지정할 수 있어요. Prometheus scrape_config 문서를 보세요.
이것은 Prometheus v2로 성공했을 수 있는 스크랩이 이 폴백 프로토콜을 지정하지 않으면 이제 실패할 수 있으므로 호환성 깨짐(breaking change)이에요. 스크랩 엔드포인트가 지원되는 Content-type 헤더 중 하나로 응답하는지 확인하세요.
-
application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=delimited -
text/plain;version=0.0.4 -
text/plain;version=1.0.0 -
application/openmetrics-text;version=0.0.1 -
application/openmetrics-text;version=1.0.0
기타 (Miscellaneous)
TSDB 형식과 다운그레이드 (TSDB format and downgrade)
TSDB 형식은 인덱스 형식의 변경을 준비하면서 Prometheus v2.55에서 약간 바뀌었어요. 결과적으로 Prometheus v3 TSDB는 Prometheus v2.55 이상만 읽을 수 있어요. v3로 업그레이드할 때 이것을 명심하세요 — TSDB 영속 데이터를 잃지 않고 v2.55보다 낮은 버전으로만 다운그레이드할 수 있어요.
추가 안전 조치로, v3로 업그레이드하기 전에 먼저 v2.55로 업그레이드하고 Prometheus가 예상대로 작동하는지 확인하는 것을 선택적으로 고려할 수 있어요.
TSDB 저장소 계약 (TSDB storage contract)
TSDB 호환 저장소는 이제 지정된 셀렉터와 일치하는 결과를 반환할 것으로 기대돼요. 이것은 일부 서드파티 구현, 아마도 remote_read를 구현하는 것들에 영향을 줄 수 있어요.
이 계약은 명시적으로 강제되지는 않지만, 정의되지 않은 동작을 일으킬 수 있어요.
UTF-8 이름 (UTF-8 names)
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
로그 메시지 형식 (Log message format)
Prometheus v3는 이전 go-kit/log 대신 log/slog를 채택했어요. 결과적으로 로그 메시지 형식이 바뀌었어요. 이전 로그 형식의 예:
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 라벨 값 (le and quantile label values)
Prometheus v3에서 클래식 히스토그램의 le 라벨과 요약의 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 구성 금지 (Disallow configuring Alertmanager with the v1 API)
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 2.0 migration guide)
Prometheus 1.8에서 2.0으로의 마이그레이션 가이드는 Prometheus v2.55 문서를 참조하세요.
더 알아보기 (Learn more)
- API 안정성 — 안정성 약속
- promtool 커맨드라인 — 이전 주제
- 커맨드라인 — 새 플래그
- 구성 (Configuration) — 새 구성 형식