> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sambanova.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Prometheus と Grafana による監視

SambaStack の監視・可観測性リファレンスアーキテクチャは、オープンソースコンポーネントを使用して、オンプレミスデプロイメント向けにメトリクス、ログ、ダッシュボードを提供します。本ガイドでは、公式の kube-prometheus-stack Helm チャートを使用して、Prometheus、Grafana、Prometheus Operator、Node Exporter を monitoring 名前空間にデプロイする手順を解説します。

<Note>
  **リファレンスアーキテクチャに関する注意:** このセットアップではサードパーティ製コンポーネント（Prometheus、Grafana など）を使用しています。バージョン、デフォルト値、コマンド構文は変更される可能性があります。SambaStack に固有でない問題については、該当コンポーネントを所有するベンダーまたはプロジェクトにお問い合わせください。
</Note>

## 前提条件

作業を始める前に、以下の要件を満たしていることを確認してください。

* **kubectl** – 対象の Kubernetes クラスターへのアクセスが設定済みであること
* **Helm**（最新バージョン） – `helm version` で確認してください
* **jq** – 動作確認時の JSON 出力の解析に使用
* **monitoring 名前空間** – 存在しない場合は、ステップ 1 で作成します
* **ストレージクラス** – Prometheus の永続ストレージ用の有効なストレージクラス

### 任意の前提条件

* **OpenSearch** – Grafana でログを可視化する場合にのみ必要です。OpenSearch 連携を含めてデプロイする場合は、先に [OpenSearch のデプロイ](/docs/ja/sambastack/reference-architecture/observability/log-storage) を完了してください。`opensearch-initial-admin-password` Secret が存在している必要があります。

<Info>
  **デプロイ順序:** フルモニタリングスタックを使用する場合は、OpenSearch → Fluent Bit → Prometheus/Grafana の順にデプロイしてください。メトリクスのみが必要な場合（ログの可視化が不要な場合）は、Prometheus/Grafana を単独でデプロイできます。
</Info>

## リソース要件

以下は、モニタリングスタックの最小リソース推奨値です。

| コンポーネント | CPU リクエスト | メモリリクエスト | ストレージ |
| - | - | - | - |
| Prometheus（レプリカごと） | 500m | 2Gi | 30Gi |
| Grafana | 250m | 512Mi | – |
| Node Exporter（ノードごと） | 100m | 128Mi | – |
| Prometheus Operator | 200m | 256Mi | – |

<Note>
  大規模なデプロイメント（100 ノード以上、または高カーディナリティのメトリクス）では、Prometheus のメモリを 4〜8Gi、ストレージを 50〜100Gi に増やしてください。合わせて、values ファイルの `retentionSize` も調整してください。
</Note>

## アーキテクチャ概要

| コンポーネント | 役割 |
| - | - |
| **Prometheus** | SambaStack サービスとクラスターノードから時系列メトリクスを収集・保存 |
| **Prometheus Operator** | Kubernetes の CRD（ServiceMonitor など）を通じて Prometheus の設定を管理 |
| **Node Exporter** | Prometheus がスクレイプする、ノード/ラックレベルのホストメトリクスを公開 |
| **Grafana** | Prometheus のメトリクスと OpenSearch のログをダッシュボードで可視化 |

### データフロー

**メトリクスの経路:**

> SambaStack サービス / Node Exporter → /metrics → Prometheus → Grafana ダッシュボード

**ログの経路（OpenSearch が必要）:**

> Pod / システムログ → Fluent Bit → OpenSearch → Grafana（ログパネル）

## デプロイ手順

### ステップ 1: monitoring 名前空間の作成

OpenSearch のデプロイによって名前空間がすでに存在する場合は、このステップをスキップしてください。

`~/.sambastack-observability/monitoring-namespace.yaml` に名前空間の設定ファイルを作成します。

```yaml theme={}
# monitoring-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: monitoring
```

設定を適用します。

```bash theme={}
kubectl apply -f monitoring-namespace.yaml
```

### ステップ 2: Helm リポジトリの追加

```bash theme={}
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
```

### ステップ 3: Grafana 管理者認証情報の Secret の作成

