본문으로 건너뛰기
vmagent AZ 분할로 AZ 간 scrape 전송 줄이기

05 · vmagent AZ 분할로 AZ 간 scrape 전송 줄이기

AZ a/c에 agent 1대씩 배치·수치는 대략적인 규모로 표시

전체 트래픽 중 inter-AZ 비중 약 90% AZ 간 내부 통신
전체 네트워크 사용량 감소 약 13% 수집 클러스터 전체에 적용할 때의 예상
agent 경로의 AZ 간 전송 약 95% 감소 먼저 적용한 클러스터 · 실측

먼저 적용한 결과와 전체 적용 시 예상 효과

전체 네트워크 트래픽의 **약 90%가 AZ 간 내부 통신(inter-AZ traffic)**이었습니다. 청구 사용량으로 계산한 비율입니다. 내부 컴포넌트 사이에서 어떤 데이터가 AZ 경계를 넘는지 확인하다가 vmagent의 수집 경로를 살펴봤습니다.

AZ c의 vmagent 한 대가 다른 AZ의 타깃까지 수집하던 구성을 AZ별 수집으로 바꿨습니다. 먼저 적용한 작은 클러스터에서는 agent 경로의 AZ 간 전송이 약 95% 줄었습니다. 가장 큰 클러스터는 아직 같은 분할을 준비 중입니다.

vmagent로 수집하는 클러스터 전체에 적용하면 전체 네트워크 사용량이 약 13% 줄어들 것으로 예상합니다. 가장 큰 클러스터 한 곳만 적용했을 때의 예상 감소율은 약 10%입니다. 약 13%와 약 10%의 두 예상 감소율은 모두 변경 전 전체 네트워크 사용량을 기준으로 합니다.

분할 전 타깃 → vmagent 구간의 AZ 간 scrape 전송은 수집 클러스터 전체를 합쳐 실제 바이트 기준으로 하루 TB 단위로 추정했습니다. 같은 계정의 인스턴스 사이에서 AZ를 넘어 전송한 1GB는 보내는 쪽과 받는 쪽에 한 번씩 잡히므로, 청구 사용량으로는 그 두 배에 해당합니다.

따라서 전체 네트워크와 비교한 약 90%·약 13%는 청구 사용량 기준으로 읽어야 합니다. 인터넷 송신처럼 한 번만 집계되는 항목도 있어, 실제 바이트 기준으로 계산한 inter-AZ 비중은 90%보다 낮습니다.

압축하기 전에 AZ를 넘는 scrape 응답

분할 전에는 워크로드를 수집하는 vmagent 한 대가 AZ c에 있었습니다. 다른 AZ의 타깃이 내보내는 scrape 응답은 전체 전송량의 절반 정도였고, 이 응답은 수집할 때마다 AZ 경계를 넘었습니다.

scrape 응답에는 메트릭 이름과 라벨 문자열이 반복됩니다. 히스토그램과 라벨이 많은 사이드카는 샘플 수에 비해 응답이 큽니다. 응답의 대부분을 차지하는 Istio 사이드카 메트릭도 압축 없이 나갔습니다.

vmagent를 지난 샘플은 모아서 압축한 뒤 원격 저장 클러스터로 보냅니다. 쓰기 경로는 vmagent → 쓰기 LB → ingress → vminsert → vmstorage이며, vmstorage가 영속 데이터와 보관 용량을 관리합니다.

워크로드 클러스터의 vmagent가 수집한 샘플을 원격 저장 클러스터로 보냅니다. 화살표는 샘플이 움직이는 방향입니다.
도식 텍스트
  • 워크로드 클러스터 · 수집
  • 원격 저장 클러스터
  • 수집 타깃 — Pod · Service · Node
  • vmagent — 수집 · 전송 대기 큐
  • 쓰기 진입점 — LB → ingress
  • vminsert — 수신 · 분산
  • vmstorage — 영속 저장 · 보관 기간
  • 응답
  • 전송
  • 전달
  • 저장

