Grafana์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ฐœ๋ฐœ: ๋น…์ƒท์˜ ์—ญ์‚ฌ

์•ˆ๋…•ํ•˜์„ธ์š” ์—ฌ๋Ÿฌ๋ถ„! ๋ช‡ ๋‹ฌ ์ „, ์šฐ๋ฆฌ๋Š” ์ƒˆ๋กœ์šด ์˜คํ”ˆ ์†Œ์Šค ํ”„๋กœ์ ํŠธ์ธ Kubernetes ๋ชจ๋‹ˆํ„ฐ๋ง์šฉ Grafana ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ํ”„๋กœ๋•์…˜์— ์ถœ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. DevOpsProdigy KubeGraf. ํ”Œ๋Ÿฌ๊ทธ์ธ ์†Œ์Šค ์ฝ”๋“œ๋Š” ๋‹ค์Œ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. GitHub์˜ ๊ณต๊ฐœ ์ €์žฅ์†Œ. ๊ทธ๋ฆฌ๊ณ  ์ด ๊ธ€์—์„œ๋Š” ์šฐ๋ฆฌ๊ฐ€ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์–ด๋–ป๊ฒŒ ๋งŒ๋“ค์—ˆ๋Š”์ง€, ์–ด๋–ค ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ–ˆ๋Š”์ง€, ๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ ์–ด๋–ค ํ•จ์ •์— ๋น ์กŒ๋Š”์ง€์— ๋Œ€ํ•œ ์ด์•ผ๊ธฐ๋ฅผ ์—ฌ๋Ÿฌ๋ถ„๊ณผ ๊ณต์œ ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๊ฐ‘์‹œ๋‹ค!

ํŒŒํŠธ 0 - ์ž…๋ฌธ: ์–ด๋–ป๊ฒŒ ์ด ์ง€์ ์— ๋„๋‹ฌํ–ˆ๋‚˜์š”?

Grafan์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ž์ฒด์ ์œผ๋กœ ์ž‘์„ฑํ•˜๋ ค๋Š” ์•„์ด๋””์–ด๋Š” ์šฐ์—ฐํžˆ ๋– ์˜ค๋ฅธ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ ํšŒ์‚ฌ๋Š” 10๋…„ ๋„˜๊ฒŒ ๋‹ค์–‘ํ•œ ์ˆ˜์ค€์˜ ๋ณต์žก์„ฑ์„ ์ง€๋‹Œ ์›น ํ”„๋กœ์ ํŠธ๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋งํ•ด ์™”์Šต๋‹ˆ๋‹ค. ๊ทธ ๋™์•ˆ ์šฐ๋ฆฌ๋Š” ๋‹ค์–‘ํ•œ ๋ชจ๋‹ˆํ„ฐ๋ง ์‹œ์Šคํ…œ์„ ํ™œ์šฉํ•˜๋ฉด์„œ ๋งŽ์€ ์ „๋ฌธ์ง€์‹๊ณผ ํฅ๋ฏธ๋กœ์šด ์‚ฌ๋ก€, ๊ฒฝํ—˜์„ ์ถ•์ ํ•ด์™”์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์–ด๋Š ์‹œ์ ์—์„œ ์šฐ๋ฆฌ๋Š” ์Šค์Šค๋กœ์—๊ฒŒ ์ด๋ ‡๊ฒŒ ๋ฌผ์—ˆ์Šต๋‹ˆ๋‹ค. "Kubernetes๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜์—ฌ "์„ค์ •ํ•˜๊ณ  ์žŠ์–ด๋ฒ„๋ฆฌ๋„๋ก" ํ•˜๋Š” ๋งˆ๋ฒ•์˜ ๋„๊ตฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?". ๋ฌผ๋ก  k8s ๋ชจ๋‹ˆํ„ฐ๋ง์„ ์œ„ํ•œ ์—…๊ณ„ ํ‘œ์ค€์€ ์˜ค๋žซ๋™์•ˆ ํ”„๋กœ๋ฉ”ํ…Œ์šฐ์Šค + ๊ทธ๋ผํŒŒ๋‚˜ ์กฐํ•ฉ. ๊ทธ๋ฆฌ๊ณ  ์ด ์Šคํƒ์„ ์œ„ํ•œ ๊ธฐ์„ฑ ์†”๋ฃจ์…˜์œผ๋กœ prometheus-operator, kubernetes-mixin ๋Œ€์‹œ๋ณด๋“œ ์„ธํŠธ, grafana-kubernetes-app ๋“ฑ ๋‹ค์–‘ํ•œ ์ข…๋ฅ˜์˜ ๋„๊ตฌ ์„ธํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