base64 エンコードしたユーザー名とパスワードを含む Secret を、`~/.sambastack-observability/monitoring/grafana-initial-admin-credentials-secret.yaml` に作成します。

```yaml theme={}
# grafana-initial-admin-credentials-secret.yaml
apiVersion: v1
data:
  admin-user: <base64-encoded-username>
  admin-password: <base64-encoded-password>
kind: Secret
metadata:
  name: grafana-initial-admin-credentials
  namespace: monitoring
type: Opaque
```

<Tip>
  値を base64 エンコードするには: `echo -n 'your-value' | base64`
</Tip>

Secret を適用します。

```bash theme={}
kubectl -n monitoring apply -f grafana-initial-admin-credentials-secret.yaml
```

### ステップ 4: values ファイルの作成

`~/.sambastack-observability/monitoring/prometheus-grafana-values.yaml` を作成します。OpenSearch と連携するかどうかに応じて、適切な設定を選択してください。

<Tabs>
  <Tab title="OpenSearch 連携あり">
    OpenSearch をデプロイ済みで、Grafana でログを可視化する場合は、こちらの設定を使用します。

    <Warning>
      この設定では、`monitoring` 名前空間に `opensearch-initial-admin-password` Secret が存在している必要があります。詳細は [ログストレージ - OpenSearch](/docs/ja/sambastack/reference-architecture/observability/log-storage) をご参照ください。
    </Warning>

    <Accordion title="values ファイル全文を表示（OpenSearch あり）">
      ```yaml theme={}
      # prometheus-grafana-values.yaml (with OpenSearch)
      alertmanager:
        enabled: false
      kubeStateMetrics:
        enabled: false
      kubernetesServiceMonitors:
        enabled: false
      defaultRules:
        create: false
      nodeExporter:
        enabled: true
      prometheusOperator:
        serviceMonitor:
          selfMonitor: false
        nodeSelector: {}
        tolerations: []
        tls:
          enabled: false
        admissionWebhooks:
          enabled: false
      prometheus:
        enabled: true
        serviceMonitor:
          selfMonitor: false
        prometheusSpec:
          replicas: 2
          nodeSelector: {}
          tolerations: []
          serviceMonitorSelector:
            matchLabels: {}
          ruleSelector:
            matchLabels: {}
          scrapeConfigSelector:
            matchLabels: {}
          retentionSize: 25GB
          storageSpec:
            volumeClaimTemplate:
              spec:
                storageClassName: <your-storage-class>
                resources:
                  requests:
                    storage: 30Gi
      grafana:
        enabled: true
        defaultDashboardsEnabled: false
        serviceMonitor:
          enabled: false
        admin:
          existingSecret: grafana-initial-admin-credentials
          userKey: admin-user
          passwordKey: admin-password
        extraEnvs:
        - name: OPENSEARCH_INITIAL_ADMIN_PASSWORD
          valueFrom:
            secretKeyRef:
              name: opensearch-initial-admin-password
              key: OPENSEARCH_INITIAL_ADMIN_PASSWORD
        plugins:
        - grafana-opensearch-datasource
        datasources:
          datasources.yaml:
            apiVersion: 1
            datasources:
              - name: Prometheus
                type: prometheus
                access: proxy
                url: http://kube-prometheus-stack-prometheus:9090
                isDefault: false
              - name: OpenSearch-Logs
                type: grafana-opensearch-datasource
                access: proxy
                url: https://opensearch-cluster-master.{{ .Release.Namespace }}.svc.cluster.local:9200
                withCredentials: true
                basicAuth: true
                basicAuthUser: admin
                basicAuthPassword: $__env{OPENSEARCH_INITIAL_ADMIN_PASSWORD}
                editable: true
                readOnly: false
                jsonData:
                  timeField: "@timestamp"
                  database: logs-7d
                  tlsSkipVerify: true
                  logLevelField: log_level
                  logMessageField: message
                  version: 3.3.2
                  versionLabel: OpenSearch 3.3.2
                  flavor: opensearch
                  maxConcurrentShardRequests: 5
                  pplEnabled: true
                  serverless: false
      ```
    </Accordion>
  </Tab>

  <Tab title="OpenSearch なし（メトリクスのみ）">
    ログの可視化が不要で、Prometheus メトリクスのみが必要な場合は、こちらの設定を使用します。

    <Accordion title="values ファイル全文を表示（メトリクスのみ）">
      ```yaml theme={}
      # prometheus-grafana-values.yaml (metrics only)
      alertmanager:
        enabled: false
      kubeStateMetrics:
        enabled: false
      kubernetesServiceMonitors:
        enabled: false
      defaultRules:
        create: false
      nodeExporter:
        enabled: true
      prometheusOperator:
        serviceMonitor:
          selfMonitor: false
        nodeSelector: {}
        tolerations: []
        tls:
          enabled: false
        admissionWebhooks:
          enabled: false
      prometheus:
        enabled: true
        serviceMonitor:
          selfMonitor: false
        prometheusSpec:
          replicas: 2
          nodeSelector: {}
          tolerations: []
          serviceMonitorSelector:
            matchLabels: {}
          ruleSelector:
            matchLabels: {}
          scrapeConfigSelector:
            matchLabels: {}
          retentionSize: 25GB
          storageSpec:
            volumeClaimTemplate:
              spec:
                storageClassName: <your-storage-class>
                resources:
                  requests:
                    storage: 30Gi
      grafana:
        enabled: true
        defaultDashboardsEnabled: false
        serviceMonitor:
          enabled: false
        admin:
          existingSecret: grafana-initial-admin-credentials
          userKey: admin-user
          passwordKey: admin-password
        datasources:
          datasources.yaml:
            apiVersion: 1
            datasources:
              - name: Prometheus
                type: prometheus
                access: proxy
                url: http://kube-prometheus-stack-prometheus:9090
                isDefault: true
      ```
    </Accordion>
  </Tab>
