EKS Thanos 배포 트러블슈팅 — StorageClass·IRSA 연쇄 오류

데이터·관측성4분조회

kube-prometheus-stack 위에 Thanos 를 올려 장기 보관과 다중 클러스터 조회를 붙였습니다. 한 번에 올라가지 않았고, 하나를 고치면 그게 가리고 있던 다음 문제가 드러나는 식으로 배포가 끝날 때까지 일곱 번 멈춰 섰습니다.

Thanos Sidecar의 S3 쓰기 실패

level=error err="Access Denied" msg="failed to upload"

ServiceAccount 에 IAM Role annotation 이 없거나, 있더라도 Trust Policy 에 그 ServiceAccount 가 없으면 이렇게 나옵니다.

kubectl annotate serviceaccount my-prometheus -n monitoring \
  eks.amazonaws.com/role-arn=arn:aws:iam::123456789012:role/ThanosS3AccessRole \
  --overwrite

# annotation은 파드가 새로 떠야 반영됩니다
kubectl delete pod prometheus-my-prometheus-0 -n monitoring

붙었는지는 컨테이너 안에서 확인합니다.

kubectl exec -n monitoring prometheus-my-prometheus-0 -c thanos-sidecar -- \
  env | grep AWS

kubectl exec -n monitoring prometheus-my-prometheus-0 -c thanos-sidecar -- \
  aws s3 ls s3://my-thanos-bucket/ --region ap-northeast-2

Trust Policy — Thanos 컴포넌트 전부 포함

Sidecar 를 고친 뒤에 다른 곳에서 같은 에러가 나왔습니다.

# Compactor
level=error err="BaseFetcher: iter bucket: Access Denied"

# StoreGateway
level=error err="bucket store initial sync: Access Denied"

Trust Policy 에 my-prometheus 만 넣어뒀는데, S3 를 읽고 쓰는 게 그것만이 아닙니다. StoreGateway, Compactor 도 각자의 ServiceAccount 로 붙습니다. 컴포넌트를 추가할 때마다 Trust Policy 를 같이 늘려야 합니다.

gp3 StorageClass 부재

level=error err="sync \"monitoring/my-prometheus\" failed:
  storage class \"gp3\" does not exist"

values 에 storageClassName: gp3 이 들어 있었지만 클러스터에 그 StorageClass 가 없었습니다.

kubectl get sc

gp2 로 바꿔 재배포했는데, 여기서 끝난 줄 알았더니 아니었습니다.

StatefulSet volumeClaimTemplates는 immutable

StoreGateway 가 Pending 에서 안 넘어갔습니다.

0/6 nodes are available: pod has unbound immediate PersistentVolumeClaims

values 를 gp2 로 고쳤지만 StatefulSet 은 이미 gp3 로 만들어져 있었습니다. volumeClaimTemplates 는 immutable 이라 helm upgrade 로 바뀌지 않습니다. PVC 는 계속 없는 StorageClass 를 요구하며 Pending 으로 남습니다.

지우고 다시 만들어야 합니다.

helm uninstall thanos -n monitoring
kubectl delete pvc data-thanos-storegateway-0 -n monitoring

StorageClass 는 처음 배포할 때 맞춰두는 게 낫습니다. 나중에 바꾸면 StatefulSet 재생성으로 번집니다.

Bitnami 기본 이미지 pull 실패

Failed to pull image "docker.io/bitnami/thanos:0.39.2-debian-12-r2": not found

Bitnami 차트의 기본 이미지가 무료로 제공되지 않습니다. 2025년 8월부터 유료 구독이 필요합니다.

Bitnami 이미지 대신 Thanos 업스트림이 배포하는 quay.io 이미지를 가리키게 합니다.

image:
  registry: quay.io
  repository: thanos/thanos
  tag: v0.39.2
  pullPolicy: IfNotPresent

차트가 이미지 출처를 검증하므로 설치할 때 우회 플래그가 필요합니다.

helm install thanos bitnami/thanos \
  -n monitoring \
  -f values/thanos-values.yaml \
  --set global.security.allowInsecureImages=true

ALB에서 path /는 다른 Ingress에 밀림

Query Frontend 가 브라우저에서 404 였습니다. 포트포워드로는 정상이었습니다.

이 Ingress 의 path 가 / 였고 같은 ALB 를 쓰는 다른 Ingress 들은 /* 였습니다. ALB 가 /* 를 먼저 매칭해서 요청이 다른 Target Group 으로 갔습니다.

queryFrontend:
  ingress:
    path: /*
kubectl describe ingress thanos-query-frontend -n monitoring | grep Path

Operator가 StatefulSet reconcile 안 함

values 에서 이미지를 v0.39.2 로 바꿨는데 StatefulSet 은 v0.34.1 그대로였습니다.

Prometheus CRD 는 갱신됐지만 Prometheus Operator 가 reconciliation 을 트리거하지 않은 상태였습니다. Operator 를 재시작하면 CRD 를 다시 읽고 StatefulSet 을 맞춥니다.

kubectl rollout restart deployment my-operator -n monitoring
kubectl delete pod prometheus-my-prometheus-0 -n monitoring

kubectl get pod prometheus-my-prometheus-0 -n monitoring \
  -o jsonpath='{.spec.containers[?(@.name=="thanos-sidecar")].image}'
  1. 불러오는 중