12.7K Views
July 29, 23
スライド概要
23/7/28 OpenShift Lounge+ "TALKs" 〜 Ops/Monitoring編 〜
OpenShiftユーザの多くが悩めるアプリケーション監視、、、 OpenShiftにはアプリケーション監視を簡単に実現できる機能「user-workload monitoring」があります。user-workload monitoringをうまく活用するためのポイントを「メトリクスの仕組み」「収集の仕組み」「アラートの仕組み」という3つの視点で解説します。
アプリケーション運用者が知るといい User Workload Monitoring の話 2023/07/28 OpenShift Lounge+ "TALKs" @mosuke5
自己紹介 名前: @mosuke5 (もーすけ・森 真也) 仕事: 2019.4~: ・OpenShiftやDevOps, Agile開発の支援 以前: ・某クラウドの日本リージョンの立ち上げ クラウド化の支援 ・モバイルNW関連のシステム開発・運用 ・ソーシャルメディア解析サービスの開発・運用 趣味:テニス、ポケモン、投資 最近:昨日、娘が1歳になりました! 2
アジェンダ 1. 2. 3. 4. 5. 6. はじめに・背景など User Workload monitoringの全体像 メトリクスの出力 収集とアラート アラートの通知 利用する上での疑問解消 (実際によくある質問など)
きっかけ・・・ OpenShiftの新機能、ユーザ定義プロ ジェクトの監視ってどこまでできる? データ期間:過去 1年間 PV数がトップ 100のなかで、一部の異常に長い滞在時間記事除く。
Cluster monitoringって OpenShiftクラスタ自身を監視することを主目的とした コンポーネント。デフォルトで起動。 以下のようなソフトウェアの集合体。 1. 2. 3. 4. 5. 6. 7. Prometheus Operator Prometheus Alertmanager kube-state-metrics openshift-state-metrics node_exporter prometheus-adapter Podのメトリクスを取得しているが、クラスタ全 体で見る形式。監視設定もプリセットがあり追 加もできない。
User workload monitoringって? もともとはOpenShiftクラスタを監視するコンポーネントだったが、OpenShift 4.6から 拡張機能として「OpenShift上のユーザアプリケーション」も監視できるようになった もの。 特徴として 1. 2. ユーザ自身がPrometheusなどの監視ツールを構築・運用しなくて良い マルチテナントで利用することができ、権限あるアプリの情報だけが確認・通知 できる
アーキテクチャ
Prometheus ● Prometheusはオープンソースのメトリクスベースモ ニタリングシステム ○ ○ ● Prometheusの特徴 ○ ○ ○ ○ ● https://github.com/prometheus/prometheus CNCF(Cloud Native Computing Foundation)の 2番目のメ ンバーでGraduated Projectのひとつ。 プル型のデータ取得アーキテクチャでスケールが容易 サービスディスカバリ機能が充実。クラウドやコンテナ環境 に最適化された仕組み 監視設定のコード化が容易 柔軟なクエリー( PromQL) 不向きなこと ○ メトリクスベースのため、イベントログや個別のイベント情報 の格納には不向き。 Grafanaと連携した可視化が容易
ざっくりのイメージ ユーザアプリケーションの Namespace メトリクス収集 アラート通知先 AlertmanagerConf 監視設定 ServiceMonitor アラートルール PrometheusRule 設定反映 Prometheus クエリー実行 ユーザが意識するエリア ユーザが意識しないエリア
ユーザが管理する範囲 ServiceMonitor PrometheusRule AlertmanagerConf 作成 ユーザ namespace: openshift-monitoring 監視 ServiceMonitorの内容を反映 PrometheusRuleの内容を反映 namespace: openshift-user-workload-monitoring Alertmanagerはクラスタ監視用を使うので、通知先設定は クラスタ管理者しかできなかった(過去形)。 OpenShift 4.11以降で改善
拡大図 デフォで取得している→ メトリクス ・PodのCPU使用率 ・Podのメモリー使用率 ・Jobの成否 … ←ユーザが定義したメトリクス 複数のPrometheusのメトリクスのデー タを束ねて提供
利用までの流れ 1. User-workload monitoringの有効化 ←本日のスコープ外 a. b. 2. 3. 4. ConfigMapで有効化設定 Prometheus/Alertmanagerのストレージ等のリソース設定 メトリクスの出力を設定 メトリクスの収集を設定 アラート・通知を設定
メトリクスの出力
利用できるメトリクス ● OpenShiftが用意しているもの ○ ○ ○ ○ ○ ○ ● Kubelet kube-state-metrics openshift-state-metrics Recording rules (node_exporter) (その他各種Operator) ユーザが用意するもの ○ 独自アプリケーションのメトリクス ■ ■ ■ ○ Micrometer xx_exporter -> pg_exporter, mysql_exporter, jvm_exporter Client library ビジネスメトリクス ■ sql_exporter
メトリクス(kubelet) Kubeletは、Kubernetesを構成するコンポーネントの ひとつ。 クラスタ内の各ノードで動作するエージェントで、主に Podのライフサイクルを管理(起動停止、リソース管 理、ヘルスチェック…)。 Kubeletには、cAdvisorというソフトウェアを組み込ん でおり、コンテナのリソース使用状況を収集・公開して いる。 確認した感じ、いくつかの種類のメトリクスのみを cAdvisorからとって公開しているよう。 (Github)
メトリクス(kube-state-metrics) kube-state-metrics は、Kubernetes APIを通じて、Kubernetesのオブジェクトの状 態をPrometheus形式のメトリクスで出力するものです。 具体的には、DeploymentやPodといったKubernetesオブジェクトの情報。 $ oc get deploy nginx -o yaml … status: availableReplicas: 3 conditions: … observedGeneration: 1 readyReplicas: 3 replicas: 3 updatedReplicas: 3
メトリクス(openshift-state-metrics) openshift-state-metrics は、OpenShiftの固有のオブジェクトの状態をPrometheus 形式のメトリクスで出力するもの。 具体的には、DeploymentConfigやRoute、BuildConfigといった、OpenShift固有の オブジェクト情報。
kube-state -metrics openshift-st ate-metrics
Recording rules (Prometheusの機能) PrometheusのRecording rulesは、頻繁に使用するまたは計算に時間のかかるクエリの結果 を新しいメトリックとして保存し、その結果を効率的に再利用する機能。 Cluster MonitoringのPrometheusでは、Recording rulesを予め用意してくれている。 # 各namespaceとclusterにおけるPendingまたはRunning状態のPodでリクエストされているCPUの合計量を計算 - expr: | sum by (namespace, cluster) ( sum by (namespace, pod, cluster) ( max by (namespace, pod, container, cluster) ( kube_pod_container_resource_requests{resource="cpu",job="kube-state-metrics"} ) * on(namespace, pod, cluster) group_left() max by (namespace, pod, cluster) ( kube_pod_status_phase{phase=~"Pending|Running"} == 1 ) ) ) record: namespace_cpu:kube_pod_container_resource_requests:sum
メトリクスの収集とアラート
監視対象設定 /metrics で公開 Prometheusの監視設定を Kubernetesマニフェストで表現できる apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: nginx-monitor spec: # メトリクスのエンドポイントの設定 # "exporter"という名前のService portを選択 endpoints: - interval: 30s port: exporter scheme: http # 検出するServiceの条件設定 # "app: test-nginx"のラベルを持つServiceを検出 selector: matchLabels: app: test-nginx スクレイピング Prometheus Operatorが、 ServiceMonitorからPrometheusの設定 ファイルを生成し、Prometheusによみこま せる。 # prometheus.yaml global: scrape_interval: 15s evaluation_interval: 15s scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090']
アラート設定 Prometheusのアラート設定をKubernetesマニフェストで表現できる alert manager アラートを評価して発報 apiVersion: monitoring.coreos.com/v1 kind: PrometheusRule metadata: name: nginx-alert spec: groups: - name: nginx-down rules: - alert: NginxPartiallyDown expr: sum(nginx_up) < 3 for: 5m labels: severity: warning Prometheus Operatorが、 PrometheusRuleからPrometheusが読み 取れるルールファイルに変換 # rulefile groups: - name: nginx-down rules: - alert: NginxPartiallyDown expr: sum(nginx_up) < 3 for: 5m labels: severity: warning
ユーザが管理する範囲 ServiceMonitor PrometheusRule AlertmanagerConf namespace: openshift-monitoring 作成 ユーザ 監視 ServiceMonitorの内容を反映 PrometheusRuleの内容を反映 namespace: openshift-user-workload-monitoring
アラートの通知
OpenShift 4.11以前の世界 ユーザアプリケーションの Namespace 監視設定 ServiceMonitor クラスタ管理の Namespace アラートルール PrometheusRule アラート通知先設 定 ・開発者A: Slack xxチャネル ・開発者B: Slack yyチャネル ・開発者C: email ② 開発者Aさん用にア ラート通知先を追加 開発者A ① 開発者Aのアラートは Slackのxxチャネルに通 知してください クラスター 管理者
OpenShift 4.11以後の世界 ユーザアプリケーションの Namespace クラスタ管理の Namespace アラート通知先 AlertmanagerConfig 監視設定 ServiceMonitor アラートルール PrometheusRule アラート通知先設 定 ② Operatorが自動 でアラート通知先を 追加 ① 自分でアラート 通知先を管理 開発者A ・開発者A: Slack xxチャネル ・開発者B: Slack yyチャネル ・開発者C: email やることなし! クラスター 管理者
アラート通知設定 Prometheusのアラート設定をKubernetesマニフェストで表現できる apiVersion: monitoring.coreos.com/v1beta1 kind: AlertmanagerConfig metadata: name: example-routing namespace: mosuke5-monitoring spec: route: receiver: default groupBy: [job] receivers: - name: default slackConfigs: - apiURL: ## KubernetesのSecretを指定 name: my-slack-secret key: url channel: mosuke5-alert sendResolved: true alert manager Prometheus Operatorが、 alertmanagerが読める形式の Configに変換して反映 # alertmanager.yaml receivers: - name: mosuke5-monitoring/example-routing/default slack_configs: - send_resolved: true api_url: https://hooks.slack.com/services/xxxxxxx channel: mosuke5-alert
利用する上での疑問解消
Prometheusがマルチテナント!? いい感じにやってくれるのはわかったけど、、、 1. 2. Prometheusってマルチテナント機能なかったはずだけど、なぜuser-workload monitoringではユーザごとに見れるメトリクスが違うの? prometheusRuleを設定したけど、なぜかアラートされないんだけど? a. prometheusRuleを設定したNamespace外のメトリクスを利用していた
クエリーが実行されるまでの流れ Developer UI /api/prometheus-tenancy/api/v1/query ?namespace=myapp &query=process_cpu_seconds_total Thanos ruler prometheusRuleを Thanos rulerに反映 する時に自動で namespaceラベルが 付与される Service (thanos-querier) Console server 9091 oauthproxy 9092 kube-rbacproxy 9093 kube-rbac proxy-rule kube-rbac 9094 proxy-metric SubjectAccessReviewsを 使って、認可処理 promQLへラベルを付けて変換 process_cpu_seconds_total{ namespace=myapp} Prometheus for cluster prom-labelproxy 9095 Thanos querier 9090 thanos-querier pod Prometheus for user メトリクス収集時に namespaceラベルを 付与
PromQL難しいんだが...!? 簡単ではないですよね、、、 しかし、以下をまず押さえると見え方が変わってくることが多い気がします - 利用できるメトリクスを把握する(時間あればデモ) - - Kube-state-metrics documents Openshift-state-metrics documents Recording ruleの内容の確認方法 Prometheusのデータタイプを理解する 統計の基本用語を覚える ChatGPTが得意なので積極的に使う 豆知識(メトリクス名の見分け方例) - kube_* : kube-state-metrics - openshift_* : openshift-state-metrics - container_* : kubelet - pod:xxx : Recording rules - namespace:xxx : Recording rules - cluster:xxx : Recording rules
Recording rulesの内容を知る % oc get cm prometheus-k8s-rulefiles-0 -o yaml | grep -B10 "record: namespace_cpu:kube_pod_container_resource_requests:sum" - expr: | sum by (namespace, cluster) ( sum by (namespace, pod, cluster) ( max by (namespace, pod, container, cluster) ( kube_pod_container_resource_requests{resource="cpu",job="kube-state-metrics"} ) * on(namespace, pod, cluster) group_left() max by (namespace, pod, cluster) ( kube_pod_status_phase{phase=~"Pending|Running"} == 1 ) ) ) record: namespace_cpu:kube_pod_container_resource_requests:sum
例)PromQL data type Prometheusで利用するメトリクスのデータタイプには以下の4つがある。 1. Counter(カウンタ) a. b. c. 2. Guarge(ゲージ) a. b. 3. カウンタと異なり、ときに増減する数値を表す。 温度やメモリ使用率、同時稼働数など増減する値に利用される。 Histogram(ヒストグラム) a. b. 4. 名前の通り「単純増加」を表す。(グラフで表すと右肩上がり) カウンタはシステム上に発生するイベントを追跡するのに使われることが多い。 例としては、Webサーバへのリクエストされた回数の計測などで利用。 指定した範囲に値がどれくらい存在するかを表す。 リクエスト応答時間やリクエストサイズなど変動しうる値で、その分布を計測する場合などに利 用される。 Summary(サマリ) a. ヒストグラムと類似し、指定した範囲に存在する値がどれくらい存在するかを表すが、パーセ ンタイル形式で表示する
例)特徴的な計算方法 container_cpu_usage_seconds_total(カウンタ) irate(container_cpu_usage_seconds_total[5m]):5分間あたりの増加率を計算 知りたいのは こっち
例)統計用語:パーセンタイル パーセンタイルは、モニタリングシステムでよく用いられる統計用語。 計測した値を、小さい順に並べた場合に、小さい方から数えてどのくらい( N%)に位置する値かを示すも の。50パーセンタイル、 90パーセンタイル、 95パーセンタイルといったように利用する。 パーセンタイルを利用する理由は、極端に大きい値(異常値)の影響を受けづらくすることがおおい。単純 平均値では、異常値の影響を受け、正確な状況把握が難しいことがある。 例として、以下のような数字があった場合の 90パーセンタイルは? 元データ: 76、88、85、87、78、80、95、92、83、89 昇順データ: 76、78、80、83、85、87、88、89、92、95 90パーセンタイル
おわりに
おわりに ● ● ● ● User Workload Monitoringは、Cluster Monitoringの拡張機能 Cluster Monitoringのデータと連携しながら、 いい感じにマネージド監視サービスを提供 ○ 仕組みをわかっておくと、トラブルシューティングなど楽に 監視システムの運用は不要だが、一定のPrometheus/PromQLの知識は必要 ○ 学び方をさぐってみよう 話せなかったけど、 ダッシュボードがイケてないなどイマイチな点もあるので、自前構築と天秤で
おまけ
kubeletのメトリクスの実体を見る場合 On node # curl -k -H "Authorization: Bearer xxxxx" https://localhost:10250/metrics/cadvisor … container_cpu_system_seconds_total{container="POD",id="xxx",image="",name="k8s_POD_sonarq ube-postgresql-0_myapp_2621cd4e-292f-4e10-a36f-9fc7614dacea_0",namespace="myapp",pod="s onarqube-postgresql-0"} 0 1690507028110 …
で、どのくらいリソースが必要なの? 1. コンピューティングリソース a. b. 2. いまのところはスケールアップで対応するしかない レプリカ数の指定をできるが Prometheusの場合、冗長化としての対応 (Github: explaining a HA + scalable setup?) ディスク a. b. 推定しやすいので、計算しましょう。 次ページで計算例を。
user-workload-monitoringの必要ディスク容量は? Prometheusは、一定時間間隔で監視対象に対してメトリクスを取得する。 監視対象と取得間隔は ServiceMonitorで定義されるため、以下の式で必要なディスク容量の推定ができ る。また、Prometheusが収集するのはメトリクスデータのため、1サンプルが大きくならない(かつ、種類に よって大きさに差が出づらい)ため計算が可能。公式ドキュメント [1] 必要なディスク容量 = 保持期間 * 取得するサンプル数 * 1サンプルあたりのデータサイズ 取得するサンプル数 -> (rate(prometheus_tsdb_head_samples_appended_total[1d])) 1サンプルあたりのデータサイズ -> (rate(prometheus_tsdb_compaction_chunk_size_bytes_sum[1d])) / rate(prometheus_tsdb_compaction_chunk_samples_sum[1d]) 43 [1] https://prometheus.io/docs/prometheus/latest/storage/#compaction
user-workload-monitoringの必要ディスク容量は? ある特定時点で以下の状況と仮定 ● ● ● 取得するサンプル数: 1000 1サンプルあたりのデータサイズ: 1.5byte 保持期間: 2週間と仮定 (1,209,600秒) 必要なディスクサイズの見積もり = 1000*1.5*1209600 = 1.8GB