</Tabs>

<Note>
  `<your-storage-class>` は、クラスターのストレージクラスに置き換えてください。利用可能なストレージクラスの確認: `kubectl get storageclass`
</Note>

### コンポーネント設定の概要

| コンポーネント | 状態 | 役割 |
| - | - | - |
| Prometheus | ✓ 有効 | メトリクスの保存とクエリ |
| Prometheus Operator | ✓ 有効 | CRD を通じた Prometheus 設定の管理 |
| Grafana | ✓ 有効 | メトリクスとログの可視化 |
| Node Exporter | ✓ 有効 | ノード/ラックレベルのホストメトリクス |
| Alertmanager | ✗ 無効 | この最小構成のリファレンスでは無効 |

### ステップ 5: kube-prometheus-stack のインストール

Helm のインストールコマンドを実行します。

```bash theme={}
helm upgrade --install kube-prometheus-stack \
  prometheus-community/kube-prometheus-stack \
  --version 60.2.0 \
  -n monitoring \
  -f prometheus-grafana-values.yaml
```

これにより、Prometheus、Prometheus Operator、Node Exporter、Grafana がデプロイされます。

### ステップ 6: 推論ルーター用 ServiceMonitor の作成

Prometheus は、ServiceMonitor を使用して SambaStack の推論ルーターを検出し、メトリクスをスクレイプします。`~/.sambastack-observability/monitoring/inference-router-sm.yaml` に以下のファイルを作成します。

```yaml theme={}
# inference-router-sm.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: inference-router-sm
  namespace: monitoring
spec:
  endpoints:
    - interval: 30s
      port: inference-router
      path: /v1/metrics
  selector:
    matchLabels:
      sambanova.ai/app: inference-router
```

ServiceMonitor を適用します。

```bash theme={}
kubectl apply -f inference-router-sm.yaml
```

## 動作確認

### Pod ステータスの確認

Prometheus の Pod を確認します。

```bash theme={}
kubectl -n monitoring get pods -l app.kubernetes.io/name=prometheus
```

期待される出力:

```text theme={}
NAME                                    READY   STATUS    RESTARTS   AGE
prometheus-kube-prometheus-stack-prometheus-0   2/2     Running   0          5m
prometheus-kube-prometheus-stack-prometheus-1   2/2     Running   0          5m
```

