mcpField
M
mimir

mimir

github.com/julianobarbosaクラウド・DevOps15117 回インストール4 日前に更新
リポジトリ

mimir について

mimirは、PrometheusとOpenTelemetryのメトリクスを長期保存するチーム向けのGrafana Mimir導入・運用ガイドです。分散コンポーネント、オブジェクトストレージ、マルチテナント、クエリ、障害調査を扱います。

主な機能

  1. 01モノリシックとマイクロサービスの導入を解説
  2. 02オブジェクトストレージのバックエンド設定
  3. 03PrometheusとOTLPメトリクスの取り込み
  4. 04テナントとテナント別制限の設定
  5. 05クエリ、アラート、障害調査の案内

活用シーン

  1. 01メトリクス長期保存用にMimirを導入
  2. 02テナント分離とテナント別制限を設定
  3. 03OpenTelemetryメトリクスを取り込み検索
  4. 04ストレージ、取り込み、クエリの問題を調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/julianobarbosa/claude-code-skills --skill mimir

インストール後、Claude Code で/mimirを入力して読み込まれたか確認します。

詳細

Grafana Mimir スキル

Grafana Mimir の包括的なガイドです。Grafana Mimir は、Prometheus メトリクスを長期保存するための、水平スケーラブルで高可用性、マルチテナント対応の時系列データベースです。

Mimir とは?

Mimir は、Prometheus と OpenTelemetry のメトリクス向けのオープンソースで、水平スケーラブルかつ高可用性を備えたマルチテナント対応の長期ストレージソリューションです。次の特長があります。

  • Prometheus の制約を克服 — スケーラビリティと長期保持を実現します
  • デフォルトでマルチテナント対応 — X-Scope-OrgID ヘッダーによるテナント分離を標準で備えています
  • オブジェクトストレージにデータを保存 — S3、GCS、Azure Blob Storage、または Swift に対応します
  • 100% Prometheus 互換 — PromQL クエリ、リモートライトプロトコルに対応します
  • LGTM+ Stack の一部 — ログ、Grafana、トレース、メトリクスを統合したオブザーバビリティを提供します

アーキテクチャの概要

コアコンポーネント
コンポーネント目的
Distributorリクエストを検証し、ハッシュリングを介して受信メトリクスを Ingester にルーティングします
Ingester時系列データをメモリに保存し、オブジェクトストレージにフラッシュします
QuerierIngester と Store-Gateway から PromQL クエリを実行します
Query Frontendクエリ結果をキャッシュし、クエリを最適化して分割します
Query Scheduler公平性を確保するため、テナントごとのクエリキューを管理します
Store-Gatewayオブジェクトストレージ内の過去のメトリクスブロックへのアクセスを提供します
Compactor保存されたメトリクスデータブロックを統合し、最適化します
Rulerレコーディングルールとアラートルールを評価します(オプション)
Alertmanagerアラートのルーティングと重複排除を処理します(オプション)
データフロー

書き込みパス:

Prometheus/OTel → Distributor → Ingester → Object Storage
                       ↓
                 Hash Ring
                 (routes by series)

読み取りパス:

Query → Query Frontend → Query Scheduler → Querier
                                              ↓
                                    Ingesters (recent)
                                              ↓
                                    Store-Gateway (historical)

デプロイモード

1. モノリシックモード(-target=all)
  • すべてのコンポーネントを単一プロセスで実行します
  • 最適な用途:開発、テスト、小規模環境(約 100 万時系列)
  • 複数のインスタンスをデプロイして水平スケーリングできます
  • 大規模環境には推奨されません(すべてのコンポーネントが一緒にスケーリングされます)
2. マイクロサービスモード(分散型)— 本番環境に推奨
# Using mimir-distributed Helm chart
distributor:
  replicas: 3

ingester:
  replicas: 3
  zoneAwareReplication:
    enabled: true

querier:
  replicas: 3

queryFrontend:
  replicas: 2

