Upgrade to Pro — share decks privately, control downloads, hide ads and more …

モニタリング入門 / Monitoring Feat. VictoriaMetrics

Cybozu
June 22, 2021

モニタリング入門 / Monitoring Feat. VictoriaMetrics

Cybozu

June 22, 2021
Tweet

More Decks by Cybozu

Other Decks in Technology

Transcript

  1. この講義のコンセプト ▶ 誰に n NecoのKubernetes環境を利⽤する開発・運⽤のメンバー ▶ 何を n モニタリングシステムの仕組みを知る n

    可視化やアラートに必要なPromQLの基本を知る n アプリケーションからメトリクスを収集する⽅法を知る n ルールに基づいてアラートを発⾏する⽅法を知る 2
  2. 3 ビジネス ü ユーザーの利⽤状況を 分析しビジネス上の意 志決定に利⽤ 運⽤ ü 問題を検出しアラート を発⾏

    ü オートスケーリング ü デプロイの⾃動化 開発 ü 性能測定 ü デバッグ ü ユーザーの利⽤状況に 応じた機能の改善 モニタリングの⽤途
  3. モニタリングシステムの構成 10 Kubernetes Node Node Node モニタリング対象 node- exporter kube-

    state- metrics cAdvisor Necoが提供するプラットフォーム 開発チームが ⽤意するもの モニタリングシステム 閲覧 アラート 開発者 収集ルール アラートルール VMStorage アプリケーション Grafana VMAgent VMAgent VMAlert AlertManager 独⾃メトリ クスの収集 保存 基本メトリ クスの収集
  4. 11 GrafanaのUI ▶ Grafana: メトリクスの可視化ツール ▶ VMAgent: メトリクスの収集 ▶ VMStorage:

    メトリクスの蓄積 ▶ VMAlert: アラートの判断 ▶ AlertManager: アラートの送信 主要コンポーネント
  5. 基本メトリクス収集のコンポーネント ▶ cAdvisor n コンテナごとのCPUやメモリ、I/Oの使⽤量などのメトリクスを収集 n https://github.com/google/cadvisor/blob/master/docs/storage/prometheus.md ▶ kube-state-metrics n

    PodやDeployment, Serviceなどのリソースのメトリクスを収集 n https://github.com/kubernetes/kube-state-metrics/tree/master/docs ▶ Node exporter n ハードウェアやOSからメトリクスを収集 n https://github.com/prometheus/node_exporter 12
  6. # HELP todo_api_requests_total A counter for requests to the wrapped

    handler. # TYPE todo_api_requests_total counter todo_api_requests_total{code="200",method="delete"} 1 todo_api_requests_total{code="200",method="get"} 4560 ・・・ # HELP todo_in_flight_requests A gauge of requests currently being served by the wrapped handler. # TYPE todo_in_flight_requests gauge todo_in_flight_requests 0 17 ラベル 値 メトリクス名 メトリクスのタイプ(後述) メトリクスの説明 メトリクスのフォーマット
  7. 18 Histogram 観測値の集計データ 例: HTTPリクエスト サイズや、リクエス トのレイテンシー Summary 観測値の集計結果 例:

    HTTPリクエスト サイズや、リクエス トのレイテンシー Gauge 現在の値を⽰す 例: ディスクの使⽤ 量、CPUの使⽤率 Counter 増加する値を⽰す 例: APIのリクエスト 数の累計、パケット の合計受信サイズ メトリクスのタイプ
  8. メトリクスはどのように蓄積されるか 19 アプリケーション metrics_a{key=value1} 123 metrics_b{key=value2} 456 VMStorage VMAgent アプリケーションは現在の

    メトリクス値のみを出⼒ 30秒周期で収集 metrics_a{key=value1,pod=A,namespace=X,instance=10.69.0.3} 123 metrics_b{key=value2 ,pod=A,namespace=X,instance=10.69.0.3} 456 ラベルを付与 (どこから取得したメトリクスか分かるようにする) metrics_a{key=value1,pod=A,namespace=X,instance=10.69.0.3} → [(0,123), (30,124) (60,125)・・・] metrics_b{key=value2 ,pod=A,namespace=X,instance=10.69.0.3} → [(0,456), (30,512) (60,675)・・・] タイムスタンプを付与して時系列データとして保存 保存
  9. よく使う関数 関数名 メトリクスタイプ 説明 absent(v instant-vector) 何でも メトリクスが存在する場合は空ベクトルを返 し、存在しない場合は値が1で⻑さ1のベクト ルを返す

    changes(v range-vector) 何でも 指定した範囲内で値が変化した回数 delta(v range-vector) gauge 指定した範囲内の最初と最後の差 increase(v range-vector) counter 指定した範囲内での増加量 rate(v range-vector) counter 指定した範囲内での秒間あたりの平均増加率 histogram_quantile (Φ scalar, b instant-vector) histogram 指定したバケットから分位数(0 ≤ φ ≤ 1)を 算出する(※後ほど詳しく解説します) 29
  10. 32 ▶ upメトリクス n 1: 起動している 0: 起動していない n なし:

    何らかの理由でメトリクスが収集できなかった up{job="todo/todo"} Query
  11. Histogramのメトリクス例 ※le: less than or equalの略 40 todo_request_duration_seconds_bucket{handler="test",method="get",le="0.25"} 534 todo_request_duration_seconds_bucket{handler="test",method="get",le="0.5"}

    1126 todo_request_duration_seconds_bucket{handler="test",method="get",le="1"} 2231 todo_request_duration_seconds_bucket{handler="test",method="get",le="2.5"} 2231 todo_request_duration_seconds_bucket{handler="test",method="get",le="5"} 2231 todo_request_duration_seconds_bucket{handler="test",method="get",le="10"} 2231 todo_request_duration_seconds_bucket{handler="test",method="get",le="+Inf"} 2231 todo_request_duration_seconds_sum{handler="test",method="get"} 1124.3332884999982 todo_request_duration_seconds_count{handler="test",method="get"} 2231 レイテンシ0.25秒以内のリクエストが534回
  12. 集計 ▶ sum, min, max, avg, count など集計をおこなう演算⼦ n https://prometheus.io/docs/prometheus/latest/querying/operators

    /#aggregation-operators ▶ byとwithoutで集計する対象のラベルを指定することができる 44
  13. 45 ▶ byで指定したラベル、もしくはwithoutで指定しなかった ラベルで集計することができる todo_api_requests_total{code=200, method=get} 100 todo_api_requests_total{code=200, method=post} 200

    todo_api_requests_total{code=500, method=get} 300 todo_api_requests_total{code=500, method=post} 400 ↓ sum(todo_api_requests_total) by (code) todo_api_requests_total{code=200} 300 todo_api_requests_total{code=500} 700 by/without
  14. 48 sum(rate(node_cpu_seconds_total sum(rate(node_cpu_seconds_total[5m])) {mode="idle"}[5m])) without(cpu) without(mode, cpu) {mode="idle",instance="10.244.1.3"} {instance="10.244.1.3"} {mode="idle",instance="10.244.1.4"}

    {instance="10.244.1.4"} {mode="idle",instance="10.244.1.5"} {instance="10.244.1.5"} modeラベルがない! ▶ 左右ですべてのラベルが⼀致するメトリクスがみつからない 場合、演算できない。 sum(rate(node_cpu_seconds_total{mode="idle"}[5m])) without(cpu) / sum(rate(node_cpu_seconds_total[5m])) without(mode, cpu) Query
  15. 49 sum(rate(node_cpu_seconds_total sum(rate(node_cpu_seconds_total[5m])) {mode="idle"}[5m])) without(cpu) without(mode, cpu) {mode="idle",instance="10.244.1.3"} {instance="10.244.1.3"} {mode="idle",instance="10.244.1.4"}

    {instance="10.244.1.4"} {mode="idle",instance="10.244.1.5"} {instance="10.244.1.5"} modeを無視してマッチ ▶ ラベルが⼀致していないメトリクス同⼠を演算する場合 n on でマッチさせるラベルを指定 n ignoring でマッチさせないラベルを指定 sum(rate(node_cpu_seconds_total{mode="idle"}[5m])) without(cpu) / ignoring(mode) sum(rate(node_cpu_seconds_total[5m])) without(mode, cpu) Query
  16. 50 kube_pod_container_status_restarts_total kube_namespace_labels {namespace="monitoring-system",pod="vmagent"} {namespace="monitoring-system",pod="vmsingle"} {namespace="monitoring-system",pod="operator"} {namespace="monitoring-system",label_team="admin"} {namespace="grafana", pod="grafana"} {namespace="grafana",

    pod="grafana-operator"} {namespace="grafana", label_team="admin"} {namespace="todo",pod="todo"} {namespace="todo",pod="request"} {namespace="todo",pod="vmagent"} {namespace="todo", label_team="user"} ▶ メトリクスが多対⼀や⼀対多の関係となる場合は、onや ignoringを指定しても演算できない。 rate(kube_pod_container_status_restarts_total[5m]) * on (namespace) kube_namespace_labels{label_team="admin"} Query
  17. 52 kube_namespace_labelsの値は必ず1なので、 かけ算をしても結果は変化しない。 {namespace="monitoring-system",pod="vmagent"} {namespace="monitoring-system",label_team="admin"} {namespace="monitoring-system",pod="vmsingle"} {namespace="monitoring-system",pod="operator"} {namespace="grafana", pod="grafana"} {namespace="grafana",

    label_team="admin"} {namespace="grafana", pod="grafana-operator"} 演算 ▶ onで指定したラベルが⼀致する組み合わせで、それぞれ演算 がおこなわれる。 rate(kube_pod_container_status_restarts_total[5m]) * on (namespace) group_left kube_namespace_labels{label_team="admin"} Query
  18. 54 node_memory_Active_bytes / on (instance) node_memory_MemTotal_bytes Query ノードごとのメモリ使⽤率 1 -

    avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) Query ノードごとのCPU使⽤率
  19. 55 expr: argocd_app_info{sync_status!="Synced"} == 1 for: 15m Alert ArgoCDによるアプリケーションの同期に失敗している expr:

    (certmanager_certificate_expiration_timestamp_seconds - time()) <= 14*24*60*60 for: 120m Alert cert-managerが発⾏した証明書の有効期限が14⽇以内に切れる expr: increase(kube_pod_container_status_restarts_total[5m]) > 0 for: 15m Alert 15分の間にPodが何度も再起動を繰り返す
  20. モニタリングシステムの構成 58 Kubernetes Node Node Node モニタリング対象 node- exporter kube-

    state- metrics cAdvisor Necoが提供するプラットフォーム 開発チームが ⽤意するもの モニタリングシステム 閲覧 アラート 開発者 収集ルール アラートルール VMStorage アプリケーション Grafana VMAgent VMAgent VMAlert AlertManager 独⾃メトリ クスの収集 保存 基本メトリ クスの収集
  21. 60 App PushGateway VMAgent 処理の完了時にメトリクスを送信する バッチなど時間がかかる処理の メトリクスを収集したい場合 メトリクスをPush App exporter

    VMAgent メトリクス収集⽤の別プログラム (exporter)を⽤意する アプリに⼿を加えられない場合など 基本はこれ App VMAgent アプリにメトリクスのAPIを実装する メトリクスの収集⽅式
  22. メトリクスの収集ルール ▶ Prometheusでは scrape_config にルールを記述 n https://prometheus.io/docs/prometheus/latest/configuration/confi guration/#scrape_config ▶ VictoriaMetrics

    Operatorではカスタムリソース (VMPodScrapeやVMServiceScrape)でルールを記述 n https://github.com/VictoriaMetrics/operator/blob/master/docs/api .MD 62
  23. 63 role: serviceはブラックボックスモニタリング向き。 ほとんど使うことはない。 VictoriaMetrics Operator Prometheus Serviceを対象にしたメトリクス収集 VMServiceScrape kubernetes_sd_configs

    role: service role: endpoints (default) role: endpointslices Podを対象にしたメトリクス収集 VMPodScrape kubernetes_sd_configs role: pod VictoriaMetrics Operatorと Prometheusの収集ルールの対応
  24. 65 apiVersion: operator.victoriametrics.com/v1beta1 kind: VMPodScrape metadata: name: todo namespace: todo

    spec: namespaceSelector: matchNames: [todo] selector: matchLabels: app.kubernetes.io/name: todo podMetricsEndpoints: - port: http scheme: http path: /metrics このラベルに⼀致するPodが メトリクス収集の対象となる 対象のPodの http という名前のポートから /metrics というパスでメトリクスを収集する ▶ Podからメトリクスを収集 するためのルールを記述 するカスタムリソース VMPodScrape
  25. 66 リラベル処理により、ラベルを整理 してからデータを保存する。 メタラベルは保存されない。 metrics_a{ key=value1,namespace=default,pod=todo } 123 メトリクス収集時に様々なメタラベ ルが付与される

    https://prometheus.io/docs/prom etheus/latest/configuration/config uration/#pod metrics_a{ key=value1, __meta_kubernetes_namespace=default, __meta_kubernetes_pod_name=todo, __meta_Kubernetes_pod_label_app=todo } 123 アプリケーションが出⼒する メトリクス metrics_a{key=value1} 123 メタラベルとリラベル
  26. 68 apiVersion: operator.victoriametrics.com/v1beta1 kind: VMPodScrape metadata: name: todo namespace: todo

    spec: /* 中略 */ podMetricsEndpoints: - port: http scheme: http path: /metrics relabelConfigs: - action: replace sourceLabels: [__meta_kubernetes_namespace] targetLabel: Kubernetes_namespace sourceLabelsに指定したラベル名を targetLabelで指定した名前に置き換える ▶ 指定したラベルの名前 や値を変更できる。 ▶ ユースケース n メタラベルを残す n ヒューマンリーダブルな 名前に変更する n 分析しやすいように値を 加⼯する Replace
  27. 70 apiVersion: operator.victoriametrics.com/v1beta1 kind: VMPodScrape metadata: name: todo namespace: todo

    spec: /* 中略 */ podMetricsEndpoints: - port: http scheme: http path: /metrics relabelConfigs: - action: keep sourceLabels: [__meta_Kubernetes_pod_name] regex: todo-.* この条件に⼀致するメトリクスのみ を保存対象とする ▶ keep: 条件にマッチした メトリクスのみを保存 する。他のメトリクス は捨てる。 ▶ drop: 条件にマッチした メトリクスは捨てる。 他のメトリクスは保存 する。 Keep/Drop
  28. 71 apiVersion: operator.victoriametrics.com/v1beta1 kind: VMPodScrape metadata: name: todo namespace: todo

    spec: /* 中略 */ podMetricsEndpoints: - port: http scheme: http path: /metrics relabelConfigs: - action: drop sourceLabels: [__name__,__address__] regex: 'up;.*:8080' __name__ が up に⼀致し、 __address__ が .*:8080 に⼀致したら捨てる ▶ 複数ラベルの条件を指定 するには、sourceLabels をカンマ区切り、regex をセミコロン区切りで書 く。 複数ラベルの指定
  29. 73 apiVersion: operator.victoriametrics.com/v1beta1 kind: VMAgent metadata: name: vmagent namespace: todo

    spec: replicaCount: 1 remoteWrite: - url: "http://vmsingle-database.monitoring- system.svc:8429/api/v1/write" podScrapeNamespaceSelector: matchLabels: kubernetes.io/metadata.name: todo scrapeInterval: 30s このラベルに⼀致するnamespace のVMPodScrapeを収集ルール として利⽤する 収集したメトリクスを保存する ストレージのURL 収集周期 Neco環境では30秒より短くできない ▶ メトリクスを収集する VMAgentをデプロイする ためのカスタムリソース VMAgent
  30. 収集ルールのデバッグ(1) ▶ VMAgentのログを確認 n kubectl logs -n todo deploy/vmagent-todo-agent -c

    vmagent ▶ ⽣成されたscrape_configの確認 n kubectl -n todo exec deploy/vmagent-todo-agent -c vmagent -- cat /etc/vmagent/config_out/vmagent.env.yaml 74
  31. 収集ルールのデバッグ(2) ▶ VMAgentのAPIをポートフォワード n kubectl port-forward -n todo deploy/vmagent-todo-agent 8429:8429

    ▶ アクティブなターゲットの⼀覧 n curl localhost:8429/api/v1/targets | jq '.data.activeTargets[].labels.job' ▶ 取得しなかったターゲットの⼀覧 n curl localhost:8429/api/v1/targets | jq '.data.droppedTargets[].discoveredLabels.job' ▶ 特定ターゲットのメタラベルなどを確認 n curl localhost:8429/api/v1/targets | jq '.data.activeTargets[] | select(.labels.job=="todo/todo")' 75
  32. アラートの通知 ▶ アプリケーションの運⽤時に問題をすばやく検知したい。 n 例:アプリケーションがクラッシュして⽴ち上がらない n 例:証明書の有効期限が切れた n 例:ディスクの空き容量がなくなった ▶

    Kubernetesではセルフヒールにより⾃動で問題が解決するこ とも多い。異常を検知したら即座にアラートをあげるのでは なく、しばらく異常が続いた場合にアラートをあげよう。 77
  33. モニタリングシステムの構成 79 Kubernetes Node Node Node モニタリング対象 node- exporter kube-

    state- metrics cAdvisor Necoが提供するプラットフォーム 開発チームが ⽤意するもの モニタリングシステム 閲覧 アラート 開発者 収集ルール アラートルール VMStorage アプリケーション Grafana VMAgent VMAgent VMAlert AlertManager 独⾃メトリ クスの収集 保存 基本メトリ クスの収集
  34. 81 apiVersion: operator.victoriametrics.com/v1beta1 kind: VMRule metadata: name: vmrule namespace: todo

    spec: groups: - name: todo rules: - alert: TodoErrorsHigh expr: | sum(rate(todo_api_requests_total{code="500"}[5m])) / sum(rate(todo_api_requests_total[5m])) > 0.3 for: 60s labels: severity: error annotations: summary: "Todo is returning errors for {{ $value }}% of requests" exprの結果を {{ $value }} で埋め込むことが可能 exprのクエリの条件に forの期間⼀致した場合に アラートを送信する ▶ アラートルールを記述する ためのカスタムリソース ▶ labelsやannotationsで送信 するアラートのレベルや メッセージを設定する VMRule
  35. 82 apiVersion: operator.victoriametrics.com/v1beta1 kind: VMAlert metadata: name: vmalert namespace: todo

    spec: replicaCount: 1 datasource: url: "http://vmsingle-database.monitoring- system.svc:8429" notifier: url: "http://vmalertmanager-alertmanager.todo.svc:9093" evaluationInterval: "30s" ruleNamespaceSelector: matchLabels: kubernetes.io/metadata.name: todo この条件にマッチするnamespace内にある VMRuleをアラートルールとして利⽤する メトリクスの取得元と アラートの送信先を設定 ▶ アラート送信を判断する VMAlertをデプロイする ためのカスタムリソース VMAlert
  36. 83 apiVersion: v1 kind: Secret metadata: name: alertmanager-setting namespace: todo

    type: Opaque stringData: alertmanager.yaml: | route: receiver: slack receivers: - name: 'slack' slack_configs: - api_url: 'https://hooks.slack.com/services/xxxxx' channel: ‘#xxxxx' text: "{{ .CommonAnnotations.summary }}" send_resolved: true VMRuleで指定したlabelsやannotationsを メッセージに埋め込むことができる すべてのアラートを Slackに送信する設定 ▶ アラートの送信先を設定 ▶ メール、Slack, PagerDuty, OpsGenieなどが利⽤可能 ▶ 重要度(severity)に応じた 通知先の振り分けも可能 AlertManager設定
  37. 84 apiVersion: operator.victoriametrics.com/v1beta1 kind: VMAlertmanager metadata: name: alertmanager namespace: todo

    spec: replicaCount: 1 configSecret: alertmanager-setting 設定ファイルのSecretリソースを指定 ▶ AlertManagerをデプロイす るためのカスタムリソース VMAlertManager
  38. 86 state: pending アラートの条件に⼀致するが 指定した時間が経過していない state: firing アラートが送信された ▶ VMAlertのAPIをポートフォワード

    n kubectl –n todo port-forward deploy/vmalert-vmalert 8888:8080 ▶ VMAlertが読み込んだルールを確認 n curl localhost:8888/api/v1/groups | jq . ▶ VMAlertが検出したアラートを確認 n curl localhost:8888/api/v1/alerts | jq . アラートのデバッグ(2)
  39. 87 ▶ AlertManagerをポートフォワード n kubectl –n todo port-forward sts/vmalertmanager-alertmanager 9093:9093

    ▶ ブラウザでlocalhost:9093 の画⾯を確認 アラートのデバッグ(3)
  40. 参考⽂献 ▶ ⼊⾨ 監視 n モダンなモニタリングのためのデザインパターン ▶ ⼊⾨ Prometheus n

    インフラとアプリケーションのパフォーマンスモニタリ ング 90