LabHub
学习 学习路径 课程

Envoy 内部结构

从五百个数字里只取你要的

在 LabHub 中继续学习

한국어 원문으로 표시합니다.

목표

통계 이름의 구조를 세 갈래로 나눠 보고, 꺼내는 법과 쪼개는 규칙과 덜어내는 법을 차례로 익힌 뒤, 이름을 바꿨을 때 무엇이 사라지는지 직접 확인한다.

왜 중요한가

통계는 대시보드와 알림이 딛고 서 있는 바닥이다. 그런데 그 바닥은 이름으로 되어 있어서, 이름의 규칙을 모르면 /stats 에서 본 값을 대시보드 질의로 옮기지 못하고, 이름을 가볍게 바꿨다가 그래프를 통째로 비운다. 여기에 더해 카운터와 게이지를 구분하지 못하면 '되돌렸는데 안 바뀐다' 에서 막히고, 제외 목록의 성질을 모르면 '필요해지면 그때 켜지' 라고 미뤘다가 정작 필요한 순간에 과거 값이 없는 것을 알게 된다.

단계

  1. 업스트림 둘을 띄우세요 — 8093ok, 8094fail. /root/envd-stats/stats.yamlstat_prefixshop 인 리스너와 클러스터 good·bad 를 두고 띄우세요(관리 9971, 리스너 127.0.0.1:10071). /hello 를 다섯 번, /bad/x 를 한 번 요청한 뒤 /root/envd-stats/01-names.txtcluster=·http=·listener= 세 줄을 적으세요 — 각각 cluster.good.upstream_rq_total, http.shop.downstream_rq_total, 그 리스너의 downstream_cx_total 통계의 이름 전체입니다.
  2. /statsfilter 를 붙여 upstream_rq_total 이 든 통계만 뽑고, format=json 을 함께 붙여 /root/envd-stats/02-filter.json 에 저장하세요. 그리고 /root/envd-stats/02-filter.txttotal_stats=(필터 없이 받은 줄 수)와 matched=(필터로 좁힌 통계 개수) 두 줄을 적으세요.
  3. /stats/prometheus 를 받아 /root/envd-stats/03-prom.txtcluster.good.upstream_rq_total 에 해당하는 줄만 저장하세요. 그리고 /root/envd-stats/03-prom.mapenvoy_name=(프로메테우스에서의 지표 이름), label_key=(클러스터 이름이 담긴 라벨의 열쇠), value=(그 값) 세 줄을 적으세요.
  4. /reset_counters 를 POST 한 뒤 두 통계를 다시 읽어 /root/envd-stats/04-reset.txtcounter_before=·counter_after=(cluster.good.upstream_rq_total), gauge_before=·gauge_after=(cluster.good.membership_total) 네 줄을 적으세요.
  5. /root/envd-stats/stats-tags.yaml 을 만드세요 — stats.yaml 과 같되 최상위에 stats_config.stats_tags 를 두어 태그 이름 envd_cluster 를 정규식 ^cluster\.((.+?)\.) 로 뽑습니다. 띄우고 /hello 를 두 번 요청한 뒤 /stats/prometheus 에서 envd_cluster 라벨이 붙은 줄 하나를 /root/envd-stats/05-tags.txt 에 저장하세요.
  6. /root/envd-stats/stats-trim.yaml 을 만드세요 — stats_config.stats_matcher.exclusion_list 로 접두사 cluster.bad. 인 통계를 제외합니다. 띄운 뒤 /root/envd-stats/06-trim.txtbefore=(5단계 설정에서의 전체 통계 줄 수), after=(이 설정에서의 줄 수), bad_stats=(이 설정에서 cluster.bad. 로 시작하는 줄 수) 세 줄을 적으세요.
  7. /root/envd-stats/stats-rename.yaml 을 만드세요 — 1단계 설정에서 stat_prefixshop 에서 checkout 으로 바꾼 것입니다. 띄우고 /hello 를 두 번 요청한 뒤 /root/envd-stats/07-rename.txtold_prefix_stats=(http.shop. 로 시작하는 통계 줄 수), new_prefix_stats=(http.checkout. 로 시작하는 줄 수), new_rq_total=(http.checkout.downstream_rq_total 의 값) 세 줄을 적으세요.
  8. /root/envd-stats/08-report.mdcounter_after_reset=·gauge_after_reset=(4단계), prom_label=(5단계에서 더한 태그 이름), trim_removed=(6단계의 before 에서 after 를 뺀 값), renamed_lost=(7단계에서 옛 접두사 통계가 사라졌으면 yes) 다섯 줄을 적고, 그 아래 배운 것을 네 줄 이상 적으세요.

