fix(nodecompat,chart): 자체 수집기 중복 차단 완성 + 스크레이프 발견 opt-in 화 - #35
Conversation
0.9.0 을 운영에 얹으면 조용히 메트릭을 잃는 결함 3건을 고친다. 셋 다 파드는 Ready, /metrics 는 200 이라 로그를 보지 않으면 드러나지 않는 종류다. ## 1. native collector 5그룹이 임베드 node_exporter 와 중복 등록 nativeCollectors 는 upstream collector 를 두 개(loadavg·uname)만 껐다. nodecompat 은 7그룹을 내므로 entropy·filefd·stat·vmstat·os 가 그대로 살아 같은 메트릭을 양쪽에서 등록했다. client_golang 은 충돌한 family 를 스크레이프에서 빼면서 200 을 계속 주므로(sink/metrics.go 가 ContinueOnError), 손실이 에러로 나타나지 않는다. Linux 실측으로 확인된 소실 대상: node_entropy_available_bits, node_filefd_allocated, node_procs_running, node_procs_blocked, node_os_version, node_vmstat_pgfault, node_vmstat_pgmajfault, node_vmstat_pswpin, node_vmstat_oom_kill. 차단 목록을 main.go 에 다시 적는 대신 nodecompat 이 자기 수집기 집합에서 파생시킨다(SupersededCollectors). subCollector 인터페이스에 Supersedes() 를 두어 새 수집기가 대체 대상을 밝히지 않으면 아예 추가되지 못하게 했다 — 두 목록이 어긋나는 것이 이 결함의 원인이었다. procs→"stat", osrelease→"os" 처럼 로컬 이름과 upstream 이름이 다른 두 건이 특히 빠지기 쉽다. 회귀 가드는 선언과 플래그의 정합성(단위)과 **실제 수집 결과의 교집합**(Linux 통합) 두 층이다. 후자는 결함을 되살려 9개 메트릭을 잡아내는 것으로 유효성을 확인했다. upstream 수집이 통째로 실패해도 교집합이 비어 통과하는 것을 막으려 "upstream family 20개 이상" 을 함께 단언한다. ## 2. nodevitals_build_info 가 소스에 박힌 버전을 신고 NewHeartbeat(cfg.Node, "0.8.5") 리터럴 탓에 0.9.0 이미지가 version="0.8.5" 를 냈다. 이 메트릭은 "이 노드가 어떤 빌드인가" 에 답하는 유일한 자기신고 수단이라, 그럴듯한 기본값은 확인 수단 자체를 없앤다. -ldflags -X main.version 주입으로 바꾸고 Chart.yaml 의 appVersion 을 단일 출처로 삼는다(Makefile·Dockerfile· release.yml 이 같은 값을 흘려보낸다). 미주입 시에는 "unknown" — 모르는 것을 모른다고 말하는 편이 아닐 수도 있는 릴리스를 자칭하는 것보다 낫다. ## 3. 스크레이프 발견 어노테이션이 업그레이드만으로 켜짐 0.9.0 이 파드 템플릿에 prometheus.io/scrape 를 무조건 렌더한다. 이미 Service / ServiceMonitor 로 수집하던 클러스터는 업그레이드만으로 role:pod 잡이 같은 파드를 한 벌 더 긁게 되어, 모든 시리즈가 job 라벨만 다른 2벌이 된다. 오류는 없고 카디널리티와 저장량만 두 배가 된다. serviceMonitor.enabled 와 같은 규칙을 적용해 scrapeAnnotations.enabled 로 분리하고 기본 off 로 둔다 — 발견 경로가 스스로 켜지는 것이 문제이지 기능 자체가 문제는 아니다. 어노테이션 정의를 configChecksums helper 에서 떼어냈다(이름과 내용이 어긋나 있었다). compatibility-check.sh 는 문서 전체에서 문자열만 grep 해 위치를 구분하지 못했고, 애초에 Makefile·CI 어디에도 연결돼 있지 않아 한 번도 실행된 적이 없었다. 파드 템플릿 안인지까지 검사하도록 고치고 chart-test 에 연결한다. Chart/appVersion 0.9.0 → 0.9.1.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 412f7e4ea9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| // node_procs_running / node_procs_blocked belong to upstream's "stat" | ||
| // collector, not to a "procs" one — that collector does not exist. | ||
| func (c *procsCollector) Supersedes() string { return "stat" } |
There was a problem hiding this comment.
Don't disable the whole stat collector
When nodeExporter.nativeCollectors is enabled, this Supersedes() value feeds NoCollectorFlags() and appends --no-collector.stat, but the local procsCollector only emits node_procs_running and node_procs_blocked. The upstream stat collector also supplies families such as node_boot_time_seconds, node_context_switches_total, node_forks_total, and node_intr_total, so enabling the embedded node_exporter with native collectors now silently drops those compatibility metrics instead of just deduplicating the two process gauges.
Useful? React with 👍 / 👎.
|
|
||
| // node_os_info / node_os_version come from upstream's "os" collector | ||
| // (os_release.go), which is not named after the file it reads. | ||
| func (c *osReleaseCollector) Supersedes() string { return "os" } |
There was a problem hiding this comment.
Keep the upstream os collector until parity
With native collectors on, returning os here disables the embedded node_exporter os collector entirely. The native replacement only emits node_os_info with 8 labels plus node_os_version, while node_exporter v1.12.1's os collector also exposes the image_id, image_version, variant, and variant_id labels and emits node_os_support_end_timestamp_seconds when SUPPORT_END is present, so clusters using those labels or support-end metadata lose or change the node_exporter-compatible surface after upgrade.
Useful? React with 👍 / 👎.
0.9.0 을 운영에 얹으면 조용히 메트릭을 잃는 결함 3건을 고칩니다. 셋 다 파드는 Ready,
/metrics는 200 이라 로그를 보지 않으면 드러나지 않습니다.1. native collector 5그룹이 임베드 node_exporter 와 중복 등록
nativeCollectors는 upstream collector 를 둘(loadavg·uname)만 껐지만nodecompat은 7그룹을 냅니다. 나머지 5개가 살아남아 같은 메트릭을 양쪽에서 등록했고,client_golang은 충돌한 family 를 스크레이프에서 빼면서도 200 을 계속 줍니다(sink/metrics.go가ContinueOnError).Linux 실측으로 확인한 소실 대상 9종 — 결함을 되살려 가드가 잡아내는 것을 확인했습니다:
entropynode_entropy_available_bitsfilefdnode_filefd_allocatedstatnode_procs_running,node_procs_blockedosnode_os_versionvmstatnode_vmstat_pgfault,pgmajfault,pswpin,oom_kill차단 목록을
main.go에 다시 적는 대신nodecompat이 자기 수집기 집합에서 파생시킵니다(SupersededCollectors).subCollector에Supersedes()를 둬서 대체 대상을 밝히지 않은 수집기는 추가 자체가 불가능하게 했습니다 — 두 목록이 어긋난 것이 이 결함의 원인이었습니다.procs→stat,osrelease→os처럼 로컬 이름과 upstream 이름이 다른 두 건이 특히 빠지기 쉽습니다.회귀 가드는 두 층입니다: 선언↔플래그 정합성(단위) + 실제 수집 결과의 교집합(Linux 통합). 후자에는 "upstream family 20개 이상" 단언을 함께 넣어, upstream 수집이 통째로 실패했을 때 교집합이 비어 통과하는 가짜 초록불을 막습니다.
2.
nodevitals_build_info가 소스에 박힌 버전을 신고NewHeartbeat(cfg.Node, "0.8.5")리터럴 탓에 0.9.0 이미지가version="0.8.5"를 냈습니다. 이 메트릭은 "이 노드가 어떤 빌드인가"에 답하는 유일한 자기신고 수단이라, 그럴듯한 기본값은 확인 수단 자체를 없앱니다.-ldflags -X main.version주입으로 바꾸고Chart.yaml의appVersion을 단일 출처로 삼습니다(Makefile·Dockerfile·release.yml 이 같은 값을 전달). 미주입 시"unknown"— 모르는 것을 모른다고 말하는 편이 아닐 수도 있는 릴리스를 자칭하는 것보다 낫습니다.실증(빌드된 바이너리):
3. 스크레이프 발견 어노테이션이 업그레이드만으로 켜짐
0.9.0 이 파드 템플릿에
prometheus.io/scrape를 무조건 렌더합니다. 이미 Service / ServiceMonitor 로 수집하던 클러스터는 업그레이드만으로role:pod잡이 같은 파드를 한 벌 더 긁게 되어, 모든 시리즈가job라벨만 다른 2벌이 됩니다. 오류는 없고 카디널리티와 저장량만 두 배가 됩니다.serviceMonitor.enabled와 같은 규칙으로scrapeAnnotations.enabled로 분리하고 기본 off 로 뒀습니다 — 발견 경로가 스스로 켜지는 것이 문제이지 기능 자체가 문제는 아닙니다. 어노테이션 정의는configChecksumshelper 에서 분리했습니다(이름과 내용이 어긋나 있었습니다).compatibility-check.sh는 문서 전체에서 문자열만 grep 해 위치를 구분하지 못했고, 애초에 Makefile·CI 어디에도 연결돼 있지 않아 한 번도 실행된 적이 없었습니다. 파드 템플릿 안인지까지 검사하도록 고치고chart-test에 연결합니다.검증
make fmt vet test통과 (13 패키지)make chart-lint(kubeconform strict),make chart-test(3종) 통과internal/nodecompat·cmd/nodevitals통과cmd/nodevitals에 첫 테스트 추가 (기존 0%)Chart/appVersion
0.9.0→0.9.1.