メッセージ監視を試してみる

メッセージ監視

はじめに

急に冷え込んできました。OpenShift Advent Calendar 2024 の 7 日目の記事です。先日 5日目の記事でアラート通知先がどのように変えられるかを確認しました。 本日は、Cluster Logging 機能の1つであるカスタムアラートの、メッセージ監視を試してみようと思います。

qiita.com

OpenShift Cluster Logging

Cluster Logging 6 からは、Elasticsearch の提供が終了し、Grafana Loki のみが利用できるようになりました。その少し前からメッセージ監視のアラートの機能が有効になっていますが、皆さんお使いになっているでしょうか。 ここでは、メッセージ監視の通知が、昨日のアラート通知と同様に管理者用(Cluster Monitoring)のAlertmanager と利用者用(User Workload Monitoring)のAlertmanager のどちらから通知されるかを見ていきたいと思います。

Loki のコンポーネントでは Ruler が監視の役割を担いますので、これについて見ていきます。

Ruler

Grafana Loki には Ruler と呼ばれるコンポーネントが含まれます。Ruler は設定されたクエリセットを継続的に評価し、その結果に基づいてアクションを起こす責務を持ちます。

grafana.com

具体的には、AlertingRule と RecordingRule の2つのカスタムリソースを用いてログメッセージを評価し、条件に一致する場合にアラートを通知する事ができます。それぞれのカスタムリソースは、Prometheus の表記と互換性があり、Prometheus を知っている場合は追加の学習コストが低い点が特徴です。

AlertingRule の例

groups:
  - name: should_fire
    rules:
      - alert: HighPercentageError
        expr: |
          sum(rate({app="foo", env="production"} |= "error" [5m])) by (job)
            /
          sum(rate({app="foo", env="production"}[5m])) by (job)
            > 0.05
        for: 10m
        labels:
            severity: page
        annotations:
            summary: High request latency
  - name: credentials_leak
    rules:
      - alert: http-credentials-leaked
        annotations:
          message: "{{ $labels.job }} is leaking http basic auth credentials."
        expr: 'sum by (cluster, job, pod) (count_over_time({namespace="prod"} |~ "http(s?)://(\\w+):(\\w+)@" [5m]) > 0)'
        for: 10m
        labels:
          severity: critical

メッセージ監視の通知先の AlertManager

