Community라이팅 & 에디팅github.com

Thanos 배포 리뷰 및 진단

Thanos 배포(Helm values, 매니페스트, 컴포넌트 플래그, 알림 규칙, 캐시 설정)를 검토, 작성 또는 규모 산정하거나 Thanos 읽기 경로 포화 상태(스토어 게이트웨이 게이트 고정, 느린 글로벌 쿼리, 유휴 후 첫 번째 쿼리 무한 대기, Receive OOM, 절대 또는 항상 발생하는 컴팩터 알림, Redis/Memcached/Dragonfly 캐시 크기 조정)를 진단할 때 사용합니다.

Thanos 배포 리뷰 및 진단란 무엇인가요?

이 스킬은 Thanos 배포를 검토하고 읽기 경로 포화 상태를 진단하기 위한 현장에서 입증된 규칙과 절차를 제공합니다. GKE에서 글로벌 쿼리어 뒤에 있는 약 20개의 단일 테넌트 Thanos 스택을 운영한 경험을 바탕으로, 데이터 손실, 중단 위험 및 비용 최적화를 방지하는 자세한 플래그 및 구성 검사 목록을 제공합니다. 쿼리어, 스토어 게이트웨이, 캐시(Redis/Memcached/Dragonfly), Receive, 컴팩터 등 각 주요 컴포넌트에 대한 심층 지침을 다루며, `references/rules.md`에 완전한 규칙 세트가 있습니다. 이 스킬은 Claude Code, Cursor, Codex와 같은 AI 에이전트가 Thanos 배포를 검토하고, 쿼리 동시성 불변 조건을 계산하며, 심각도에 따라 순위가 매겨진 결과를 생성하는 데 적합합니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/PixiBixi/claude-skills/tree/HEAD/plugins/wiki/skills/reviewing-thanos-deployments

Installed? Explore more 라이팅 & 에디팅 skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Thanos 배포 리뷰

GKE에서 글로벌 쿼리어 뒤에 있는 약 20개의 단일 테넌트 Thanos 스택(Thanos 0.42, 캐시 0.35+)을 운영한 현장 규칙입니다. 숫자와 근거를 포함한 신뢰할 수 있는 출처입니다:

전체 규칙 세트(R1-R102, 플래그, 기본값, 메트릭, 앵커)는 references/rules.md에 있습니다. 변경 사항이 영향을 미치는 각 컴포넌트의 섹션을 결론 내리기 전에 읽으십시오.

리뷰 절차

  1. Thanos 버전(이미지 태그)을 확인합니다. 플래그와 기본값은 변경됩니다: 모든 플래그를 버전에 맞게 확인합니다(규칙 R92).
  2. 래퍼 차트(bitnami thanos, 로컬 umbrella 차트, 수동 extraFlags/args)를 사용하는 경우, 렌더링된 매니페스트(helm template per stack)의 플래그를 읽고, values 파일이 아닌 것을 확인합니다. 레이어가 서로를 재정의하고 일부 플래그는 템플릿에만 존재합니다.
  3. 배포별 이름(레이블 스택이 정리되는 레이블, 테넌트 레이블, 클러스터 또는 데이터센터 레이블)은 구성 자체에서 가져옵니다. diff에 표시되지 않으면 이름을 가정하지 말고 GitOps 저장소를 요청합니다.
  4. 각 구성 요소에 대해 아래 체크리스트를 실행한 다음 references/rules.md의 해당 섹션을 실행합니다.
  5. 동시성 불변 조건을 4가지 플래그 중 하나라도 설정되거나 기본값으로 남겨진 경우 실제 값으로 계산합니다.
  6. 알림 규칙을 구성 요소가 실제로 실행되는 방식(CronJob, 스팟, Pending 파드)에 대해 확인합니다.
  7. 아래 출력 형식으로 보고합니다.

컴포넌트별 체크리스트

동시성 불변 조건(쿼리 프론트엔드 + 쿼리어 + 스토어 게이트웨이). --query-range.max-query-parallelism (기본값 14) x min(selectors, --query.max-concurrent-select) (기본값 4)는 min(--store.grpc.series-max-concurrency, --query.max-concurrent) (둘 다 기본값 20)보다 낮게 유지되어야 합니다. 기본값은 이미 이를 위반합니다(56 vs 20). 병렬성만으로 게이트 한도에 도달하면 하나의 쿼리가 모든 스택의 게이트를 포화시킵니다. --query.max-concurrent-select를 4보다 훨씬 높게 올리면 한도가 제거됩니다: 승수는 원시 선택기 개수가 됩니다. 스토어 게이트웨이 RSS를 바인딩하도록 크기가 조정된 게이트(OOMKill 후 설정)는 메모리 바운드이므로 유지하십시오. 불변 조건은 광범위한 쿼리에 바인딩됩니다: 측정된 쿼리는 평균 1.5개의 선택기를 가지며, 게이트 포화는 하나의 광범위한 쿼리가 아닌 기록 샤드의 여러 동시 쿼리에서 발생했습니다. 글로벌 쿼리어는 StoreAPI를 통해 지역 쿼리어에 도달하며, 이는 PromQL 게이트를 우회합니다. 두 승수를 함께 수정하고, 글로벌 프론트엔드를 포함하고, --query.max-concurrent를 전체 쿼리어 풀에 대해 계산하고, 각 승수에 준수해야 하는 다운스트림 한도를 주석으로 추가하십시오.

