Contents
1. Prometheus が Kubernetes 監視の中心になる理由
Kubernetes クラスタで可用性を保つには、コンポーネントやアプリケーションの状態をリアルタイムに把握できる仕組みが不可欠です。Prometheus はプル方式と豊富なエクスポーターにより、クラスタ全体・各ワークロードのメトリクスを統一的に取得・保存します。本セクションでは、主要コンポーネントの役割と Operator が提供する CRD(ServiceMonitor / PodMonitor など)を俯瞰し、監視基盤全体像をつかむためのポイントを整理します。
1‑1. データ取得モデルと主要コンポーネント
Prometheus のデータ収集は「pull」が基本です。対象エンドポイント(/metrics)に対して定期的にスクレイピングし、時系列データベースに格納します。その上で以下の補助コンポーネントがメトリクス提供を担います。
| コンポーネント | 主な役割 | 代表的なエクスポート先 |
|---|---|---|
| Prometheus Server | スクレイピング・保存・PromQL クエリ実行 | http://prometheus-operated:9090 |
| kube‑state‑metrics | Kubernetes オブジェクト(Deployment、Pod など)の状態を OpenMetrics 形式で公開 | http://kube-state-metrics:8080/metrics |
| node‑exporter | ノードレベルのハードウェア指標(CPU、メモリ、ディスク I/O 等)を提供 | http://node-exporter:9100/metrics |
1‑2. Operator が提供する CRD の役割
Operator は 宣言的に監視対象を管理 できるよう、以下の CRD を導入しています。これらは ServiceMonitor / PodMonitor といったリソースでスクレイピング設定を記述し、Pod の増減に自動追従します。
| CRD | 用途 | 主なフィールド例 |
|---|---|---|
| ServiceMonitor | Service オブジェクト単位でスクレイピング設定 |
selector, endpoints, scrapeInterval |
| PodMonitor | ラベルでマッチした Pod を直接対象化 | podMetricsEndpoints, relabelings |
| Prometheus | Prometheus 本体のデプロイ・設定を宣言的に管理 | version, storageSpec, resources |
2. Helm(v3.14)で kube‑prometheus‑stack を安全にインストール
Helm は Kubernetes 上のアプリケーションパッケージングツールとして事実上の標準です。2024 年末時点で安定リリースされている Helm v3.14 と、公式チャート prometheus-community/kube-prometheus-stack を組み合わせると、TLS・RBAC がデフォルトで有効化された監視スタックを数分で構築できます。
2‑1. 前提条件とリポジトリ設定
まずは Helm と kubectl のバージョンが要件を満たすことを確認します。以下のコマンドは Helm v3.14+ が前提です。
|
1 2 3 4 |
# バージョン確認(例) helm version --short # → v3.14.2 kubectl version --client -o yaml | grep gitVersion |
次に公式チャートリポジトリを追加し、最新バージョンを取得します。
|
1 2 3 4 5 |
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update # 利用可能な最新版(2024‑10 時点)を確認 helm search repo prometheus-community/kube-prometheus-stack --versions | head -n 5 |
最新情報: 公式ドキュメントは常に更新されています。詳細は https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack を参照してください。
2‑2. カスタム values.yaml の設計指針
以下は 最小構成 としつつ、セキュリティ・スケーラビリティを考慮した設定例です。実運用ではワークロード規模に合わせて resources や nodeSelector を調整してください。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# values.yaml(抜粋) prometheus: enabled: true version: "v2.53.0" # 2024‑10 時点の最新安定版 resources: requests: cpu: 500m memory: 1Gi limits: cpu: 2 memory: 4Gi storageSpec: volumeClaimTemplate: spec: storageClassName: gp3 # 高速 SSD 推奨 accessModes: ["ReadWriteOnce"] resources: requests: storage: 50Gi podSecurityContext: runAsNonRoot: true fsGroup: 65534 alertmanager: enabled: true version: "v0.27.0" config: global: resolve_timeout: 5m route: receiver: slack receivers: - name: slack slack_configs: - api_url: https://hooks.slack.com/services/XXXXX/XXXXX/XXXXX channel: "#alerts" grafana: enabled: true adminPassword: "ChangeMe123!" sidecar: dashboards: enabled: true kubeStateMetrics: enabled: true version: "v2.11.0" nodeExporter: enabled: true version: "v1.8.0" |
カスタマイズのチェックポイント
| 項目 | 推奨設定 | 理由 |
|---|---|---|
resources.requests |
CPU 500 m、Memory 1 Gi | 小規模クラスターで安定稼働を保証 |
storageSpec.volumeClaimTemplate.storage |
50 Gi(gp3) | 長期保存が必要なメトリクスに最適 |
podSecurityContext.runAsNonRoot |
true |
2024‑10 の CNCF セキュリティガイドラインに準拠 |
alertmanager.config.global.resolve_timeout |
5m |
アラートの自動解決遅延を最小化 |
インストールは次のコマンドで実行します。
|
1 2 3 4 |
helm install kube-prom-stack prometheus-community/kube-prometheus-stack \ -n monitoring --create-namespace \ -f values.yaml |
3. ServiceMonitor / PodMonitor のベストプラクティスとカスタムエクスポーター
CRD を活用すれば、コード変更なしで監視対象を追加・削除できます。本節ではラベル設計のポイント、実装例、および Go 言語で作成したシンプルな OpenMetrics エクスポーターを紹介します。
3‑1. ラベル設計と名前空間選定
- Namespace の明示的指定:
namespaceSelector.matchNamesに監視対象の Namespace を列挙し、他環境への漏洩を防止。 - アプリ固有ラベル:
app.kubernetes.io/nameなど標準ラベルに加えて、monitoring=trueのようなスイッチラベルを付与すると管理が楽です。
3‑2. ServiceMonitor の実装例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: payment-svc-monitor namespace: monitoring labels: release: kube-prom-stack spec: selector: matchLabels: app.kubernetes.io/name: payment-service namespaceSelector: matchNames: - production endpoints: - port: metrics # Service が公開しているポート名 interval: 30s scrapeTimeout: 10s |
ポイント
- interval は過剰取得を防ぐため 30 秒 を推奨。
- scrapeTimeout はエンドポイントの応答時間に余裕を持たせる(10 秒)
3‑3. PodMonitor の実装例(動的ワーカーポッド)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
apiVersion: monitoring.coreos.com/v1 kind: PodMonitor metadata: name: payment-worker-monitor namespace: monitoring spec: selector: matchLabels: app.kubernetes.io/name: payment-worker podMetricsEndpoints: - port: metrics interval: 30s metricRelabelings: - sourceLabels: [__name__] regex: 'go_.*' action: drop # Go ランタイム指標は除外例 |
3‑4. カスタムエクスポーター(Go)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
package main import ( "net/http" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" ) var ( requests = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "myapp_requests_total", Help: "Processed request count by path and method", }, []string{"path", "method"}, ) ) func init() { prometheus.MustRegister(requests) } func handler(w http.ResponseWriter, r *http.Request) { requests.WithLabelValues(r.URL.Path, r.Method).Inc() w.Write([]byte("OK")) } func main() { http.Handle("/metrics", promhttp.Handler()) http.HandleFunc("/", handler) if err := http.ListenAndServe(":8080", nil); err != nil { panic(err) } } |
prometheus/client_golangが/metricsエンドポイントを自動で公開。- Deployment に
app: myapp-exporterラベルを付与すれば、上記 PodMonitor が即座にスクレイピング対象となります。
4. セキュリティ強化:RBAC 最小権限と mTLS(cert‑manager)
監視基盤は内部コンポーネント同士の通信が多いため、最小権限の RBAC と TLS による暗号化を必ず導入します。本節では実装例と注意点を示します。
4‑1. Prometheus Operator 用最小 RBAC
以下は ClusterRole と ClusterRoleBinding の最小構成です。prometheus-operator が必要とする API リソースだけに絞っています。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: prometheus-operator-minimal rules: # Pod・Service 等の監視対象取得 - apiGroups: [""] resources: ["pods", "services", "endpoints", "nodes"] verbs: ["get", "list", "watch"] # Operator が管理する CRD(Prometheus, ServiceMonitor, etc.) - apiGroups: ["monitoring.coreos.com"] resources: - prometheus - servicemonitors - podmonitors - alertmanagers verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: prometheus-operator-minimal-binding subjects: - kind: ServiceAccount name: prometheus-operator namespace: monitoring roleRef: kind: ClusterRole name: prometheus-operator-minimal apiGroup: rbac.authorization.k8s.io |
ポイント
monitoring.coreos.comは Operator が独自に定義する API グループです。不要な*権限は削除し、create/patch/deleteを必要最小限のリソースだけに限定します。
4‑2. cert‑manager による自己署名 ClusterIssuer と TLS シークレット
まず cert‑manager 本体をインストールします(Helm v3.14 推奨)。
|
1 2 3 4 5 6 7 8 |
helm repo add jetstack https://charts.jetstack.io helm repo update helm install cert-manager jetstack/cert-manager \ --namespace cert-manager --create-namespace \ --version v1.14.0 \ --set installCRDs=true |
自己署名 ClusterIssuer の作成例
|
1 2 3 4 5 6 7 |
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: selfsigned-clusterissuer spec: selfSigned: {} |
Prometheus 用 TLS シークレット生成(Certificate リソース)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: prometheus-tls namespace: monitoring spec: secretName: prometheus-tls-secret dnsNames: - prometheus.monitoring.svc - prometheus.monitoring.svc.cluster.local issuerRef: name: selfsigned-clusterissuer kind: ClusterIssuer |
values.yaml の prometheus.prometheusSpec.tlsConfig に上記シークレットを参照させ、ServiceMonitor 側でも同様に tlsConfig を設定すれば mTLS が有効になります。
|
1 2 3 4 5 6 7 8 9 10 11 12 |
# values.yaml 追加部 prometheus: prometheusSpec: tlsConfig: caFile: /etc/prometheus/tls/ca.crt certFile: /etc/prometheus/tls/tls.crt keyFile: /etc/prometheus/tls/tls.key secretMounts: - name: prometheus-tls-secret mountPath: /etc/prometheus/tls readOnly: true |
5. データ永続化と長期保存(PVC + remote_write)
5‑1. 永続ボリュームの推奨設定
|
1 2 3 4 5 6 7 8 9 10 |
prometheus: storageSpec: volumeClaimTemplate: spec: storageClassName: gp3 # 高スループット SSD accessModes: ["ReadWriteOnce"] resources: requests: storage: 100Gi # 1 年程度の標準保存量想定 |
5‑2. remote_write による長期ストレージ連携
Prometheus のローカルディスクが逼迫する前に、外部の長期保存基盤へデータを送ります。代表的なオープンソースは Thanos と Mimir です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
remoteWrite: - url: https://thanos-receiver.example.com/api/v1/receive tlsConfig: insecureSkipVerify: false queueConfig: maxSamplesPerSend: 5000 - url: https://mimir.example.com/api/v1/push basicAuth: username: admin passwordFromSecret: name: mimir-credentials key: password |
備考:
basicAuth.passwordFromSecretは Kubernetes Secret から安全に参照する方法です。平文で記載しないよう注意してください。
6. Alertmanager の高度な通知設定
Alertmanager はアラートの集約・抑制・ルーティングを担当します。以下は Slack と Microsoft Teams 両方に通知できるテンプレート例です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
apiVersion: v1 kind: ConfigMap metadata: name: alertmanager-config namespace: monitoring data: alertmanager.yml: | global: resolve_timeout: 5m route: group_by: ['alertname', 'cluster'] group_wait: 30s group_interval: 5m repeat_interval: 1h receiver: slack-teams-multi receivers: - name: slack-teams-multi slack_configs: - api_url: https://hooks.slack.com/services/XXXXX/XXXXX/XXXXX channel: '#alerts' title: "[{{ .Status }}] {{ .Labels.alertname }}" webhook_configs: - url: https://outlook.office.com/webhook/XXXXX/IncomingWebhook/... inhibit_rules: - source_match: severity: 'critical' target_match: severity: 'warning' equal: ['alertname', 'cluster'] |
- 抑制ルールで
critical→warningの重複通知を防止。 webhook_configsを併用すれば Teams への同時送信が可能です。
7. Grafana による可視化と障害診断フロー
Grafana は Prometheus データのダッシュボード表示に最適です。kube‑prometheus‑stack に同梱された Sidecar が ConfigMap の変化を検知し、Dashboard を自動ロードします。
7‑1. 公式ダッシュボードインポート手順
- Grafana UI に
adminユーザーでログイン(パスワードはvalues.yamlのgrafana.adminPassword)。 - メニュー Create → Import を選択。
- 「Grafana.com」から ID 3150(Kubernetes Cluster Monitoring)を入力し、データソースとして
Prometheusを指定。
7‑2. カスタムパネル例(自作エクスポーター指標)
|
1 2 3 4 5 6 7 8 |
type: graph title: MyApp Requests per Minute datasource: Prometheus targets: - expr: rate(myapp_requests_total[1m]) legendFormat: "{{path}} {{method}}" interval: "" |
rate(...[1m])により 1 分間のリクエスト増加率を可視化。- ラベル埋め込みでパス別・メソッド別に即座にフィルタリング可能。
7‑3. 障害診断チェックリスト
| 症状 | 確認手順 | 主な原因例 | 推奨対処 |
|---|---|---|---|
| Pod が CrashLoopBackOff | kubectl describe pod <pod> -n monitoringkubectl logs <pod> -p |
起動スクリプトエラー、リソース不足 | リソースリクエスト増加、ログでスタックトレース確認 |
| Prometheus が Scrape エラー | Prometheus UI → Targets で赤丸確認kubectl logs prometheus-<id> -n monitoring |
ServiceMonitor ラベル不一致、TLS シークレット欠如 | ラベル・Namespace を再確認、TLS 秘密情報の有無を検証 |
| Alert が届かない | curl -s http://alertmanager:9093/api/v2/alertskubectl get secret alertmanager-config -o yaml |
Receiver 名ミスマッチ、Webhook URL 無効 | Receiver 設定と URL を再確認、NetworkPolicy の許可範囲をチェック |
| Grafana がデータ取得できない | Grafana → Data Sources で「Test」実行kubectl port-forward svc/prometheus-operated 9090 |
Prometheus Service 名変更、NetworkPolicy 制限 | Service 名とポートの正当性確認、Policy に例外ルール追加 |
診断フロー: UI/CLI → ログ取得 → CRD 定義比較 → ネットワーク・RBAC・TLS の切り分け という順序で問題を局所化します。
8. まとめ
- Prometheus + Operator が Kubernetes 環境のメトリクス収集基盤として最も成熟している。
- Helm v3.14 と公式 kube‑prometheus‑stack チャート を利用すれば、TLS・RBAC がデフォルトで有効化された安全なスタックを数分で構築できる。
- ServiceMonitor / PodMonitor にラベルと Namespace のベストプラクティスを適用し、カスタムエクスポーターを自作すれば任意のマイクロサービスも即座に監視対象になる。
- 最小権限 RBAC と cert‑manager による mTLS が内部通信のセキュリティ基盤となり、監査要件も満たせる。
- PVC + remote_write でローカル保存と長期外部保存を両立し、データ喪失リスクを低減できる。
- Alertmanager の高度なテンプレート と Grafana ダッシュボード により、インシデント検知から可視化・対応までのフローが一体化する。
上記手順とベストプラクティスをそのまま自環境に適用すれば、2024‑10 時点で セキュアかつ拡張性の高い Prometheus 監視基盤 が構築できます。継続的なバージョンアップと設定見直しを行うことで、将来的な機能追加や脅威への対応もスムーズに進められます。
参考リンク
| 内容 | URL |
|---|---|
| Prometheus Operator GitHub(最新リリース) | https://github.com/prometheus-operator/prometheus-operator/releases |
| Helm Chart – kube‑prometheus‑stack | https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack |
| cert‑manager 公式ドキュメント | https://cert-manager.io/docs/ |
| Grafana Dashboard Hub(ID 3150) | https://grafana.com/grafana/dashboards/3150 |
| CNCF Security Best Practices (2024) | https://github.com/cncf/tag-security/blob/main/README.md |