압축 전 응답이 이동하는 타깃 → vmagent 구간부터 바꾸기로 했습니다. 저장소·보관 기간·수집 대상·주기를 유지하면 경로 변경이 전송량에 미친 효과를 비교할 수 있습니다. agent 한 대에 몰렸던 수집 부하도 나뉘지만 이번 비교는 AZ 간 전송량을 대상으로 했습니다.

전송 규모는 평균 scrape 전송량과 다른 AZ에서 발생하는 바이트 비중으로 추정했습니다. 파드 수가 비슷해도 응답 크기는 다를 수 있어, 타깃 개수 대신 실제 전송량을 기준으로 삼았습니다.

클러스터당 agent 1대인 구성에서는 이 구간의 하루 AZ 간 전송량을 TB 단위로 추정했습니다. 모든 타깃을 같은 AZ의 agent가 수집하면 AZ 간 scrape 전송은 거의 없어질 것으로 예상했습니다. 수집하는 메트릭의 양과 저장량은 그대로 두는 변경입니다.

AZ별 수집 필터와 agent 배치

분할할 때는 기존 agent를 AZ a에 고정하고 AZ c에 새 agent를 추가해, AZ a/c에 한 대씩, 총 두 대를 둡니다. 각 agent는 담당 타깃을 수집하고 기존 원격 저장 엔드포인트로 샘플을 보냅니다.

AZ c의 agent 한 대가 전체를 수집하던 구성과, 기존 agent를 AZ a로 옮기고 AZ c에 한 대를 추가한 구성을 비교합니다. 주황 화살표가 AZ를 넘는 scrape 전송입니다. 분할 전에는 전체 scrape 전송량의 약 50%가 이 경로로 AZ를 넘었고, 분할 뒤에는 같은 AZ 안에서 끝납니다.
도식 텍스트
  • AS-IS · 수집 클러스터
  • AS-IS · 원격 저장 클러스터
  • TO-BE · AZ a/c에 한 대씩
  • TO-BE · 원격 저장 클러스터
  • AZ a 타깃 — 전송량의 약 50%
  • AZ c 타깃 — 전송량의 약 50%
  • vmagent · AZ c — 한 대가 전체 수집
  • 쓰기 진입점 — LB → ingress
  • VM 저장소 — vminsert → vmstorage
  • AZ a 타깃 — 같은 AZ에서 수집
  • AZ c 타깃 — 같은 AZ에서 수집
  • 기존 vmagent · AZ a — AZ a · fallback
  • 새 vmagent · AZ c — AZ c 타깃만 keep
  • 쓰기 진입점 — 기존 목적지 유지
  • VM 저장소 — vminsert → vmstorage
  • AZ 횡단
  • 응답
  • 전송
  • 저장
  • AZ 내부
  • AZ 내부
  • 전송
  • 전송
  • 저장

Node 메타데이터로 타깃을 구분

타깃의 AZ는 Node 라벨에서 읽습니다. promscrape.kubernetes.attachNodeMetadataAll: "true"로 Pod·Endpoint에 Node 메타데이터를 붙이고, __meta_kubernetes_node_label_topology_kubernetes_io_zone을 기준으로 수집 대상을 나눕니다. agent가 실행될 AZ는 nodeAffinity로 고정합니다.

수집 필터와 agent 배치를 함께 맞춰야 합니다. AZ c 타깃만 골라도 agent가 AZ a에 뜨면 응답은 여전히 AZ를 넘습니다. agent를 두 AZ에 배치하고 필터를 나누지 않으면 같은 타깃을 중복 수집할 수 있습니다.

구성기존 agent · AZ a새 agent · AZ c
수집 규칙AZ c 타깃 dropAZ c 타깃만 keep
zone을 판정할 수 없는 타깃fallback으로 수집제외
VMStaticScrape·VMProbe·VMScrapeConfig전담제외

분류되지 않은 타깃은 기존 agent가 담당