grafana-kubernetes-app ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ์šฐ๋ฆฌ์—๊ฒŒ ๊ฐ€์žฅ ํฅ๋ฏธ๋กœ์šด ์˜ต์…˜์ธ ๊ฒƒ ๊ฐ™์•˜์ง€๋งŒ XNUMX๋…„ ๋„˜๊ฒŒ ์ง€์›๋˜์ง€ ์•Š์•˜์œผ๋ฉฐ ๊ฒŒ๋‹ค๊ฐ€ ์ƒˆ ๋ฒ„์ „์˜ node-exporter ๋ฐ kube-state-metrics์™€๋„ ์ž‘๋™ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์–ด๋Š ์ˆœ๊ฐ„ ์šฐ๋ฆฌ๋Š” โ€œ์šฐ๋ฆฌ ์Šค์Šค๋กœ ๊ฒฐ์ •์„ ๋‚ด๋ ค์•ผ ํ•˜์ง€ ์•Š์„๊นŒ?โ€๋ผ๊ณ  ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ”Œ๋Ÿฌ๊ทธ์ธ์— ๊ตฌํ˜„ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•œ ์•„์ด๋””์–ด๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

  • "์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋งต" ์‹œ๊ฐํ™”: ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋„ค์ž„์ŠคํŽ˜์ด์Šค, ๋ฐฐํฌ๋ณ„๋กœ ๊ทธ๋ฃนํ™”ํ•˜์—ฌ ํŽธ๋ฆฌํ•˜๊ฒŒ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
  • "๋ฐฐํฌ - ์„œ๋น„์Šค(+ํฌํŠธ)"์™€ ๊ฐ™์€ ์—ฐ๊ฒฐ ์‹œ๊ฐํ™”.
  • ํด๋Ÿฌ์Šคํ„ฐ ๋…ธ๋“œ ์ „์ฒด์— ํด๋Ÿฌ์Šคํ„ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ๋ฅผ ์‹œ๊ฐํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • Prometheus ๋ฐ k8s API ์„œ๋ฒ„์™€ ๊ฐ™์€ ์—ฌ๋Ÿฌ ์†Œ์Šค์—์„œ ์ธก์ •ํ•ญ๋ชฉ ๋ฐ ์ •๋ณด๋ฅผ ์ˆ˜์ง‘ํ•ฉ๋‹ˆ๋‹ค.
  • ์ธํ”„๋ผ ๋ถ€๋ถ„(CPU ์‹œ๊ฐ„, ๋ฉ”๋ชจ๋ฆฌ, ๋””์Šคํฌ ํ•˜์œ„ ์‹œ์Šคํ…œ, ๋„คํŠธ์›Œํฌ ์‚ฌ์šฉ)๊ณผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ์ง(์ƒํƒœ ํฌ๋“œ, ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ณต์ œ๋ณธ ์ˆ˜, ํ™œ์„ฑ/์ค€๋น„ ํ…Œ์ŠคํŠธ ํ†ต๊ณผ์— ๋Œ€ํ•œ ์ •๋ณด)์„ ๋ชจ๋‘ ๋ชจ๋‹ˆํ„ฐ๋งํ•ฉ๋‹ˆ๋‹ค.

ํŒŒํŠธ 1: "Grafana ํ”Œ๋Ÿฌ๊ทธ์ธ"์ด๋ž€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