Grafana の Pod を確認します。

```bash theme={}
kubectl -n monitoring get pods -l app.kubernetes.io/name=grafana
```

期待される出力:

```text theme={}
NAME                                          READY   STATUS    RESTARTS   AGE
kube-prometheus-stack-grafana-XXXXX-XXXXX     1/1     Running   0          5m
```

Node Exporter の Pod を確認します。

```bash theme={}
kubectl -n monitoring get pods -l app.kubernetes.io/name=prometheus-node-exporter
```

### UI へのアクセス

<Tabs>
  <Tab title="Prometheus">
    Prometheus をポートフォワードします。

    ```bash theme={}
    kubectl -n monitoring port-forward svc/kube-prometheus-stack-prometheus 9090:9090 &
    ```

    アクセス先: [http://localhost:9090](http://localhost:9090)

    停止するには: `pkill -f "port-forward.*9090"`
  </Tab>

  <Tab title="Grafana">
    Grafana をポートフォワードします。

    ```bash theme={}
    kubectl -n monitoring port-forward svc/kube-prometheus-stack-grafana 8080:80 &
    ```

    アクセス先: [http://localhost:8080](http://localhost:8080)

    停止するには: `pkill -f "port-forward.*8080"`
  </Tab>
</Tabs>

### Grafana 認証情報の取得

```bash theme={}
kubectl -n monitoring get secret grafana-initial-admin-credentials -o json \
  | jq -r '.data | to_entries[] | "\(.key): \(.value | @base64d)"'
```

### Prometheus ターゲットの確認

1. [http://localhost:9090](http://localhost:9090) で Prometheus UI にアクセスします
2. **Status → Targets** に移動します
3. `node-exporter` ターゲットが UP と表示されることを確認します
4. `inference-router-sm` ターゲットが UP と表示されることを確認します（SambaStack が稼働している場合）

### Grafana データソースの確認

1. [http://localhost:8080](http://localhost:8080) で Grafana にログインします
2. **Connections → Data sources** に移動します
3. **Prometheus** データソースに「Data source is working」と表示されることを確認します
4. OpenSearch 連携を使用している場合は、**OpenSearch-Logs** データソースに「Data source is working」と表示されることを確認します

***

## 成功基準

以下の条件を満たしていれば、インストールは完了です。

* `monitoring` 名前空間で Prometheus の Pod（2 レプリカ）が稼働している
* Grafana の Pod が稼働しており、アクセスできる
* すべてのノードで Node Exporter の Pod が稼働している
* Prometheus で Node Exporter のターゲットが UP と表示される
* 設定した管理者認証情報で Grafana にログインできる
* Grafana の Prometheus データソースに「Data source is working」と表示される
* （設定した場合）Grafana の OpenSearch データソースに「Data source is working」と表示される

## Node Exporter ダッシュボードのインポート

Node Exporter が公開するノード/ラックレベルのメトリクスを可視化するには、次の手順を実行します。

<Steps>
  <Step title="Grafana にログイン">
    動作確認セクションで取得した認証情報を使用します。
  </Step>

  <Step title="Import に移動">
    **Dashboards → New → Import** に移動します。
  </Step>

  <Step title="ダッシュボードのインポート">
    ダッシュボード ID `1860` を入力し、**Load** をクリックします。
  </Step>

  <Step title="データソースの選択">
    データソースとして **Prometheus** を選択し、**Import** をクリックします。
  </Step>
</Steps>

このダッシュボードには、CPU 使用率、メモリ使用率、ディスク I/O、ネットワークメトリクス、ノードの正常性が含まれます。

<Info>
  ダッシュボード ID 1860 は、コミュニティ製の「Node Exporter Full」ダッシュボードです。SambaStack デプロイメントにおけるラック単位の可視化に最適です。
</Info>

## 設定リファレンス

| パラメータ | デフォルト値 | 説明 |
| - | - | - |
| `prometheus.prometheusSpec.replicas` | 2 | 高可用性のための Prometheus レプリカ数 |
| `prometheus.prometheusSpec.retentionSize` | 25GB | 最も古いデータが削除され始めるまでの最大ストレージ容量 |
| `prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.resources.requests.storage` | 30Gi | Prometheus データ用の PVC サイズ |
| `grafana.admin.existingSecret` | grafana-initial-admin-credentials | 管理者認証情報を含む Secret |
| `nodeExporter.enabled` | true | Node Exporter の DaemonSet をデプロイ |

## トラブルシューティング

### Prometheus の Pod が Pending のまま進まない

**症状:** Prometheus の Pod が `Pending` 状態のまま進まない。

**原因:** PersistentVolumeClaim を満たすことができない。

**対処方法:**

```bash theme={}
# Check PVC status
kubectl -n monitoring get pvc

# Verify storage class exists
kubectl get storageclass
```

### Grafana で OpenSearch データソースが「Data source is not working」になる

**症状:** Grafana で OpenSearch データソースのテストが失敗する。

**考えられる原因:**

1. **OpenSearch が未デプロイ:** 先に OpenSearch をデプロイしてください。詳細は [ログストレージ - OpenSearch](/docs/ja/sambastack/reference-architecture/observability/log-storage) をご参照ください。

2. **Secret の欠落:** Secret が存在することを確認します。
   ```bash theme={}
   kubectl -n monitoring get secret opensearch-initial-admin-password
   ```

3. **OpenSearch が起動していない:** OpenSearch の Pod ステータスを確認します。
   ```bash theme={}
   kubectl -n monitoring get pod opensearch-cluster-master-0
   ```

### ServiceMonitor がターゲットをスクレイプしない

**症状:** カスタム ServiceMonitor のターゲットが Prometheus に表示されない。

**対処方法:** ServiceMonitor が `monitoring` 名前空間にあり、ラベルが一致していることを確認します。

```bash theme={}
kubectl -n monitoring get servicemonitor
kubectl -n monitoring describe servicemonitor inference-router-sm
```

### Node Exporter の Pod が一部のノードで起動しない

**症状:** Node Exporter の Pod 数がクラスターのノード数より少ない。

**原因:** ノードに taint が設定されており、スケジューリングが妨げられている可能性があります。

**対処方法:** Node Exporter の設定に toleration を追加するか、ノードの taint を削除してください。

## 次のステップ

Prometheus と Grafana が稼働したら、次に進みます。

1. **カスタムダッシュボードの作成** – 推論レイテンシ、QPS、アクセラレーター使用率など、SambaStack 固有のメトリクスのダッシュボードを構築します。

2. **ServiceMonitor の追加** – Prometheus メトリクスを公開する他の SambaStack コンポーネント用に、ServiceMonitor を作成します。

3. **アラートの有効化** – 本番の監視用に Alertmanager を設定します。values ファイルで `alertmanager.enabled: true` を設定してください。

4. **ログの探索** – OpenSearch と Fluent Bit がデプロイされている場合は、Grafana の Explore 機能で `logs-7d` インデックスをクエリできます。

## クリーンアップ

クラスターからモニタリングスタックを削除するには、以下を実行します。

Helm リリースをアンインストールします。

```bash theme={}
helm uninstall kube-prometheus-stack -n monitoring
```

Grafana 認証情報の Secret を削除します。

```bash theme={}
kubectl delete secret grafana-initial-admin-credentials -n monitoring
```

ストレージを解放するために、Prometheus の PersistentVolumeClaim を削除します。

```bash theme={}
kubectl -n monitoring delete pvc -l app.kubernetes.io/name=prometheus
```

ServiceMonitor を削除します。

```bash theme={}
kubectl delete servicemonitor inference-router-sm -n monitoring
```

<Warning>
  PVC を削除すると、保存されているメトリクスデータがすべて完全に削除されます。事前に、重要なメトリクスをエクスポート済みであることを確認してください。
</Warning>

<Note>
  OpenSearch や Fluent Bit を含むモニタリングスタック全体を削除する場合は、名前空間ごと削除できます: `kubectl delete namespace monitoring`。これによりすべてのリソースが削除され、元に戻すことはできません。
</Note>