기존 agent는 AZ a만 keep하도록 제한하지 않습니다. 양쪽 agent가 자기 AZ만 수집하면 zone 정보가 없는 타깃은 어느 쪽에도 속하지 못합니다. 기존 agent에서 AZ c만 제외하면 신규 AZ나 zone 정보가 없는 타깃도 계속 수집할 수 있습니다.

표의 VMStaticScrape·VMProbe·VMScrapeConfig도 Node 메타데이터가 없거나 SD 구성이 달라 기존 agent가 전담합니다.

먼저 적용한 클러스터에서는 수명이 짧은 노드가 삭제될 때 Node 객체가 파드보다 먼저 사라진 일이 있었습니다. 기존 agent가 해당 파드를 fallback으로 한두 번 더 수집했고, 두 agent 사이의 중복 1건으로 나타났습니다. 누락 대신 중복을 허용한 설계가 동작한 경우라 조치하지 않았습니다.

fallback은 분류되지 않은 타깃의 수집 담당을 정하는 규칙입니다. 새 agent가 죽었을 때 기존 agent가 AZ c까지 대신 수집하는 장애 전환 기능은 없습니다. 분할 뒤에는 agent별 담당 범위의 수집 중단을 감시하고, 해당 AZ에서 agent가 다시 실행될 노드 여유도 확보해야 합니다.

두 agent를 한 번에 바꾸는 전환

두 agent의 설정을 한 번에 바꾸기로 했습니다. 먼저 적용한 클러스터에서는 이 방식으로 전환한 뒤 30초 구간 하나에서 타깃의 약 8%가 빠졌고, 이후에는 정상 수집했습니다. 앞서 검토했던 계획은 새 agent를 배포한 뒤 기존 agent의 수집 범위를 좁히는 두 단계 방식이었습니다.

배포 중에는 두 agent 모두 새 파드가 Ready가 된 뒤에 옛 파드가 지워집니다. 그동안 pod·service 타깃은 옛 파드가 계속 수집하므로 공백이 없습니다. node 타깃(kubelet·cAdvisor·probes)은 옛 파드가 새 설정을 읽는 즉시 AZ c 노드를 빼므로, 새 agent가 뜰 때까지 AZ c의 node 타깃이 빕니다. 이 시리즈를 읽는 자동 확장 쿼리는 없습니다.

두 agent가 같은 타깃을 수집하는 동안에는 외부 라벨을 같게 맞춰 저장소의 중복 제거가 한 벌만 남기게 합니다. 외부 라벨이 다르면 다음 절의 시리즈 중복 문제가 생깁니다.

동시 전환 중 라벨 구성이 달라지는 일을 피하려고, zone을 판정하지 못한 타깃에 표시 라벨을 붙이는 규칙은 제거했습니다. 옛 파드는 Node 메타데이터를 붙이는 옵션 없이 새 설정을 읽어, pod·service 타깃의 zone이 비어 보입니다. 표시 규칙이 있으면 이때 모든 시리즈에 라벨이 붙어 라벨 구성이 바뀝니다. drop 규칙만 있으면 옛 파드는 이 타깃을 그대로 수집합니다.

전환 중 라벨 변경으로 발생한 자동 확장

먼저 적용한 클러스터에서는 수집 방향을 확인하려고 붙인 zone 라벨과 agent별 외부 라벨 차이가 문제를 만들었습니다. 수집 경로와 함께 저장되는 라벨까지 바꾸면 대시보드와 자동 확장 쿼리에도 영향을 줍니다.

옛·새 시리즈를 함께 더한 KEDA 트리거

검증용 라벨을 붙이거나 외부 라벨을 바꾸면 같은 타깃의 메트릭도 새 시리즈가 됩니다. 옛 시리즈가 조회 범위에서 빠지기 전까지는 둘이 함께 보일 수 있습니다. 이를 sum()으로 더하면 실제 부하가 그대로여도 값이 커집니다.

전환 중 이 값이 KEDA 트리거에 반영돼 불필요한 증설이 발생했습니다. 기존·새 시리즈를 같은 수집 대상 기준으로 묶고 최근 샘플을 읽도록 트리거 쿼리를 보강했습니다.