๊ธฐ์ˆ ์ ์ธ ๊ด€์ ์—์„œ Grafana์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ์€ Grafana ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ„ฐ๋ฆฌ(/var/grafana/ํ”Œ๋Ÿฌ๊ทธ์ธ/ /dist/module.js) SystemJS ๋ชจ๋“ˆ๋กœ ๋กœ๋“œ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด ๋””๋ ‰ํ„ฐ๋ฆฌ์—๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์— ๋Œ€ํ•œ ๋ชจ๋“  ๋ฉ”ํƒ€ ์ •๋ณด(์ด๋ฆ„, ๋ฒ„์ „, ํ”Œ๋Ÿฌ๊ทธ์ธ ์œ ํ˜•, ์ €์žฅ์†Œ/์‚ฌ์ดํŠธ/๋ผ์ด์„ผ์Šค ๋งํฌ, ์ข…์†์„ฑ ๋“ฑ)๊ฐ€ ํฌํ•จ๋œplugin.json ํŒŒ์ผ์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Grafana์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ฐœ๋ฐœ: ๋น…์ƒท์˜ ์—ญ์‚ฌ
module.ts

Grafana์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ฐœ๋ฐœ: ๋น…์ƒท์˜ ์—ญ์‚ฌ
ํ”Œ๋Ÿฌ๊ทธ์ธ.json

์Šคํฌ๋ฆฐ์ƒท์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด ์šฐ๋ฆฌ๋Š”plugin.type = app์„ ์ง€์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. Grafana์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ์„ธ ๊ฐ€์ง€ ์œ ํ˜•์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํŒจ๋„: ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ์œ ํ˜•์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ - ๋‹ค์–‘ํ•œ ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์ธก์ •ํ•ญ๋ชฉ์„ ์‹œ๊ฐํ™”ํ•˜๋Š” ํŒจ๋„์ž…๋‹ˆ๋‹ค.
๋ฐ์ดํ„ฐ ์†Œ์Šค: ์ผ๋ถ€ ๋ฐ์ดํ„ฐ ์†Œ์Šค(์˜ˆ: Prometheus-datasource, ClickHouse-datasource, ElasticSearch-datasource)์— ๋Œ€ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ ์ปค๋„ฅํ„ฐ์ž…๋‹ˆ๋‹ค.
์•ฑ: Grafana ๋‚ด์—์„œ ์ž์‹ ๋งŒ์˜ ํ”„๋ŸฐํŠธ์—”๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์ถ•ํ•˜๊ณ , ์ž์‹ ๋งŒ์˜ HTML ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค๊ณ , ๋ฐ์ดํ„ฐ ์†Œ์Šค์— ์ˆ˜๋™์œผ๋กœ ์•ก์„ธ์Šคํ•˜์—ฌ ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์‹œ๊ฐํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ, ๋‹ค๋ฅธ ์œ ํ˜•(๋ฐ์ดํ„ฐ์†Œ์Šค, ํŒจ๋„)์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ๊ณผ ๋‹ค์–‘ํ•œ ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ์ข…์†์„ฑ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Grafana์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ฐœ๋ฐœ: ๋น…์ƒท์˜ ์—ญ์‚ฌ
type=app์ธ ํ”Œ๋Ÿฌ๊ทธ์ธ ์ข…์†์„ฑ์˜ ์˜ˆ.

ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋กœ JavaScript์™€ TypeScript๋ฅผ ๋ชจ๋‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์ €ํฌ๋Š” ์ด๋ฅผ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค). ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ์œ ํ˜•์˜ hello-world ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์œ„ํ•œ ์ค€๋น„ ๋งํฌ๋ฅผ ์ฐพ์•„๋ณด์„ธ์š”: ์ด ์ €์žฅ์†Œ์—๋Š” ์‚ฌ์ „ ์„ค์น˜ ๋ฐ ๊ตฌ์„ฑ๋œ ๋นŒ๋”๊ฐ€ ํฌํ•จ๋œ ์ˆ˜๋งŽ์€ ์Šคํƒ€ํ„ฐ ํŒฉ(React์— ์‹คํ—˜์ ์ธ ํ”Œ๋Ÿฌ๊ทธ์ธ ์˜ˆ์ œ๋„ ์žˆ์Œ)์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

2๋ถ€: ๋กœ์ปฌ ํ™˜๊ฒฝ ์ค€๋น„