쿼리어.

  • 부분 응답은 기본적으로 켜져 있습니다(--query.partial-response 기본값 true): 플래그가 없으면 안전한 기본값이 아닙니다. 이는 오류가 발생한 스토어를 드롭하고 느린 스토어는 드롭하지 않습니다: --store.response-timeout 기본값은 0ms(비활성화)이므로, 하나의 느린 스토어는 드롭되는 대신 --query.timeout(기본값 2m)에서 전체 쿼리를 실패하게 합니다.
  • ruler 또는 경고에서 사용하는 쿼리어의 부분 응답은 알림을 조용히 놓칠 수 있으며, 부분 응답은 절대 캐시되지 않습니다. 인간 Grafana 데이터 소스에서만 요청별로 활성화하십시오.
  • --selector-label은 템플릿 기본값이 되어서는 안 됩니다: 레이블의 2개 값을 수집하는 스택은 두 번째 값에 대해 EMPTY를 반환합니다(조용한 데이터 손실). 스택별로, 쿼리가 실제로 전달하는 단일 값 레이블을 선택하십시오. 설정된 각 스택이 실제로 수집하는 내용과 비교하여 확인하십시오.
  • --grpc-compression은 v0.43.0 이후로 더 이상 사용되지 않습니다. --endpoint.sd-config의 client_config.compression per endpoint로 대체되었지만, 해당 엔드포인트도 자체 tls_config(예: enabled: false)를 설정하지 않으면 무시됩니다: 그렇지 않으면 전역 플래그가 여전히 우선합니다.

스토어 게이트웨이.

  • 포화 상태를 해결하기 위해 --store.grpc.series-max-concurrency를 절대 올리지 마십시오: 게이트는 대기열을 만들고 거부하지 않습니다. 포화는 시간 초과로 나타나며, 대부분의 분은 한도보다 훨씬 낮으며, 이를 올리면 스파이크 동안 유일한 바운드가 제거됩니다. 쿼리 프론트엔드 느린 로그에서 클라이언트를 찾으십시오.
  • --store.limits.request-series=2000000은 절대 실행되지 않는 복사된 값입니다(측정된 가장 큰 호출: 200000 시리즈). 먼저 thanos_bucket_store_series_data_touched_bucket{data_type="series"}를 측정하십시오.
  • thanos_bucket_store_queries_dropped_total이 0이라는 것은 아무것도 증명하지 않습니다: 기본적으로 0(해제)인 리미터만 계산합니다.
  • 시간 샤드는 겹쳐야 합니다; --min-time/--max-time 범위가 맞닿아 있으면 복제본이 없을 때 블라인드 윈도우가 보장됩니다. --min-time은 가장 오래된 바운드입니다. 양수 --max-time(예: 3h)은 상한이 아닙니다: 샤드는 Receive 위에 현재까지 서비스합니다.
  • 노드 부팅 디스크에 emptyDir이 없어야 합니다: 인덱스 헤더 다운로드가 이를 포화시킵니다(30분 복구). 프로비저닝된 IOPS/처리량이 있는 전용 PVC; Hyperdisk Balanced에서 용량은 성능을 제공하지 않습니다.
  • --sync-block-duration을 15m 기본값보다 낮게 설정하는 것은 캐싱 버킷 뒤에서 거의 비용이 들지 않습니다(이에 의존하는 것은 iter 호출만, 측정된 fleet 전체에서 ~1 USD/월): 전용 롤아웃을 할 가치가 없으며, 다음 계획된 재시작에서 수정하십시오.
  • lazy reader를 유지하고, lazy 인덱스 헤더 다운로드는 절대 하지 마십시오(p99 ~224초). 기본 5m 유휴 시간 제한에서는 각 간격 후 첫 번째 쿼리가 전체 재로드를 지불합니다. 숨겨진 플래그 --store.index-header-lazy-reader-idle-timeout을 근무일(10h)로 올리면 한 스택에서 로드 시간이 84% 단축되었으며, 상주 메모리 비용이 발생합니다. 숨겨진 플래그: 업그레이드 시 재확인하십시오.