queryScheduler:
  replicas: 2

storeGateway:
  replicas: 3

compactor:
  replicas: 1

Helm によるデプロイ

リポジトリを追加
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
分散型 Mimir をインストール
helm install mimir grafana/mimir-distributed \
  --namespace monitoring \
  --values values.yaml
事前構築済みの値ファイル
ファイル目的
values.yamlMinIO を使用した非本番環境でのテスト
small.yaml約 100 万時系列(単一レプリカ、HA なし)
large.yaml本番環境(約 1,000 万時系列)
本番環境向けの値の例
# Deployment mode
mimir:
  structuredConfig:
    multitenancy_enabled: true

# Storage configuration
mimir:
  structuredConfig:
    common:
      storage:
        backend: azure  # or s3, gcs
        azure:
          account_name: ${AZURE_STORAGE_ACCOUNT}
          account_key: ${AZURE_STORAGE_KEY}
          endpoint_suffix: blob.core.windows.net

    blocks_storage:
      azure:
        container_name: mimir-blocks

    alertmanager_storage:
      azure:
        container_name: mimir-alertmanager

    ruler_storage:
      azure:
        container_name: mimir-ruler

# Distributor
distributor:
  replicas: 3
  resources:
    requests:
      cpu: 1
      memory: 2Gi
    limits:
      memory: 4Gi

# Ingester
ingester:
  replicas: 3
  zoneAwareReplication:
    enabled: true
  persistentVolume:
    enabled: true
    size: 50Gi
  resources:
    requests:
      cpu: 2
      memory: 8Gi
    limits:
      memory: 16Gi

# Querier
querier:
  replicas: 3
  resources:
    requests:
      cpu: 1
      memory: 2Gi
    limits:
      memory: 8Gi

# Query Frontend
query_frontend:
  replicas: 2
  resources:
    requests:
      cpu: 500m
      memory: 1Gi
    limits:
      memory: 2Gi

# Query Scheduler
query_scheduler:
  replicas: 2

# Store Gateway
store_gateway:
  replicas: 3
  persistentVolume:
    enabled: true
    size: 20Gi
  resources:
    requests:
      cpu: 500m
      memory: 2Gi
    limits:
      memory: 8Gi

# Compactor
compactor:
  replicas: 1
  persistentVolume:
    enabled: true
    size: 50Gi
  resources:
    requests:
      cpu: 1
      memory: 4Gi
    limits:
      memory: 8Gi

# Gateway for external access
gateway:
  enabledNonEnterprise: true
  replicas: 2

# Monitoring
metaMonitoring:
  serviceMonitor:
    enabled: true

ストレージの設定

重要な要件
  • バケットは手動で作成する必要があります — Mimir はバケットを作成しません
  • バケットは分ける必要があります — blocks_storage、alertmanager_storage、ruler_storage は同じバケットとプレフィックスを共有できません
  • Azure:階層型名前空間を無効にする必要があります
Azure Blob Storage
mimir:
  structuredConfig:
    common:
      storage:
        backend: azure
        azure:
          account_name: <storage-account-name>
          # Option 1: Account Key (via environment variable)
          account_key: ${AZURE_STORAGE_KEY}
          # Option 2: User-Assigned Managed Identity
          # user_assigned_id: <identity-client-id>
          endpoint_suffix: blob.core.windows.net

    blocks_storage:
      azure:
        container_name: mimir-blocks

    alertmanager_storage:
      azure:
        container_name: mimir-alertmanager

    ruler_storage:
      azure:
        container_name: mimir-ruler
AWS S3
mimir:
  structuredConfig:
    common:
      storage:
        backend: s3
        s3:
          endpoint: s3.us-east-1.amazonaws.com
          region: us-east-1
          access_key_id: ${AWS_ACCESS_KEY_ID}
          secret_access_key: ${AWS_SECRET_ACCESS_KEY}

    blocks_storage:
      s3:
        bucket_name: mimir-blocks

    alertmanager_storage:
      s3:
        bucket_name: mimir-alertmanager

    ruler_storage:
      s3:
        bucket_name: mimir-ruler