ํ”Œ๋Ÿฌ๊ทธ์ธ ์ž‘์—…์„ ์œ„ํ•ด์„œ๋Š” ๋‹น์—ฐํžˆ prometheus, node-exporter, kube-state-metrics, grafana ๋“ฑ ๋ชจ๋“  ์‚ฌ์ „ ์„ค์น˜๋œ ๋„๊ตฌ๊ฐ€ ํฌํ•จ๋œ kubernetes ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ํ™˜๊ฒฝ์€ ๋น ๋ฅด๊ณ  ์‰ฝ๊ณ  ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์„ค์ •๋˜์–ด์•ผ ํ•˜๋ฉฐ, ํ•ซ ๋ฆฌ๋กœ๋“œ๋ฅผ ๋ณด์žฅํ•˜๋ ค๋ฉด Grafana ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ๊ฐœ๋ฐœ์ž ์ปดํ“จํ„ฐ์—์„œ ์ง์ ‘ ๋งˆ์šดํŠธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ ์ƒ๊ฐ์— ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๋ฅผ ๋กœ์ปฌ์—์„œ ์ž‘์—…ํ•˜๋Š” ๊ฐ€์žฅ ํŽธ๋ฆฌํ•œ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋ฏธ๋‹ˆํ๋ธŒ. ๋‹ค์Œ ๋‹จ๊ณ„๋Š” prometheus-operator๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Prometheus + Grafana ์กฐํ•ฉ์„ ์„ค์น˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•ˆ์— ์ด ๊ธฐ์‚ฌ minikube์— prometheus-operator๋ฅผ ์„ค์น˜ํ•˜๋Š” ๊ณผ์ •์„ ์ž์„ธํžˆ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ์ง€์†์„ฑ์„ ํ™œ์„ฑํ™”ํ•˜๋ ค๋ฉด ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ง€์†์„ฑ : ์‚ฌ์‹ค charts/grafana/values.yaml ํŒŒ์ผ์—์„œ ์ž์ฒด PV ๋ฐ PVC๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  persistence.existingClaim ๋งค๊ฐœ๋ณ€์ˆ˜์— ์ด๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

์ตœ์ข… Minikube ์‹คํ–‰ ์Šคํฌ๋ฆฝํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

minikube start --kubernetes-version=v1.13.4 --memory=4096 --bootstrapper=kubeadm --extra-config=scheduler.address=0.0.0.0 --extra-config=controller-manager.address=0.0.0.0
minikube mount 
/home/sergeisporyshev/Projects/Grafana:/var/grafana --gid=472 --uid=472 --9p-version=9p2000.L

ํŒŒํŠธ 3: ์‹ค์ œ ๊ฐœ๋ฐœ

๊ฐ์ฒด ๋ชจ๋ธ

ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ตฌํ˜„์„ ์ค€๋น„ํ•˜๋ฉด์„œ ์šฐ๋ฆฌ๋Š” ์ž‘์—…ํ•  ๋ชจ๋“  ๊ธฐ๋ณธ Kubernetes ์—”ํ„ฐํ‹ฐ๋ฅผ TypeScript ํด๋ž˜์Šค ํ˜•์‹(pod, ๋ฐฐํฌ, daemonset, statefulset, job, cronjob, ์„œ๋น„์Šค, ๋…ธ๋“œ, ๋„ค์ž„์ŠคํŽ˜์ด์Šค)์œผ๋กœ ์„ค๋ช…ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฐ ํด๋ž˜์Šค๋Š” ์ƒ์„ฑ์ž, ์†Œ๋ฉธ์ž, ๊ฐ€์‹œ์„ฑ์„ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ์ „ํ™˜ํ•˜๊ธฐ ์œ„ํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๊ณตํ†ต BaseModel ํด๋ž˜์Šค์—์„œ ์ƒ์†๋ฉ๋‹ˆ๋‹ค. ๊ฐ ํด๋ž˜์Šค๋Š” ๋‹ค๋ฅธ ์—”ํ„ฐํ‹ฐ์™€์˜ ์ค‘์ฒฉ ๊ด€๊ณ„(์˜ˆ: ๋ฐฐํฌ ์œ ํ˜• ์—”ํ„ฐํ‹ฐ์— ๋Œ€ํ•œ Pod ๋ชฉ๋ก)๋ฅผ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

import {Pod} from "./pod";
import {Service} from "./service";
import {BaseModel} from './traits/baseModel';

export class Deployment extends BaseModel{
   pods: Array<Pod>;
   services: Array<Service>;

   constructor(data: any){
       super(data);
       this.pods = [];
       this.services = [];
   }
}