캐시.

  • Thanos < v0.35.0에서 테넌트 간 공유 캐싱 버킷: 키 충돌, 스토어 게이트웨이는 Ready 상태를 유지하고 기록 데이터를 제공하지 않습니다. Redis prefix는 모든 버전에서 격리합니다. 단일 테넌트 카나리는 이를 잡을 수 없습니다.
  • 동일한 Redis의 인덱스 캐시 및 캐싱 버킷: 별도의 db (인덱스 db: 1).
  • 공유 캐시를 IN-MEMORY 캐시 크기로 크기 조정하지 마십시오(파드 가동 시간을 측정합니다). TTL 윈도우(명시적 단계로 롤링 >= 24시간 하위 쿼리의 P95) 동안 작업 세트의 크기를 측정하고, 파드 수가 아닌 샤드의 복제본 간 측정된 중복으로 나눕니다. 복제본은 동일한 블록을 로드하지만 다른 청크를 캐시합니다: 2개의 복제본은 1.4로 측정되었으며 2가 아닙니다.
  • 캐싱 버킷 하위 범위는 24시간 동안 유지됩니다(chunk_subrange_ttl). Redis expiration은 이를 관리하지 않습니다.
  • 쿼리 프론트엔드 캐시 파일은 엄격하게 구문 분석됩니다: ttl 없음, enabled_items 없음, TTL은 config: 아래의 expiration입니다. 알 수 없는 키: 컴포넌트가 시작을 거부합니다.
  • Sentinel 뒤의 Redis: Sentinel 서비스 + master_name, 그렇지 않으면 장애 조치 후 쓰기가 이전 마스터로 이동합니다.

Receive.

  • 전용 우선 순위 클래스로 온디맨드 상태를 유지합니다: 아직 업로드되지 않은 데이터를 보유하는 유일한 구성 요소입니다. 다른 모든 것은 스팟으로 이동합니다.
  • 메모리 제한을 피크 활성 시리즈로 설정합니다. head_series_limit는 공유 멀티 테넌트 Receive 또는 복제가 있는 경우에만 효과적입니다: 단일 복제본에서는 429가 테넌트의 모든 쓰기를 차단하고, OOM은 재시작과 WAL 재생만 발생시킵니다. 연결 가능한 meta_monitoring_url 없이는 비활성 상태입니다. 요청 제한은 413을 반환하고(Prometheus가 데이터를 삭제함), 시리즈 제한은 429를 반환합니다(재시도됨).
  • 풀 크기가 변경될 때는 Ketama 해시링, hashmod가 아닙니다.
  • Go 힙 바인딩: 파드 메모리 제한의 GOMEMLIMIT 또는 --enable-auto-gomemlimit(기본적으로 꺼져 있음, 컨테이너 제한의 0.9). Go는 1.25부터 cgroup에서 GOMAXPROCS를 설정하며, GOMEMLIMIT는 절대 설정하지 않습니다. Receive OOM은 서비스 재개 전에 WAL 재생을 의미합니다.

컴팩터.

  • CronJob으로: concurrencyPolicy: Forbid는 필수입니다(버킷에서 2개의 컴팩터가 블록을 손상시킴).
  • thanos_compact_todo_* 게이지는 --wait로만 등록됩니다: CronJob 모드에서는 이에 대한 알림이 절대 실행되지 않습니다. 기본 ThanosCompactIsDown은 23시간/24시간 실행됩니다. kube-state-metrics CronJob 규칙과 스토어 게이트웨이 thanos_blocks_meta_synced 백로그 프록시로 교체하십시오. 컴팩터 메트릭(thanos_compact_group_compactions_failures_total...)에 대한 모든 알림은 CronJob 모드에서 절대 실행되지 않습니다: 실행 사이에 스크랩 대상이 없습니다.
  • Thanos 버킷에 버킷 수명 주기 규칙 또는 아카이브 스토리지 클래스를 절대 사용하지 마십시오: 컴팩터만 블록 종속성을 알고 있습니다. 재시도 루프는 API 비용을 절감액의 10배로 증가시켰습니다.
  • 보존 계층은 스토어 게이트웨이가 제공하는 것과 정렬됩니다.

교차 요소.

  • 한 스택의 모든 구성 요소는 하나의 영역에 있습니다: 영역 간 트래픽은 데이터 경로의 모든 화살표에 대해 청구됩니다. 스택의 영역 분산 제약 조건은 비용 버그이며, 그렇지 않으면 의도적인 절충입니다.
  • for: 30m인 StatefulSet desired vs ready replicas에 대한 스토어 준비 상태 알림: up == 0은 제거된 Pending 파드에 대해 절대 실행되지 않으며, for: 5m은 정상적인 스팟 복구 시 페이지를 보냅니다.

포화 진단

references/rules.md의 절차 D1-D10을 사용하십시오. D1의 핵심: in_flight = throughput x duration(리틀의 법칙), 파드별 측정; 기간이 일반적으로 지배적입니다(현장에서 x190 대 x4.5). max_over_time(...[$__interval:1m])로 게이트 패널 읽기, p999/p9999의 지연 시간, count(group by (pod) (up == 1))로 fleet 크기 읽기.

출력 형식

심각도별로 순위가 매겨진 결과: 데이터 손실 또는 조용한 잘못된 결과, 그 다음 중단 위험(구성 요소가 시작을 거부하는 구성은 여기에 포함), 그 다음 비용, 그 다음 위생. 각 결과:

  • 필드 또는 플래그, 라인 포함
  • 문제 및 구체적인 결과
  • 수정 사항, 정확한 값 또는 스니펫으로
  • references/rules.md에서 복사한 wiki URL(앵커 포함, 규칙 ID는 내부용이므로 생략)

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

관련 스킬