sum(max by (pod) (last_over_time(metric[1m])))

last_over_time(...[1m])으로 조회 창을 1분으로 좁히고 max by (pod)로 같은 파드의 옛·새 시리즈를 하나로 묶었습니다. 이 식을 다른 메트릭에 적용할 때는 pod만으로 같은 대상을 구분할 수 있는지 확인해야 합니다. 서로 다른 대상까지 하나로 묶으면 값의 의미가 달라집니다.

이후 전환에서는 두 agent의 외부 라벨을 같은 값으로 맞추고 검증용 라벨을 추가하지 않는 것을 기본으로 삼았습니다. 외부 라벨의 기본값은 agent 리소스 이름을 따르므로 그대로 두면 값이 달라집니다.

수집 방향은 vmagent의 타깃 목록과 자체 메트릭으로 확인할 수 있습니다. AZ별 수집과 저장 시리즈에 AZ 라벨을 추가하는 일은 별개의 결정입니다.

라벨 개수 상한에 걸린 시리즈

기존 라벨이 많던 일부 시리즈는 zone 라벨을 추가하면서 수신 측의 라벨 개수 상한에 걸렸습니다. 수집이 계속돼도 저장된 라벨 구성이 달라지면, 특정 라벨로 조회하는 쿼리에서는 데이터가 사라진 것처럼 보일 수 있습니다.

분할에는 서비스 디스커버리 단계의 Node 메타라벨을 사용하고, 저장되는 라벨은 최소한으로 변경하기로 했습니다. 전환 검증에서도 타깃의 up 상태뿐 아니라 기존 쿼리가 기대하는 라벨로 계속 조회되는지 확인해야 합니다.

타깃 대조부터 쓰기 경로 검증까지

전환이 끝나면 수집 범위와 총량을 확인한 뒤, 전송량 감소가 누락 때문은 아닌지 검증해야 합니다.

확인 항목확인할 내용
수집 범위두 agent 사이의 중복·누락, fallback 타깃, down 타깃
수집량scrape와 remote write 총량이 전환 전후 비슷한지
구간별 행 수agent 송신, vminsert 수신, vmstorage 저장의 행 수가 이어지는지
외부 라벨두 agent의 외부 라벨이 같은 값인지
검증용 라벨새 라벨이 시리즈 정체성을 바꾸거나 라벨 개수 상한을 넘지 않는지
자동 확장 쿼리lookback 구간에서 옛 시리즈와 새 시리즈를 함께 합산하지 않는지
agent 가용성AZ별 실행 노드 여유와 수집 중단 알림이 있는지

먼저 적용한 클러스터에서는 전환 직후 두 agent의 타깃 목록을 대조했습니다. AZ c 타깃은 새 agent에, AZ a와 fallback 타깃은 기존 agent에 있는지 확인했습니다. 한쪽의 누락과 다른 쪽의 중복이 같은 수일 수도 있어, 전체 타깃 수만 비교하지 않고 빠지거나 겹친 타깃을 따로 찾았습니다.

이어 두 agent의 scrape와 remote write 전송량을 합쳐 분할 전과 비교했습니다. 수집 총량은 비슷하게 유지되고, AZ 경계를 넘는 양은 줄어야 의도한 결과입니다.

쓰기 경로에서는 agent 송신, vminsert 수신, vmstorage 저장 행 수를 같은 1시간 창으로 맞춰 봤습니다. 구간별 차이는 1% 안이었고 drop·재시도·대기 큐 카운터는 모두 0이었습니다. 이 차이는 카운터를 읽는 시각이 달라 생기는 범위입니다.

측정할 때는 조회 시점과 구간도 맞춰야 했습니다.

  • 자동 확장 쿼리는 대시보드 그래프와 별도로 확인했습니다. 그래프의 조회 간격이 길면 전환 중 잠깐 커진 값을 놓칠 수 있어, KEDA가 읽는 instant query 결과를 대조했습니다.
  • agent 파드 교체 직후에는 짧은 rate와 긴 구간 평균이 다르게 보였습니다. 안정화 뒤 같은 측정 창으로 다시 비교하고, 누적 전송량에서도 같은 방향인지 확인했습니다.
  • 과거 전송량을 AZ별로 나누려면 이미 사라진 파드·노드도 찾아야 했습니다. 현재 목록만으로는 당시 타깃을 매핑할 수 없어, 목록의 조회 범위도 측정 기간에 맞췄습니다.