getter ๋ฐ setter์˜ ๋„์›€์œผ๋กœ ํ•„์š”ํ•œ ์—”ํ„ฐํ‹ฐ ๋ฉ”ํŠธ๋ฆญ์„ ํŽธ๋ฆฌํ•˜๊ณ  ์ฝ๊ธฐ ์‰ฌ์šด ํ˜•์‹์œผ๋กœ ํ‘œ์‹œํ•˜๊ฑฐ๋‚˜ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํ• ๋‹น ๊ฐ€๋Šฅํ•œ CPU ๋…ธ๋“œ์˜ ํ˜•์‹ํ™”๋œ ์ถœ๋ ฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

get cpuAllocatableFormatted(){
   let cpu = this.data.status.allocatable.cpu;
   if(cpu.indexOf('m') > -1){
       cpu = parseInt(cpu)/1000;
   }
   return cpu;
}

ํŽ˜์ด์ง€

๋ชจ๋“  ํ”Œ๋Ÿฌ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ชฉ๋ก์€ ์ฒ˜์Œ์— ์ข…์†์„ฑ ์„น์…˜์˜ pluing.json์— ์„ค๋ช…๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

Grafana์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ฐœ๋ฐœ: ๋น…์ƒท์˜ ์—ญ์‚ฌ

๊ฐ ํŽ˜์ด์ง€์˜ ๋ธ”๋ก์—๋Š” ํŽ˜์ด์ง€ ์ด๋ฆ„์„ ํ‘œ์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์ด ํŽ˜์ด์ง€์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ์Šฌ๋Ÿฌ๊ทธ๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค). ์ด ํŽ˜์ด์ง€์˜ ์ž‘์—…์„ ๋‹ด๋‹นํ•˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ์˜ ์ด๋ฆ„(๊ตฌ์„ฑ ์š”์†Œ ๋ชฉ๋ก์€ module.ts๋กœ ๋‚ด๋ณด๋‚ด์ง‘๋‹ˆ๋‹ค) ์ด ํŽ˜์ด์ง€ ์ž‘์—…์ด ๊ฐ€๋Šฅํ•œ ์‚ฌ์šฉ์ž ์—ญํ• ๊ณผ ์‚ฌ์ด๋“œ๋ฐ”์— ๋Œ€ํ•œ ํƒ์ƒ‰ ์„ค์ •์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

ํŽ˜์ด์ง€ ์ž‘์—…์„ ๋‹ด๋‹นํ•˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ์—์„œ templateUrl์„ ์„ค์ •ํ•˜๊ณ  ์—ฌ๊ธฐ์— ๋งˆํฌ์—…์ด ํฌํ•จ๋œ html ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ์ „๋‹ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ปจํŠธ๋กค๋Ÿฌ ๋‚ด๋ถ€์—์„œ๋Š” ์ข…์†์„ฑ ์ฃผ์ž…์„ ํ†ตํ•ด ์ตœ๋Œ€ 2๊ฐœ์˜ ์ค‘์š”ํ•œ ๊ฐ๋„ ์„œ๋น„์Šค์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • backendSrv - Grafana API ์„œ๋ฒ„์™€์˜ ์ƒํ˜ธ ์ž‘์šฉ์„ ์ œ๊ณตํ•˜๋Š” ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค.
  • datasourceSrv - Grafana์— ์„ค์น˜๋œ ๋ชจ๋“  ๋ฐ์ดํ„ฐ ์†Œ์Šค์™€์˜ ๋กœ์ปฌ ์ƒํ˜ธ ์ž‘์šฉ์„ ์ œ๊ณตํ•˜๋Š” ์„œ๋น„์Šค(์˜ˆ: .getAll() ๋ฉ”์„œ๋“œ) - ์„ค์น˜๋œ ๋ชจ๋“  ๋ฐ์ดํ„ฐ ์†Œ์Šค ๋ชฉ๋ก์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ) - ํŠน์ • ๋ฐ์ดํ„ฐ ์†Œ์Šค์˜ ์ธ์Šคํ„ด์Šค ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

Grafana์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ฐœ๋ฐœ: ๋น…์ƒท์˜ ์—ญ์‚ฌ