참고

이름은 세 갈래로 시작한다

업스트림 둘을 띄우세요 — 8093ok, 8094fail. /root/envd-stats/stats.yamlstat_prefixshop 인 리스너와 클러스터 good·bad 를 두고 띄우세요(관리 9971, 리스너 127.0.0.1:10071). /hello 를 다섯 번, /bad/x 를 한 번 요청한 뒤 /root/envd-stats/01-names.txtcluster=·http=·listener= 세 줄을 적으세요 — 각각 cluster.good.upstream_rq_total, http.shop.downstream_rq_total, 그 리스너의 downstream_cx_total 통계의 이름 전체입니다.

Envoy 의 통계 이름은 무엇에 대한 숫자인지를 접두사로 밝힙니다. cluster. 는 업스트림 쪽, http. 는 그 HTTP 연결 관리자가 처리한 요청 쪽, listener. 는 소켓 쪽입니다. 같은 요청 하나가 세 군데에서 각각 세어지므로, 세 숫자가 어긋날 때 그 차이가 바로 단서가 됩니다. 리스너 이름에는 주소와 포트가 들어가는데 점 대신 밑줄이 쓰이는 자리가 있으니 직접 확인하세요.

오백 개 중에서 필요한 것만 꺼낸다

/statsfilter 를 붙여 upstream_rq_total 이 든 통계만 뽑고, format=json 을 함께 붙여 /root/envd-stats/02-filter.json 에 저장하세요. 그리고 /root/envd-stats/02-filter.txttotal_stats=(필터 없이 받은 줄 수)와 matched=(필터로 좁힌 통계 개수) 두 줄을 적으세요.

통계는 기본 설정에서도 오백 개가 넘습니다. 그래서 관리 포트에는 질의 파라미터가 있습니다 — ?filter= 는 정규식이고 ?format=json 은 기계가 읽을 모양으로 바꿉니다. 둘은 & 로 함께 쓸 수 있습니다. 셸에서는 ?& 가 특수 문자이므로 주소 전체를 따옴표로 감싸세요. JSON 쪽 개수는 jq '.stats | length' 로 셉니다.

같은 값이 다른 이름으로 나간다

/stats/prometheus 를 받아 /root/envd-stats/03-prom.txtcluster.good.upstream_rq_total 에 해당하는 줄만 저장하세요. 그리고 /root/envd-stats/03-prom.mapenvoy_name=(프로메테우스에서의 지표 이름), label_key=(클러스터 이름이 담긴 라벨의 열쇠), value=(그 값) 세 줄을 적으세요.

프로메테우스에는 '점으로 이어 붙인 긴 이름' 이라는 개념이 없습니다. 지표 이름과 라벨 집합으로 표현하지요. 그래서 Envoy 는 내보낼 때 이름을 쪼갭니다cluster.good.upstream_rq_total 은 지표 이름 하나와 클러스터 이름을 담은 라벨로 나뉩니다. 이 규칙을 알아야 /stats 에서 본 이름을 대시보드 질의로 옮길 수 있습니다. 라벨은 중괄호 안에 열쇠="값" 으로 들어 있습니다.

되돌리는 단추는 절반에만 듣는다

/reset_counters 를 POST 한 뒤 두 통계를 다시 읽어 /root/envd-stats/04-reset.txtcounter_before=·counter_after=(cluster.good.upstream_rq_total), gauge_before=·gauge_after=(cluster.good.membership_total) 네 줄을 적으세요.

통계에는 종류가 있습니다. 카운터는 계속 늘기만 하는 누적값이고, 게이지는 지금 이 순간의 상태이며, 히스토그램은 값의 분포입니다. /reset_counters 는 이름 그대로 카운터만 0 으로 되돌립니다 — 게이지는 '지금 성한 서버가 몇 대인가' 같은 현재 상태라 되돌릴 것이 없습니다. 이 차이를 모르면 '되돌렸는데 값이 안 바뀐다' 에서 막힙니다. POST 는 curl -X POST 로 보냅니다.