Google Cloud Storage
mimir:
  structuredConfig:
    common:
      storage:
        backend: gcs
        gcs:
          service_account: ${GCS_SERVICE_ACCOUNT_JSON}

    blocks_storage:
      gcs:
        bucket_name: mimir-blocks

    alertmanager_storage:
      gcs:
        bucket_name: mimir-alertmanager

    ruler_storage:
      gcs:
        bucket_name: mimir-ruler

制限の設定

mimir:
  structuredConfig:
    limits:
      # Ingestion limits
      ingestion_rate: 25000                    # Samples/sec per tenant
      ingestion_burst_size: 50000              # Burst size
      max_series_per_metric: 10000
      max_series_per_user: 1000000
      max_global_series_per_user: 1000000
      max_label_names_per_series: 30
      max_label_name_length: 1024
      max_label_value_length: 2048

      # Query limits
      max_fetched_series_per_query: 100000
      max_fetched_chunks_per_query: 2000000
      max_query_lookback: 0                    # No limit
      max_query_parallelism: 32

      # Retention
      compactor_blocks_retention_period: 365d  # 1 year

      # Out-of-order samples
      out_of_order_time_window: 5m
テナントごとのオーバーライド(ランタイム設定)
# runtime-config.yaml
overrides:
  tenant1:
    ingestion_rate: 50000
    max_series_per_user: 2000000
    compactor_blocks_retention_period: 730d    # 2 years
  tenant2:
    ingestion_rate: 75000
    max_global_series_per_user: 5000000

ランタイム設定を有効にします。

mimir:
  structuredConfig:
    runtime_config:
      file: /etc/mimir/runtime-config.yaml
      period: 10s

高可用性の設定

Prometheus の重複排除向け HA Tracker
mimir:
  structuredConfig:
    distributor:
      ha_tracker:
        enable_ha_tracker: true
        kvstore:
          store: memberlist
        cluster_label: cluster
        replica_label: __replica__

    memberlist:
      join_members:
        - mimir-gossip-ring.monitoring.svc.cluster.local:7946

Prometheus の設定:

global:
  external_labels:
    cluster: prom-team1
    __replica__: replica1

remote_write:
  - url: http://mimir-gateway:8080/api/v1/push
    headers:
      X-Scope-OrgID: my-tenant
ゾーンを考慮したレプリケーション
ingester:
  zoneAwareReplication:
    enabled: true
    zones:
      - name: zone-a
        nodeSelector:
          topology.kubernetes.io/zone: us-east-1a
      - name: zone-b
        nodeSelector:
          topology.kubernetes.io/zone: us-east-1b
      - name: zone-c
        nodeSelector:
          topology.kubernetes.io/zone: us-east-1c

store_gateway:
  zoneAwareReplication:
    enabled: true

シャッフルシャーディング

障害を分離するため、テナントのデータをインスタンスの一部に制限します。

mimir:
  structuredConfig:
    limits:
      # Write path
      ingestion_tenant_shard_size: 3

      # Read path
      max_queriers_per_tenant: 5
      store_gateway_tenant_shard_size: 3

OpenTelemetry との統合

OTLP メトリクスの取り込み

OpenTelemetry Collector の設定:

exporters:
  otlphttp:
    endpoint: http://mimir-gateway:8080/otlp
    headers:
      X-Scope-OrgID: "my-tenant"

service:
  pipelines:
    metrics:
      receivers: [otlp]
      exporters: [otlphttp]
指数ヒストグラム(実験的機能)
// Go SDK configuration
Aggregation: metric.AggregationBase2ExponentialHistogram{
    MaxSize:  160,      // Maximum buckets
    MaxScale: 20,       // Scale factor
}