Grafana์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ฐœ๋ฐœ: ๋น…์ƒท์˜ ์—ญ์‚ฌ

Grafana์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ฐœ๋ฐœ: ๋น…์ƒท์˜ ์—ญ์‚ฌ

ํŒŒํŠธ 4: ๋ฐ์ดํ„ฐ ์†Œ์Šค

Grafana์˜ ๊ด€์ ์—์„œ ๋ณด๋ฉด datasource๋Š” ๋‹ค๋ฅธ ๋ชจ๋“  ํ”Œ๋Ÿฌ๊ทธ์ธ๊ณผ ์™„์ „ํžˆ ๋™์ผํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ์ž…๋‹ˆ๋‹ค. ์ž์ฒด ์ง„์ž…์  module.js๊ฐ€ ์žˆ๊ณ  ๋ฉ”ํƒ€ ์ •๋ณด๊ฐ€ ์žˆ๋Š” ํŒŒ์ผ์ธplugin.json์ด ์žˆ์Šต๋‹ˆ๋‹ค. type = app์ธ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๊ฐœ๋ฐœํ•  ๋•Œ ๊ธฐ์กด ๋ฐ์ดํ„ฐ ์†Œ์Šค(์˜ˆ: prometheus-datasource)์™€ ์ž์ฒด ๋ฐ์ดํ„ฐ ์†Œ์Šค(dist/datasource/*)์— ์ง์ ‘ ์ €์žฅํ•˜๊ฑฐ๋‚˜ ์ข…์†์„ฑ์œผ๋กœ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋Š” ์ž์ฒด ๋ฐ์ดํ„ฐ ์†Œ์Šค์™€ ์ƒํ˜ธ ์ž‘์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ ์ฝ”๋“œ์™€ ํ•จ๊ป˜ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ฐ์ดํ„ฐ ์†Œ์Šค ์ธ์Šคํ„ด์Šค ๊ตฌ์„ฑ ํŽ˜์ด์ง€์— ์‚ฌ์šฉ๋  config.html ํ…œํ”Œ๋ฆฟ๊ณผ ConfigCtrl ์ปจํŠธ๋กค๋Ÿฌ์™€ ๋ฐ์ดํ„ฐ ์†Œ์Šค์˜ ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ์ดํ„ฐ ์†Œ์Šค ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

KubeGraf ํ”Œ๋Ÿฌ๊ทธ์ธ์—์„œ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค ๊ด€์ ์—์„œ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋Š” ๋‹ค์Œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” kubernetes ํด๋Ÿฌ์Šคํ„ฐ์˜ ์ธ์Šคํ„ด์Šค์ž…๋‹ˆ๋‹ค(์†Œ์Šค ์ฝ”๋“œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ). ๋งํฌ):

  • k8s API ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘(๋„ค์ž„์ŠคํŽ˜์ด์Šค, ๋ฐฐํฌ ๋ชฉ๋ก ๊ฐ€์ ธ์˜ค๊ธฐ...)
  • prometheus-datasource(๊ฐ ํŠน์ • ํด๋Ÿฌ์Šคํ„ฐ์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ค์ •์—์„œ ์„ ํƒ๋จ)์— ๋Œ€ํ•œ ์š”์ฒญ์„ ํ”„๋ก์‹œํ•˜๊ณ  ์ •์  ํŽ˜์ด์ง€์™€ ๋Œ€์‹œ๋ณด๋“œ ๋ชจ๋‘์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ์‘๋‹ต ํ˜•์‹์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  • ์ •์  ํ”Œ๋Ÿฌ๊ทธ์ธ ํŽ˜์ด์ง€์—์„œ ๋ฐ์ดํ„ฐ ์—…๋ฐ์ดํŠธ(์„ค์ •๋œ ์ƒˆ๋กœ๊ณ ์นจ ๋นˆ๋„ ์‚ฌ์šฉ)
  • grafana-dashboards์—์„œ ํ…œํ”Œ๋ฆฟ ์‹œํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์ฟผ๋ฆฌ ์ฒ˜๋ฆฌ(metriFindQuery() ๋ฉ”์„œ๋“œ)

Grafana์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ฐœ๋ฐœ: ๋น…์ƒท์˜ ์—ญ์‚ฌ

Grafana์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ฐœ๋ฐœ: ๋น…์ƒท์˜ ์—ญ์‚ฌ

Grafana์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ฐœ๋ฐœ: ๋น…์ƒท์˜ ์—ญ์‚ฌ

  • ์ตœ์ข… k8s ํด๋Ÿฌ์Šคํ„ฐ์™€์˜ ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ.
testDatasource(){
   let url = '/api/v1/namespaces';
   let _url = this.url;
   if(this.accessViaToken)
       _url += '/__proxy';
   _url += url;
   return this.backendSrv.datasourceRequest({
       url: _url,
       method: "GET",
       headers: {"Content-Type": 'application/json'}
   })
       .then(response => {
           if (response.status === 200) {
               return {status: "success", message: "Data source is OK", title: "Success"};
           }else{
               return {status: "error", message: "Data source is not OK", title: "Error"};
           }
       }, error => {
           return {status: "error", message: "Data source is not OK", title: "Error"};
       })
}

์šฐ๋ฆฌ ์ƒ๊ฐ์— ๋˜ ๋‹ค๋ฅธ ํฅ๋ฏธ๋กœ์šด ์ ์€ ๋ฐ์ดํ„ฐ ์†Œ์Šค์— ๋Œ€ํ•œ ์ธ์ฆ ๋ฐ ๊ถŒํ•œ ๋ถ€์—ฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜์˜ ๊ตฌํ˜„์ž…๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๊ธฐ๋ณธ ์ œ๊ณต Grafana ๊ตฌ์„ฑ ์š”์†Œ datasourceHttpSettings๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ตœ์ข… ๋ฐ์ดํ„ฐ ์†Œ์Šค์— ๋Œ€ํ•œ ์•ก์„ธ์Šค๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด URL ๋ฐ ๊ธฐ๋ณธ ์ธ์ฆ/๊ถŒํ•œ ์„ค์ •(login-password ๋˜๋Š” client-cert/client-key)์„ ์ง€์ •ํ•˜์—ฌ http ๋ฐ์ดํ„ฐ ์†Œ์Šค์— ๋Œ€ํ•œ ์•ก์„ธ์Šค๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฒ ์–ด๋Ÿฌ ํ† ํฐ(k8s์˜ ์‚ฌ์‹ค์ƒ ํ‘œ์ค€)์„ ์‚ฌ์šฉํ•˜์—ฌ ์•ก์„ธ์Šค๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์•ฝ๊ฐ„์˜ ์กฐ์ •์ด ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด ๋‚ด์žฅ๋œ Grafana "ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ฒฝ๋กœ" ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ์„ ์ฐธ์กฐํ•˜์„ธ์š”). ๊ณต์‹ ๋ฌธ์„œ ํŽ˜์ด์ง€). ๋ฐ์ดํ„ฐ ์†Œ์Šค ์„ค์ •์—์„œ grafana ํ”„๋ก์‹œ ์„œ๋ฒ„๊ฐ€ ์ฒ˜๋ฆฌํ•  ๋ผ์šฐํŒ… ๊ทœ์น™ ์„ธํŠธ๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ฐ ๊ฐœ๋ณ„ ์—”๋“œํฌ์ธํŠธ์— ๋Œ€ํ•ด ํ…œํ”Œ๋ฆฟ์ด ๊ฐ€๋Šฅํ•œ ํ—ค๋” ๋˜๋Š” URL์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋Š” jsonData ๋ฐ secureJsonData ํ•„๋“œ์—์„œ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(๋น„๋ฐ€๋ฒˆํ˜ธ ๋˜๋Š” ํ† ํฐ์„ ์•”ํ˜ธํ™”๋œ ํ˜•์‹์œผ๋กœ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด). ์ด ์˜ˆ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฟผ๋ฆฌ๋Š” /__proxy/api/v1/๋„ค์ž„์ŠคํŽ˜์ด์Šค ์–‘์‹์˜ URL๋กœ ํ”„๋ก์‹œ๋ฉ๋‹ˆ๋‹ค.
Authorization: Bearer ํ—ค๋”๊ฐ€ ์žˆ๋Š” /api/v8/namespaces.

Grafana์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ฐœ๋ฐœ: ๋น…์ƒท์˜ ์—ญ์‚ฌ

Grafana์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ฐœ๋ฐœ: ๋น…์ƒท์˜ ์—ญ์‚ฌ

๋‹น์—ฐํžˆ k8s API ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ฝ๊ธฐ ์ „์šฉ ์•ก์„ธ์Šค ๊ถŒํ•œ์ด ์žˆ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ํ•„์š”ํ•˜๋ฉฐ ์ƒ์„ฑ์„ ์œ„ํ•œ ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋„ ๋‹ค์Œ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ”Œ๋Ÿฌ๊ทธ์ธ ์†Œ์Šค ์ฝ”๋“œ.

ํŒŒํŠธ 5: ์ถœ์‹œ

Grafana์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ฐœ๋ฐœ: ๋น…์ƒท์˜ ์—ญ์‚ฌ

์ž์‹ ๋งŒ์˜ Grafana ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ž‘์„ฑํ•˜๊ณ  ๋‚˜๋ฉด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ด๋ฅผ ๊ณต๊ฐœ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค๊ณ  ์‹ถ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. Grafana์—์„œ๋Š” ์—ฌ๊ธฐ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. grafana.com/grafana/plugins

๊ณต์‹ ์Šคํ† ์–ด์—์„œ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋‹ค์Œ์—์„œ PR์„ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ €์žฅ์†Œrepo.json ํŒŒ์ผ์— ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ˜ํ…์ธ ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

Grafana์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ฐœ๋ฐœ: ๋น…์ƒท์˜ ์—ญ์‚ฌ

์—ฌ๊ธฐ์„œ version์€ ํ”Œ๋Ÿฌ๊ทธ์ธ ๋ฒ„์ „์ด๊ณ , url์€ ์ €์žฅ์†Œ์— ๋Œ€ํ•œ ๋งํฌ์ด๋ฉฐ, commit์€ ํ”Œ๋Ÿฌ๊ทธ์ธ์˜ ํŠน์ • ๋ฒ„์ „์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ปค๋ฐ‹์˜ ํ•ด์‹œ์ž…๋‹ˆ๋‹ค.

์ถœ๋ ฅ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฉ‹์ง„ ๊ทธ๋ฆผ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Grafana์šฉ ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ฐœ๋ฐœ: ๋น…์ƒท์˜ ์—ญ์‚ฌ

์ด์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋Š” Readme.md, Changelog.md ๋ฐ ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ค๋ช…๊ณผ ํ•จ๊ป˜ ํ”Œ๋Ÿฌ๊ทธ์ธ.json ํŒŒ์ผ์—์„œ ์ž๋™์œผ๋กœ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

6๋ถ€: ๊ฒฐ๋ก  ๋Œ€์‹ 

์šฐ๋ฆฌ๋Š” ์ถœ์‹œ ํ›„์—๋„ ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ฐœ๋ฐœ์„ ์ค‘๋‹จํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ด์ œ ์šฐ๋ฆฌ๋Š” ํด๋Ÿฌ์Šคํ„ฐ ๋…ธ๋“œ์˜ ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๊ณ , UX๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•œ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ๋„์ž…ํ•˜๊ณ , ํด๋ผ์ด์–ธํŠธ์™€ GitHub ์‚ฌ์šฉ์ž ๋ชจ๋‘๋กœ๋ถ€ํ„ฐ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•œ ํ›„ ๋ฐ›์€ ๋งŽ์€ ์–‘์˜ ํ”ผ๋“œ๋ฐฑ์„ ์ˆ˜์ง‘ํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ท€ํ•˜์˜ ๋ฌธ์ œ๋‚˜ ๋Œ์–ด์˜ค๊ธฐ ์š”์ฒญ์„ ๋ณด๋‚ด์ฃผ์‹œ๋ฉด ๋งค์šฐ ๊ธฐ์  ๊ฒƒ์ž…๋‹ˆ๋‹ค :)

์ด ๊ธฐ์‚ฌ๊ฐ€ Grafana์™€ ๊ฐ™์€ ํ›Œ๋ฅญํ•œ ๋„๊ตฌ๋ฅผ ์ดํ•ดํ•˜๊ณ  ์•„๋งˆ๋„ ์ž์‹ ๋งŒ์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ž‘์„ฑํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!)

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€