이름을 쪼개는 규칙을 직접 정한다

/root/envd-stats/stats-tags.yaml 을 만드세요 — stats.yaml 과 같되 최상위에 stats_config.stats_tags 를 두어 태그 이름 envd_cluster 를 정규식 ^cluster\.((.+?)\.) 로 뽑습니다. 띄우고 /hello 를 두 번 요청한 뒤 /stats/prometheus 에서 envd_cluster 라벨이 붙은 줄 하나를 /root/envd-stats/05-tags.txt 에 저장하세요.

기본 태그 규칙은 Envoy 가 이미 여럿 들고 있습니다(클러스터 이름·리스너 주소 등). 거기에 규칙을 더하면 내 조직의 이름 규칙을 라벨로 뽑아낼 수 있습니다 — 예를 들어 클러스터 이름에 팀 이름을 접두사로 붙여 두었다면 그것만 따로 라벨로 만들 수 있고, 그러면 대시보드에서 팀별로 묶어 볼 수 있습니다. 정규식의 첫 번째 괄호가 이름에서 잘라낼 부분이고 두 번째 괄호가 라벨 값입니다. 필드 이름은 stats_tags 입니다 (stat_tags 가 아닙니다).

내보내지 않을 것을 고른다

/root/envd-stats/stats-trim.yaml 을 만드세요 — stats_config.stats_matcher.exclusion_list 로 접두사 cluster.bad. 인 통계를 제외합니다. 띄운 뒤 /root/envd-stats/06-trim.txtbefore=(5단계 설정에서의 전체 통계 줄 수), after=(이 설정에서의 줄 수), bad_stats=(이 설정에서 cluster.bad. 로 시작하는 줄 수) 세 줄을 적으세요.

통계는 메모리를 먹고, 프로메테우스로 내보내면 시계열 수만큼 저장 비용이 됩니다. 클러스터가 수백 개인 프록시에서는 이 숫자가 금방 감당하기 어려워집니다. 그래서 내보낼 것을 고르는 장치가 있습니다 — 제외 목록이나 포함 목록으로 접두사·정확한 이름·정규식을 지정합니다. 주의할 점은 제외된 통계는 화면에서 사라지는 것이 아니라 아예 기록되지 않는다는 것입니다. 필요해진 뒤에 되살려도 그 사이의 값은 없습니다.

낱말 하나를 바꾸면 대시보드가 빈다

/root/envd-stats/stats-rename.yaml 을 만드세요 — 1단계 설정에서 stat_prefixshop 에서 checkout 으로 바꾼 것입니다. 띄우고 /hello 를 두 번 요청한 뒤 /root/envd-stats/07-rename.txtold_prefix_stats=(http.shop. 로 시작하는 통계 줄 수), new_prefix_stats=(http.checkout. 로 시작하는 줄 수), new_rq_total=(http.checkout.downstream_rq_total 의 값) 세 줄을 적으세요.

stat_prefix 는 이름을 위한 값이라 트래픽에는 아무 영향이 없습니다. 그래서 리팩터링하다가 가볍게 바꾸기 쉬운데, 그 순간 그 접두사를 쓰던 모든 대시보드와 알림이 빈 그래프가 됩니다. 게다가 값이 0 으로 떨어지는 것이 아니라 시계열 자체가 사라지므로, '데이터 없음' 을 장애로 다루지 않는 알림이라면 아무도 모릅니다. 이름은 인터페이스다 — 바꿀 때는 쓰는 쪽을 먼저 찾아야 합니다.

통계 운영 메모를 남긴다

/root/envd-stats/08-report.mdcounter_after_reset=·gauge_after_reset=(4단계), prom_label=(5단계에서 더한 태그 이름), trim_removed=(6단계의 before 에서 after 를 뺀 값), renamed_lost=(7단계에서 옛 접두사 통계가 사라졌으면 yes) 다섯 줄을 적고, 그 아래 배운 것을 네 줄 이상 적으세요.

이 메모는 다음에 대시보드를 만들거나 프록시 설정을 리팩터링할 때 자기가 읽을 글입니다. 특히 마지막 줄은 '이름은 인터페이스다' 라는 규칙으로 적어 두면 좋습니다 — 값은 앞 단계에서 만든 파일에서 가져오세요.