분할 뒤에도 남는 원격 저장 경로

수집부터 저장까지 이 경로에서 발생한 AZ 간 전송의 약 87%는 scrape 구간이었습니다(추정). 분할 뒤에도 remote write와 저장 클러스터 내부 통신에 해당하는 나머지 13% 정도는 남습니다.

여기서 약 13%는 수집·저장 경로의 AZ 간 전송 중 남는 비중입니다. 서두의 약 13%는 전체 네트워크 청구 사용량에서 줄어들 것으로 예상한 비중이므로 분모가 다릅니다.

새 agent의 출발 AZ가 달라지면 agent → 쓰기 LB 구간에서 AZ 간 전송이 생깁니다. 이 구간은 같은 VPC의 internal ALB를 사용하므로 요금이 붙지 않습니다.

구간분할 뒤 확인할 점
타깃 → vmagent타깃과 agent가 같은 AZ에 있는지
vmagent → 쓰기 LBLB 종류와 접속 경로. 같은 VPC의 internal ALB면 AZ를 넘어도 청구되지 않음
LB → ingress → vminsert요청이 저장 클러스터 안에서 어느 AZ로 분산되는지
vminsert → vmstorage저장 노드 선택과 복제 과정에서 AZ를 넘는 양이 얼마나 남는지

수집을 나눠도 저장 경로까지 같은 AZ로 맞춰지지는 않습니다. 쓰기 경로를 한 AZ에 모으면 전송이 줄어들 수 있지만 장애 영향은 커질 수 있습니다.

남는 구간 중 가장 큰 것은 vminsert → vmstorage입니다. vminsert가 시리즈 해시로 모든 저장 노드에 샘플을 나누고 복제본을 두 벌 보내기 때문에 수집 위치를 바꿔도 줄어들지 않습니다. 이 구간 전송의 3분의 1 남짓이 AZ를 넘었습니다(실측). 저장 계층에서 바꿀 것은 06 저장 구조에 따로 정리했습니다.

다음 검토 대상은 타깃의 응답 크기

AZ 분할 뒤에도 타깃이 내보내는 응답 크기는 그대로입니다. 수집과 파싱 부하까지 줄이려면 응답에 담긴 메트릭을 살펴봐야 합니다. 확인한 응답에서는 Istio 사이드카의 히스토그램 버킷과 반복되는 라벨 문자열이 큰 비중을 차지했습니다.

다음에는 사용하지 않는 히스토그램 버킷과 중복 정보를 담은 라벨을 검토합니다. 수집 뒤 metric relabel로 버리면 타깃 → agent 전송은 이미 발생한 상태입니다. 타깃 → agent 전송량까지 줄이려면 타깃이 내보내는 응답 자체를 줄이거나 압축해야 합니다.

Istio는 파드 annotation으로 메트릭 응답 압축을 켤 수 있습니다. 분할 뒤에는 응답이 AZ를 넘지 않아 전송 쪽 이득이 작고, vmagent가 압축을 푸는 데 CPU가 더 들어 우선순위를 낮췄습니다.

응답을 바꾸기 전에는 해당 메트릭을 사용하는 대시보드와 알림부터 확인해야 합니다. 라벨을 변경한다면 전환 때 겪은 시리즈 변경 문제도 함께 검증해야 합니다.

AZ를 건너면 지연과 대역폭이 어떻게 달라지는지는 부록 A에 atomai kubernetes-docs의 실측으로 보충했습니다.

관련 문서: 스택 구성 · vmagent 전송 튜닝 · 자기감시 메트릭 · 저장 구조에서 바꿀 것

마지막 수정 일자