主なメリット:

  • 最小値と最大値が明示されるため、推定が不要です
  • 極端なパーセンタイルの精度が向上します
  • ネイティブの OTLP 形式を保持します

マルチテナント

mimir:
  structuredConfig:
    multitenancy_enabled: true
    no_auth_tenant: anonymous    # Used when multitenancy disabled

テナントヘッダーを指定したクエリ:

curl -H "X-Scope-OrgID: tenant-a" \
  "http://mimir:8080/prometheus/api/v1/query?query=up"

テナント ID の制約:

  • 最大 150 文字
  • 使用可能:英数字、! - _ . * ' ( )
  • 使用禁止:単独の . または ..、__mimir_cluster、スラッシュ

API リファレンス

取り込みエンドポイント
# Prometheus remote write
POST /api/v1/push

# OTLP metrics
POST /otlp/v1/metrics

# InfluxDB line protocol
POST /api/v1/push/influx/write
クエリエンドポイント
# Instant query
GET,POST /prometheus/api/v1/query?query=<promql>&time=<timestamp>

# Range query
GET,POST /prometheus/api/v1/query_range?query=<promql>&start=<start>&end=<end>&step=<step>

# Labels
GET,POST /prometheus/api/v1/labels
GET /prometheus/api/v1/label/{name}/values

# Series
GET,POST /prometheus/api/v1/series

# Exemplars
GET,POST /prometheus/api/v1/query_exemplars

# Cardinality
GET,POST /prometheus/api/v1/cardinality/label_names
GET,POST /prometheus/api/v1/cardinality/active_series
管理エンドポイント
# Flush ingester data
GET,POST /ingester/flush

# Prepare shutdown
GET,POST,DELETE /ingester/prepare-shutdown

# Ring status
GET /ingester/ring
GET /distributor/ring
GET /store-gateway/ring
GET /compactor/ring

# Tenant stats
GET /distributor/all_user_stats
GET /api/v1/user_stats
GET /api/v1/user_limits
ヘルスと設定
GET /ready
GET /metrics
GET /config
GET /config?mode=diff
GET /runtime_config

Azure ID の設定

ユーザー割り当てのマネージド ID

1. ID を作成します:

az identity create \
  --name mimir-identity \
  --resource-group <rg>

IDENTITY_CLIENT_ID=$(az identity show --name mimir-identity --resource-group <rg> --query clientId -o tsv)
IDENTITY_PRINCIPAL_ID=$(az identity show --name mimir-identity --resource-group <rg> --query principalId -o tsv)

2. ノードプールに割り当てます:

az vmss identity assign \
  --resource-group <aks-node-rg> \
  --name <vmss-name> \
  --identities /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/mimir-identity

3. ストレージのアクセス許可を付与します:

az role assignment create \
  --role "Storage Blob Data Contributor" \
  --assignee-object-id $IDENTITY_PRINCIPAL_ID \
  --scope /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Storage/storageAccounts/<storage>

4. Mimir を設定します:

mimir:
  structuredConfig:
    common:
      storage:
        azure:
          user_assigned_id: <IDENTITY_CLIENT_ID>
ワークロード ID フェデレーション

1. フェデレーション資格情報を作成します:

az identity federated-credential create \
  --name mimir-federated \
  --identity-name mimir-identity \
  --resource-group <rg> \
  --issuer <aks-oidc-issuer-url> \
  --subject system:serviceaccount:monitoring:mimir \
  --audiences api://AzureADTokenExchange

2. Helm の値を設定します:

serviceAccount:
  annotations:
    azure.workload.identity/client-id: <IDENTITY_CLIENT_ID>

podLabels:
  azure.workload.identity/use: "true"

トラブルシューティング

よくある問題

1. コンテナーが見つからない(Azure)

# Create required containers
az storage container create --name mimir-blocks --account-name <storage>
az storage container create --name mimir-alertmanager --account-name <storage>
az storage container create --name mimir-ruler --account-name <storage>