昨日、[アラート通知のコントロール(https://rheb.hatenablog.com/entry/2024/12/06/215706)ということで、以下の3点を確認しました。

  1. 利用者はアラート通知を行いたいが、通知先は管理者により管理される
  2. 利用者はアラート通知を行いたい、かつ通知先も利用者が管理したい
  3. 管理者もカスタムでアラートを追加するため利用者と負荷を分散したい(利用者は通知先の設定を自分で管理しなければならなくなる)

通知先のコントロールを利用者が行うか管理者が行うかについては先日整理したので、本日はメッセージ監視の通知が管理者用の AlertManager か利用者用の AlertManager かを確認していきます。

パターンとしては 1 と 3 を確認します。

利用するアプリとメッセージ監視ルール

一定時間毎に ERROR という文字列を出力するアプリケーションを利用します。特別機能は必要ないので、以下のDeploymentでアプリをデプロします。

cat <<EOF | oc apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: error-logger
  labels:
    app: error-logger
spec:
  replicas: 1
  selector:
    matchLabels:
      app: error-logger
  template:
    metadata:
      labels:
        app: error-logger
    spec:
      containers:
      - name: error-logger
        image: busybox
        command: ["sh", "-c", "while true; do echo ERROR; sleep 1; done"]

EOF

また、メッセージ監視も ERROR という文字列がある一定以上の割合で出力された場合にアラートを発報するよう設定します。

  apiVersion: loki.grafana.com/v1
  kind: AlertingRule
  metadata:
    name: sample-alert
    labels:
      example.jp/system: sample
  spec:
    tenantID: "application"
    groups:
      - name: SampleError
        rules:
          - alert: HighPercentageError
            expr: |
              sum(rate({kubernetes_namespace_name="log-sample", kubernetes_pod_name=~".*"} |= "ERROR" [1m])) by (job)
                /
              sum(rate({kubernetes_namespace_name="log-sample", kubernetes_pod_name=~".*"}[1m])) by (job)
                > 0.01
            for: 10s
            labels:
              severity: critical
            annotations:
              summary: This is summary
              description: This is description

アラート監視の設定の有効化

LokiStack はデフォルトではメッセージ監視が有効になっていないために、以下のフィールドを LokiStack に設定します。Namespace セレクターのラベル等は環境ごとに変えてください。

...
spec:
...
  rules:
    enabled: true
    namespaceSelector:
      matchLabels:
        example.jp/alert: 'true'
    selector:
      matchLabels:
        example.jp/system: sample
...

パターン1: 管理者用の AlertManager への通知

アラート通知の確認で利用したコマンドに、Ruler の設定を表示されるコマンドを追加した以下のコマンドを使って状況を確認していきます。

echo "User: alerts"
oc exec -it alertmanager-user-workload-0 -n openshift-user-workload-monitoring -- amtool alert query --alertmanager.url http://localhost:9093

echo ""
echo "Cluster: alerts"
oc exec -it alertmanager-main-1 -n openshift-monitoring -- amtool alert query --alertmanager.url http://localhost:9093

echo ""
echo "User workload: alertmanager.yaml"
oc exec -it alertmanager-user-workload-0 -n openshift-user-workload-monitoring -- cat /etc/alertmanager/config_out/alertmanager.env.yaml; echo ""

echo ""
echo "Cluster: alertmanager.yaml"
oc exec -it alertmanager-main-1 -n openshift-monitoring -- cat /etc/alertmanager/config_out/alertmanager.env.yaml; echo ""


echo ""
echo "Cluster Logging: Ruler"
oc exec -it logging-loki-ruler-0 -n openshift-logging -- cat /etc/loki/config/config.yaml | egrep "^ruler:" -A 10; echo ""

まずは、管理者用の Monitoring の設定

apiVersion: v1
kind: ConfigMap
metadata:
  name: cluster-monitoring-config
  namespace: openshift-monitoring
data:
  config.yaml: |
    enableUserWorkload: true

利用者用の Monitoring の設定はアラート通知については不要です。

この状態で、アラートが発生すると次のようになります。利用者の Monitoring の設定はないため、AlertManager の情報取得はエラーとなります。 Loki の Ruler の設定を見ると https://_web._tcp.alertmanager-operated.openshift-monitoring.svc を参照していることがわかります。管理者用の AlertManager を見ています。この設定が示すように、メッセージ監視のアラート HighPercentageError が管理者用の AlertManager に通知されていることが確認できます。

User: alerts
Error from server (NotFound): pods "alertmanager-user-workload-0" not found

Cluster: alerts
Alertname                            Starts At                Summary                                                                                                    State
Watchdog                             2024-12-07 01:36:52 UTC  An alert that should always be firing to certify that Alertmanager is working properly.                    active
UpdateAvailable                      2024-12-07 01:38:06 UTC  Your upstream update recommendation service recommends you update your cluster.                            active
PrometheusOperatorRejectedResources  2024-12-07 01:42:32 UTC  Resources rejected by Prometheus operator                                                                  active
InsightsRecommendationActive         2024-12-07 01:44:33 UTC  An Insights recommendation is active for this cluster.                                                     active
KubeDaemonSetMisScheduled            2024-12-07 01:52:49 UTC  DaemonSet pods are misscheduled.                                                                           active
KubeDaemonSetMisScheduled            2024-12-07 01:52:49 UTC  DaemonSet pods are misscheduled.                                                                           active
KubeDaemonSetMisScheduled            2024-12-07 01:52:49 UTC  DaemonSet pods are misscheduled.                                                                           active
KubeDaemonSetRolloutStuck            2024-12-07 02:07:49 UTC  DaemonSet rollout is stuck.                                                                                active
KubeDaemonSetRolloutStuck            2024-12-07 02:07:49 UTC  DaemonSet rollout is stuck.                                                                                active
KubeDaemonSetRolloutStuck            2024-12-07 02:07:49 UTC  DaemonSet rollout is stuck.                                                                                active
PrometheusDuplicateTimestamps        2024-12-07 02:37:55 UTC  Prometheus is dropping samples with duplicate timestamps.                                                  active
ClusterNotUpgradeable                2024-12-07 02:38:10 UTC  One or more cluster operators have been blocking minor version cluster upgrades for at least an hour.      active
PrometheusDuplicateTimestamps        2024-12-07 02:38:25 UTC  Prometheus is dropping samples with duplicate timestamps.                                                  active
PodDisruptionBudgetAtLimit           2024-12-07 02:39:38 UTC  The pod disruption budget is preventing further disruption to pods.                                        active
HighOverallControlPlaneMemory        2024-12-07 05:17:04 UTC  Memory utilization across all control plane nodes is high, and could impact responsiveness and stability.  active
HighPercentageError                  2024-12-07 11:55:32 UTC  This is summary                                                                                            active

User workload: alertmanager.yaml
Error from server (NotFound): pods "alertmanager-user-workload-0" not found


Cluster: alertmanager.yaml
inhibit_rules:
  - equal:
      - namespace
      - alertname
    source_matchers:
      - severity = critical
    target_matchers:
      - severity =~ warning|info
  - equal:
      - namespace
      - alertname
    source_matchers:
      - severity = warning
    target_matchers:
      - severity = info
receivers:
  - name: Critical
  - name: Default
    slack_configs:
      - channel: '#openshift-on-kvm'
        api_url: >-
          https://hooks.slack.com/services/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
  - name: Watchdog
route:
  group_by:
    - namespace
  group_interval: 5m
  group_wait: 30s
  receiver: Default
  repeat_interval: 12h
  routes:
    - matchers:
        - alertname = Watchdog
      receiver: Watchdog
    - matchers:
        - severity = critical
      receiver: Critical


Cluster Logging: Ruler
ruler:
  enable_api: true
  enable_sharding: true
  alertmanager_url: https://_web._tcp.alertmanager-operated.openshift-monitoring.svc
  enable_alertmanager_v2: true
  enable_alertmanager_discovery: true
  alertmanager_refresh_interval: 1m
  wal:
    dir: /tmp/wal
    truncate_frequency: 60m
    min_age: 5m

パターン3: 利用者用の AlertManager への通知

今度は利用者用の AlertManager へ通知を行います。利用者用のAlertManager の有効化と AlergMangerConfig の設定を有効にします。

管理者用の Monitoring の設定

apiVersion: v1
kind: ConfigMap
metadata:
  name: cluster-monitoring-config
  namespace: openshift-monitoring
data:
  config.yaml: |
    enableUserWorkload: true

利用者用の Monitoring の設定

apiVersion: v1
kind: ConfigMap
metadata:
  name: user-workload-monitoring-config
  namespace: openshift-user-workload-monitoring
data:
  config.yaml: |
    alertmanager:
      enabled: true
      enableAlertmanagerConfig: true     

この状態で、メッセージ監視を行います。

確認結果は次のとおりとなります。監視の通知が利用者用の AlertManager に届いていることが確認できます。ただし、Ruler の設定が相変わらず管理者用の AlertManager を向いています。何が起きているのでしょうか。

User: alerts
Alertname            Starts At                Summary          State
HighPercentageError  2024-12-07 12:16:04 UTC  This is summary  active

Cluster: alerts
Alertname                            Starts At                Summary                                                                                                    State
Watchdog                             2024-12-07 01:36:52 UTC  An alert that should always be firing to certify that Alertmanager is working properly.                    active
UpdateAvailable                      2024-12-07 01:38:06 UTC  Your upstream update recommendation service recommends you update your cluster.                            active
PrometheusOperatorRejectedResources  2024-12-07 01:42:32 UTC  Resources rejected by Prometheus operator                                                                  active
InsightsRecommendationActive         2024-12-07 01:44:33 UTC  An Insights recommendation is active for this cluster.                                                     active
KubeDaemonSetMisScheduled            2024-12-07 01:52:49 UTC  DaemonSet pods are misscheduled.                                                                           active
KubeDaemonSetMisScheduled            2024-12-07 01:52:49 UTC  DaemonSet pods are misscheduled.                                                                           active
KubeDaemonSetMisScheduled            2024-12-07 01:52:49 UTC  DaemonSet pods are misscheduled.                                                                           active
KubeDaemonSetRolloutStuck            2024-12-07 02:07:49 UTC  DaemonSet rollout is stuck.                                                                                active
KubeDaemonSetRolloutStuck            2024-12-07 02:07:49 UTC  DaemonSet rollout is stuck.                                                                                active
KubeDaemonSetRolloutStuck            2024-12-07 02:07:49 UTC  DaemonSet rollout is stuck.                                                                                active
PrometheusDuplicateTimestamps        2024-12-07 02:37:55 UTC  Prometheus is dropping samples with duplicate timestamps.                                                  active
ClusterNotUpgradeable                2024-12-07 02:38:10 UTC  One or more cluster operators have been blocking minor version cluster upgrades for at least an hour.      active
PrometheusDuplicateTimestamps        2024-12-07 02:38:25 UTC  Prometheus is dropping samples with duplicate timestamps.                                                  active
PodDisruptionBudgetAtLimit           2024-12-07 02:39:38 UTC  The pod disruption budget is preventing further disruption to pods.                                        active
HighOverallControlPlaneMemory        2024-12-07 05:17:04 UTC  Memory utilization across all control plane nodes is high, and could impact responsiveness and stability.  active

User workload: alertmanager.yaml
route:
  receiver: Default
  group_by:
  - namespace
  routes:
  - receiver: alert-sample/slack-routing/sample
    matchers:
    - namespace="alert-sample"
    continue: true
receivers:
- name: Default
- name: alert-sample/slack-routing/sample
  slack_configs:
  - api_url: https://hooks.slack.com/services/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
    channel: '#openshift-on-kvm'
templates: []


Cluster: alertmanager.yaml
inhibit_rules:
  - equal:
      - namespace
      - alertname
    source_matchers:
      - severity = critical
    target_matchers:
      - severity =~ warning|info
  - equal:
      - namespace
      - alertname
    source_matchers:
      - severity = warning
    target_matchers:
      - severity = info
receivers:
  - name: Critical
  - name: Default
    slack_configs:
      - channel: '#openshift-on-kvm'
        api_url: >-
          https://hooks.slack.com/services/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
  - name: Watchdog
route:
  group_by:
    - namespace
  group_interval: 5m
  group_wait: 30s
  receiver: Default
  repeat_interval: 12h
  routes:
    - matchers:
        - alertname = Watchdog
      receiver: Watchdog
    - matchers:
        - severity = critical
      receiver: Critical


Cluster Logging: Ruler
ruler:
  enable_api: true
  enable_sharding: true
  alertmanager_url: https://_web._tcp.alertmanager-operated.openshift-monitoring.svc
  enable_alertmanager_v2: true
  enable_alertmanager_discovery: true
  alertmanager_refresh_interval: 1m
  wal:
    dir: /tmp/wal
    truncate_frequency: 60m
    min_age: 5m

実は、Ruler コンポーネントの設定ファイルは、更に別のファイル /etc/loki/config/runtime-config.yaml によって設定が一部上書きされています。 中身を見ると以下のようになっています。

---
overrides:
  application:
    ruler_alertmanager_config:
      alertmanager_url: https://_web._tcp.alertmanager-operated.openshift-user-workload-monitoring.svc
      enable_alertmanager_v2: true
      enable_alertmanager_discovery: true
      alertmanager_refresh_interval: 1m
      alertmanager_client:
        tls_ca_path: /var/run/ca/alertmanager/service-ca.crt
        tls_server_name: alertmanager-user-workload.openshift-user-workload-monitoring.svc.cluster.local
        type: Bearer
        credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token

こちらで、通知先の Alertmanager が利用者用となっていることが確認できます。 これで実態と設定の内容が一致しました。

まとめ

メッセージ監視の通知がどちらのAlertManager に通知されるか実際の設定と振舞いを確認しました。また実際にPodに設定される内容も確認し、振舞いとあっていることも確認できました。 これでようやく週末を迎えられそうです。

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。