-
Notifications
You must be signed in to change notification settings - Fork 0
component cloud infra collector
Dashboard가 AWS와 Kubernetes API를 직접 호출하지 않도록, 필요한 상태만 주기적으로 수집해 DynamoDB/S3 read model로 만드는 Lambda 컴포넌트다.
Cloud Infra Collector는 하나의 코드 패키지를 Fast와 Slow Lambda로 나눠 실행한다.
EventBridge Scheduler rate(1 minute)
-> CloudInfraFastCollector
-> LATEST.fast + HISTORY#FAST + S3 fast snapshot
EventBridge Scheduler rate(5 minutes)
-> CloudInfraSlowCollector
-> LATEST.slow + HISTORY#SLOW + S3 slow snapshot
| 구분 | 주기 | 목적 |
|---|---|---|
| Fast | 1분 | 사용자 서비스와 데이터 파이프라인의 빠른 이상 감지 |
| Slow | 5분 | EKS/Kubernetes/ArgoCD와 S3 inventory 상태 수집 |
Fast 대상은 장애 영향이 빠르고 CloudWatch의 1분 metric과 잘 맞는다. Slow 대상은 API 호출량이 많고 상대적으로 천천히 변하므로 5분으로 분리한다. 이 분리는 화면 갱신 지연과 AWS/Kubernetes API 호출 비용을 함께 제어한다.
초기에는 CloudWatch Container Insights로 EKS node/pod/container metric 전체를 상시 수집하는 방식을 검토했다. 현재 기준은 다음과 같다.
metrics-server: 사용
CloudWatch Container Insights: 기본 비활성
필요한 요약 metric: Slow Collector가 Kubernetes Metrics API에서 직접 수집
2-node Hub에서 Container Insights와 관련 로그를 상시 수집하면 MVP 환경에 과한 월 비용이 발생한다. Dashboard는 원본 container metric 전체가 아니라 node ready, pod phase, restart, top pod와 같은 요약값만 필요하므로 collector read model이 더 적합하다.
비용의 대부분은 CloudWatch GetMetricData이고, 이는 "받는 metric 개수 × 수집 주기"에 비례한다. 단가는 $0.01 / 1,000 metrics이며 CloudWatch 무료 티어(1M API 요청)에서 GetMetricData는 제외되어 첫 metric부터 과금된다.
metric 1개 1분 수집 = 43,200회/월 ≈ $0.43/월
metric 1개 5분 수집 = 8,640회/월 ≈ $0.086/월
따라서 같은 데이터라도 출처를 고르면 과금 여부가 갈린다. 비용은 사용률 metric에서만 발생한다.
| 데이터 | 출처 | 과금 |
|---|---|---|
| 상태(available / ACTIVE / Synced) |
Describe*, ArgoCD CRD |
무료 |
| 카운트(ECS desired/running, ALB healthy host, DLQ depth) |
DescribeServices, DescribeTargetHealth, SQS GetQueueAttributes
|
무료 |
| node/pod CPU·메모리 | Kubernetes Metrics API (metrics-server) | 무료 |
| 사용률·rate(CPU%, 메모리%, 5xx, latency, throttle, error, eviction) | CloudWatch GetMetricData
|
유료 |
비용 절감 레버:
- 상태값은
Describe로, DLQ depth는GetQueueAttributes로 받아 CloudWatch 과금을 회피한다. - 자주 안 변하는 사용률(Redis/RDS)은 Slow(5분)로 옮겨 해당 metric 비용을 1/5로 낮춘다.
-
GetMetricData는 한 호출에 최대 500 metric까지 배치한다(호출 수는 줄지만 metric당 과금은 동일). - fast 사용률 metric 수를 줄이면 비용은 선형으로 감소한다.
대략 비용(사용률 metric 2535개, 대부분 fast 1분, 상시 가동 기준):
필요 metric만 collector 수집(Container Insights OFF): ~$11~17/월
(CloudWatch GetMetricData가 ~$10~15로 동인, 나머지 Lambda/DDB/S3는 합쳐 ~$1 내외)
CloudWatch Container Insights 전체 상시 ON: ~$65~75/월
데모 build/destroy 운영 패턴에서는 stack 가동 시간만 과금되어 실제 비용은 훨씬 낮다. 환경별 합계는 비용 기준서를 따른다.
Fast Collector는 AWS control API, CloudWatch, DynamoDB를 사용한다.
| 영역 | 주요 값 | 출처 |
|---|---|---|
| ECS | desired/running/pending, CPU/Memory |
ecs:DescribeServices, CloudWatch AWS/ECS
|
| ALB | healthy/unhealthy target, 5xx, latency | ELBv2 API, CloudWatch AWS/ApplicationELB
|
| CloudFront | 5xx error rate | CloudWatch AWS/CloudFront
|
| Redis | 상태, CPU, free memory, connections, evictions | ElastiCache API, CloudWatch |
| RDS | 상태, CPU, connections, free memory/storage | RDS API, CloudWatch |
| Lambda | invocation, error, throttle, p95 duration | CloudWatch AWS/Lambda
|
| DynamoDB | system error, read/write throttle | CloudWatch AWS/DynamoDB
|
| SQS DLQ | visible message, oldest message age | CloudWatch AWS/SQS
|
| Scheduler | enabled/disabled | EventBridge Scheduler GetSchedule
|
| Factory freshness | pipeline status, age, Safety Score, top causes | FACTORY#{factory_id}/LATEST |
Fast 결과는 다음 section으로 묶인다.
fast.backend_runtime
fast.datastores
fast.data_pipeline
fast.factory_freshness
fast.errors[]
각 section은 status, 판단 근거인 reasons[], 수집 실패인 errors[]를 가진다. 수집 예외가 있으면 해당 section은 과거 정상값으로 위장하지 않고 unknown이 된다.
Factory freshness는 factory-a/b/c의 pipeline_status 중 가장 나쁜 값을 section 상태로 사용한다. 최신 코드의 Cloud overall_status에도 이 section이 포함된다.
Slow Collector는 management plane과 저장 경로 freshness를 수집한다.
| 영역 | 주요 값 | 출처 |
|---|---|---|
| EKS cluster | status, version, 생성 시각 | eks:DescribeCluster |
| EKS nodegroup | status, scaling, health issue | EKS API |
| Auto Scaling | desired/healthy instance | Auto Scaling API |
| Kubernetes node | Ready, CPU/Memory | Kubernetes API, Metrics API |
| Kubernetes pod | phase, restart, CPU/Memory top N | Kubernetes API, Metrics API |
| ArgoCD | application sync/health | ArgoCD Application CRD |
| S3 freshness | raw/processed/processed_agg 최신 object | s3:ListBucket |
결과 section은 다음과 같다.
slow.eks_management
slow.storage_freshness
slow.errors[]
Storage freshness는 공장별 최신 raw, processed/state_snapshot, processed_agg/metrics_5m object를 확인한다. 세 시각이 모두 없으면 unknown, processed 또는 aggregate가 없으면 warning, 필요한 출력이 있으면 normal이다.
Collector 내부 상태 우선순위는 다음과 같다.
normal < unknown < warning < critical
overall_status는 현재 Fast와 Slow section의 최악 상태다.
backend_runtime
datastores
data_pipeline
factory_freshness
eks_management
storage_freshness
-> worst_status()
주요 판정 예:
- ECS desired가 있는데 running이 0이면
critical, 일부만 running이면warning - ALB healthy target이 0이면
critical, 5xx 또는 latency 임계 초과면warning - Redis/RDS service가 available이 아니면
critical - Lambda error/throttle, DynamoDB throttle, DLQ message, disabled scheduler는
warning - EKS/NodeGroup이 ACTIVE가 아니거나 ASG healthy가 부족하면
warning또는critical - node가 모두 NotReady면
critical, 일부 NotReady면warning - Failed pod가 하나라도 있으면 현재 collector 코드에서는
critical - ArgoCD Degraded는
critical, OutOfSync는warning
Collector 임계값은 Lambda 환경 변수로 바꿀 수 있지만, 문서보다 배포된 코드와 Terraform 입력을 우선한다.
기존 AEGIS-DynamoDB-FactoryStatus 테이블을 재사용한다.
pk = CLOUD#infra
sk = LATEST
sk = HISTORY#FAST#{timestamp} # 기본 TTL 6시간
sk = HISTORY#SLOW#{timestamp} # 기본 TTL 24시간
Fast write는 기존 slow와 slow_updated_at을 보존하고 fast만 갱신한다. Slow write도 기존 Fast 필드를 보존한다. 따라서 서로 다른 scheduler 실행이 상대 track을 지우지 않는다.
S3에는 TTL 필드를 제외한 전체 snapshot을 저장한다.
processed/cloud_infra/fast/yyyy=YYYY/mm=MM/dd=DD/hh=HH/{timestamp}.json
processed/cloud_infra/slow/yyyy=YYYY/mm=MM/dd=DD/hh=HH/{timestamp}.json
DynamoDB는 Dashboard의 hot read model이고, S3 snapshot은 RiskAlertDispatcher trigger와 장기 데이터 처리의 입력이다.
Collector가 중단되면 스스로 stale 상태를 새로 쓸 수 없다. 따라서 Dashboard Backend가 LATEST를 읽는 시점에 freshness를 다시 계산한다.
| Track | stale 기준 |
|---|---|
| Fast |
fast_updated_at age > 180초 |
| Slow |
slow_updated_at age > 900초 |
시각이 없거나 파싱할 수 없어도 stale이다. stale track은 container와 하위 section 상태가 unknown으로 바뀌며, 저장된 overall_status가 normal이면 API 응답에서는 warning으로 올린다.
이 판정은 Dashboard 표시용 최소 변환이다. S3를 직접 읽는 RiskAlertDispatcher는 이 Backend 변환을 거치지 않고 snapshot 자체의 상태와 규칙을 평가한다.
Slow Collector는 AWS IAM 권한만으로 Kubernetes API를 읽을 수 없다. Terraform은 Lambda 실행 role을 EKS access entry로 등록하고 cluster 범위의 AmazonEKSAdminViewPolicy를 연결한다.
Lambda IAM role
-> aws_eks_access_entry
-> AmazonEKSAdminViewPolicy
-> EKS endpoint 인증
-> Kubernetes/Metrics/ArgoCD read
권한이 없거나 새 EKS cluster 재생성 후 binding이 복구되지 않으면 kubernetes_api 수집이 실패하고 관련 상태가 unknown이 된다. 이때 collector errors[]와 CloudWatch Lambda 로그를 함께 확인한다.
두 소비자는 같은 S3/DynamoDB read model을 사용하지만 목적이 다르다.
| 소비자 | 사용 방식 |
|---|---|
| Cloud Infra 화면 | Fast/Slow 전체 section, factory freshness, history, read-time stale 상태를 표시 |
| RiskAlertDispatcher | S3 snapshot의 alert rule만 평가하고 specific 원인 중심으로 Slack 전송 |
특히 Factory freshness와 Redis/RDS datastores section은 Cloud 화면과 최신 overall_status에는 포함되지만, 현재 Cloud fast Slack의 section generic 규칙에서는 평가하지 않는다. Factory freshness 이상은 factory state_snapshot의 pipeline alert 경로에서 처리한다. Datastore API 수집 실패는 통합 fast.errors[]의 collector error로 알림 대상이 될 수 있지만, Redis/RDS 상태 임계 초과 자체는 현재 Dashboard 관찰 항목이다.
관련 문서
- 시스템 아키텍처
- 제어 & 데이터 플레인
- Dashboard VPC 설계
- 하드웨어 배치
- Hub EKS 네임스페이스
- Tailscale Mesh VPN
- 데이터 생명주기
- 데이터 조회 모델
- 실시간 갱신 구조
- IoT 데이터 계약
- Reporting Pipeline
- 로컬 스토리지
- 클라우드 스토리지
- Edge Agent
- Edge AI 탐지
- Factory-A Log Adapter
- Dummy Sensor
- Edge IoT Publisher
- Lambda Data Processor
- Risk Normalizer
- Risk Score Engine
- Pipeline Status Aggregator
- Graph Aggregator 5m
- Cloud Infra Collector
- Daily Report Generator
- Risk Alert Dispatcher
- Image Snapshot Pipeline
- Dashboard Backend
- Dashboard Web
- AI 채팅 어시스턴트