2. 認証に失敗する(Azure)

# Verify RBAC assignment
az role assignment list --scope /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Storage/storageAccounts/<storage>

# Assign if missing
az role assignment create \
  --role "Storage Blob Data Contributor" \
  --assignee-object-id <principal-id> \
  --scope <storage-scope>

# Restart pod to refresh token
kubectl delete pod -n monitoring <ingester-pod>

3. Ingester の OOM

ingester:
  resources:
    limits:
      memory: 16Gi  # Increase memory

4. クエリのタイムアウト

mimir:
  structuredConfig:
    querier:
      timeout: 5m
      max_concurrent: 20

5. カーディナリティが高い

mimir:
  structuredConfig:
    limits:
      max_series_per_user: 5000000
      max_series_per_metric: 50000
診断コマンド
# Check pod status
kubectl get pods -n monitoring -l app.kubernetes.io/name=mimir

# Check ingester logs
kubectl logs -n monitoring -l app.kubernetes.io/component=ingester --tail=100

# Check distributor logs
kubectl logs -n monitoring -l app.kubernetes.io/component=distributor --tail=100

# Verify readiness
kubectl exec -it <mimir-pod> -n monitoring -- wget -qO- http://localhost:8080/ready

# Check ring status
kubectl port-forward svc/mimir-distributor 8080:8080 -n monitoring
curl http://localhost:8080/distributor/ring

# Check configuration
kubectl exec -it <mimir-pod> -n monitoring -- cat /etc/mimir/mimir.yaml

# Validate configuration before deployment
mimir -modules -config.file <path-to-config-file>
監視する主要なメトリクス
# Ingestion rate per tenant
sum by (user) (rate(cortex_distributor_received_samples_total[5m]))

# Series count per tenant
sum by (user) (cortex_ingester_memory_series)

# Query latency
histogram_quantile(0.99, sum by (le) (rate(cortex_request_duration_seconds_bucket{route=~"/api/prom/api/v1/query.*"}[5m])))

# Compactor status
cortex_compactor_runs_completed_total
cortex_compactor_runs_failed_total

# Store-gateway block sync
cortex_bucket_store_blocks_loaded

サーキットブレーカー(Ingester)

mimir:
  structuredConfig:
    ingester:
      push_circuit_breaker:
        enabled: true
        request_timeout: 2s
        failure_threshold_percentage: 10
        cooldown_period: 10s
      read_circuit_breaker:
        enabled: true
        request_timeout: 30s

状態:

  1. Closed - 通常の動作
  2. Open - 障害が発生しているインスタンスへの転送を停止
  3. Half-open - クールダウン後に、試験的なリクエストを限定的に送信

外部リソース


注意事項

  • X-Scope-OrgID によるマルチテナンシー:ヘッダーがない場合、テナント「fake」に警告なく書き込まれます。Loki と同じ落とし穴です。
  • 保持期間はテナントごとに設定されます。グローバルな保持期間の環境変数はフォールバックにすぎず、テナントの設定ミスがあっても警告なく優先されます。
  • Ingester のレプリケーション係数が 3 未満の場合、1 件の障害でデータが失われます。一部の Helm チャートではデフォルトが 1 です。そのまま本番環境に導入しないでください。
  • クエリフロントエンドのキャッシュ TTL を変更すると、キャッシュ済みの結果がすべて無効になります。query_range_results_cache_ttl を変更しても、既存のエントリーの有効期間は延長されません。
  • マルチテナントのストレージパスは、S3 バケットのプレフィックスを共有します。tenant-1 が tenant-2 のパスを読み取れるように誤って許可するのは設定ミスですが、チャートでは防止されません。
  • distributor.ingestion-rate-limit-strategy: global には、正常に動作する memberlist が必要です。警告なく発生する障害モードでは、調整が行われず、ディストリビューターごとの制限が適用されるため、意図したトラフィックの 10 倍まで許可されます。

コメント