반응형
쿠버네티스에서 Grafana를 Helm Chart로 배포하고, AWS ALB Ingress Controller로 외부에 노출하는 작업을 하다 보면 이런 상황을 만나곤 합니다.
- ALB 콘솔 Target Group 상태: Unhealthy
- 그런데 웹 브라우저에서 접속하면 Grafana 정상 동작
"아니… 헬스체크가 깨졌는데 어떻게 접속이 되지?"
저도 처음엔 이 상황이 꽤 혼란스러웠습니다.
1. 문제 상황
Terraform으로 kube-prometheus-stack의 Grafana를 설치하고, ALB Ingress를 통해 / 경로로 연결했을 때의 상태입니다.
ALB Target Group 상태
IP: 10.0.x.x:3000
Status: Unhealthy
Health checks failed with ...
그런데 브라우저로 http://<ALB-DNS>:3000 접속하면 Grafana 로그인 화면이 잘 뜹니다.
2. 왜 이런 현상이 생기나?
원인은 크게 두 가지입니다.
(1) Grafana의 / 경로 응답이 302 리다이렉트
- ALB의 기본 성공코드(success-codes)는 200입니다.
- Grafana / 요청은 보통 /login으로 302 Found 리다이렉트합니다.
- ALB는 302를 실패로 간주 → 타겟 상태 Unhealthy.
(2) ALB의 라우팅 동작 (Fail-Open)
- ALB는 모든 타겟이 Unhealthy일 때도 요청을 라우팅합니다.
- 그 결과 콘솔은 빨갛게 떠도, 실제 요청은 전달 → Grafana 접속은 가능.
즉, 접속은 되지만 ALB 입장에서 건강하지 않은 서비스로 보고 있는 겁니다.
3. 해결 방법
헬스체크가 200으로 떨어지게 만들면 됩니다.
Grafana는 /api/health 경로에서 JSON 형태로 항상 200 OK를 반환합니다.
ALB Ingress에 다음 Annotation을 추가하면 됩니다.
"alb.ingress.kubernetes.io/healthcheck-path" = "/api/health"
"alb.ingress.kubernetes.io/success-codes" = "200-399"
완성된 예시 (Terraform Ingress)
resource "kubernetes_ingress_v1" "grafana_alb" {
metadata {
name = "grafana-alb"
namespace = "monitoring"
annotations = {
"alb.ingress.kubernetes.io/scheme" = "internal"
"alb.ingress.kubernetes.io/target-type" = "ip"
"alb.ingress.kubernetes.io/group.name" = "shared-alb"
"alb.ingress.kubernetes.io/listen-ports" = jsonencode([{ HTTP = 3000 }])
"alb.ingress.kubernetes.io/backend-protocol" = "HTTP"
# ✅ 헬스체크 수정
"alb.ingress.kubernetes.io/healthcheck-path" = "/api/health"
"alb.ingress.kubernetes.io/success-codes" = "200-399"
}
}
spec {
ingress_class_name = "alb"
rule {
http {
path {
path = "/"
path_type = "Prefix"
backend {
service {
name = "kube-prometheus-stack-grafana"
port { number = 80 }
}
}
}
}
}
}
}
4. 적용 후 변화
- ALB Target Group 상태: Healthy
- 접속: 그대로 정상
- 모니터링, 로드밸런싱 안정성 ↑
5. 추가 팁
- 보안그룹 열기: target-type=ip일 경우, ALB → Pod targetPort(TCP 3000) 트래픽이 노드 SG에서 허용돼야 함.
- 다른 서비스에도 동일 패턴 적용: Prometheus는 /-/healthy, Argo CD는 / 또는 /healthz 경로 사용.
- 성공 코드 범위 조정: 200-399로 지정하면 대부분의 리다이렉트/정상 응답이 통과.
6. 마무리
이번 경험으로 얻은 교훈은 간단합니다.
ALB 헬스체크는 실제 앱의 정상 동작 경로를 지정해야 한다.
Grafana처럼 루트 경로가 리다이렉트되는 서비스는 반드시 별도의 health endpoint를 써야, 콘솔 상태와 실제 서비스 상태가 일치하게 됩니다.
반응형
'DevOps' 카테고리의 다른 글
| OpenVPN Split Tunnel 환경에서 특정 서브넷 라우팅 누락 문제와 EKS 환경 라우팅 고려사항 (0) | 2025.08.15 |
|---|---|
| EKS에서 Amazon DocumentDB 연결 테스트: 왜 telnet은 안되고 mongo는 될까? (1) | 2025.08.12 |
| Terraform으로 ArgoCD + GitHub Deploy Key 구성 시 SSH 인증 오류 해결기 (0) | 2025.08.08 |
| Terraform으로 AWS ALB Ingress 삭제 시 finalizer에 걸려 무한 대기하는 문제 해결기 (0) | 2025.08.08 |
| AWS ALB Ingress Controller – 포트 & Path 기반 라우팅 완전 정리 (0) | 2025.08.08 |
댓글