動的なスコープ検出の設定
Kubernetes クラスター内では、Service や Pod が頻繁に作成および削除されます。手動で各ターゲットに対応する ServiceMonitor リソースを作成・管理するのは、スケールする環境においては非現実的です。Prometheus Operator は、標準的な追加スクリプト設定を用いることで、この作業を自動化する機能を提供しています。
特定のアノテーションを持つ Service を自動的にターゲットとして見つけ出すためには、`additionalScrapeConfigs` パラメータを利用します。具体的には、`kubernetes_sd_configs` を使用し、対象となる Service に対して `prometheus.io/scrape=true` というラベルが付与されているかどうかを検知します。
まずは、以下のような構成定義を用意します。ここでは名前を変えて、job 名を「k8s-auto-scrape」とし、ターゲット識別ロジックを維持しつつ変数名を変更しました。
scrape_targets.yaml: |
- job_name: 'k8s-auto-scrape'
kubernetes_sd_configs:
- role: endpoints
relabel_configs:
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
action: replace
target_label: __scheme__
regex: (https?)
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
action: replace
target_label: __address__
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
- action: labelmap
regex: __meta_kubernetes_service_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_service_name]
action: replace
target_label: kubernetes_name
この YAML ファイルをベース64エンコードして、Kubernetes の Secret オブジェクトとして格納します。以下は、コマンドラインでの実装手順です。
kubectl create secret generic k8s-extra-scrape --from-file=scrape_targets.yaml -n monitoring
生成されたシークレットを確認すると、`scrape_targets.yaml` キーに相当する値が Base64 で格納されていることが確認できます。その後、Prometheus のカスタマレジストリ定義(CRD)ファイルに、このシークレットへの参照を追加する必要があります。
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
name: monitor-main
namespace: monitoring
spec:
# その他の設定...
additionalScrapeConfigs:
name: k8s-extra-scrape
key: scrape_targets.yaml
secrets:
- etcd-certs
# リテンションや警告設定などもここに記述
RBAC 権限の確認
設定を適用した直後に Prometheus デッシュボードを確認すると、ターゲットリストに新しいジョブが表示されない場合があります。これは通常、Pod が API サーバーの Kubernetes エンドポイントをリストする権限を持っていないことが原因です。
Pod のログを確認すると、「services is forbidden」や「pods is forbidden」といったエラーメッセージが出力されているはずです。これは、Prometheus の ServiceAccount が持つ ClusterRole に不足している権限を補完する必要があります。
該当するロール定義を更新し、以下の権限を追加します。
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: prom-monitor-role
rules:
- apiGroups:
- ""
resources:
- nodes
- services
- endpoints
- pods
- nodes/proxy
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- configmaps
- nodes/metrics
verbs:
- get
- nonResourceURLs:
- /metrics
verbs:
- get
このロールを適用し、Prometheus Pod を再デプロイすることで、自動的に検出されたエンドポイントが Targets ページに登録されるようになります。
メトリクスデータの永続化戦略
上記の手順で監視設定が完了しても、Pod が再起動するとこれまで収集されたデータが失われる恐れがあります。这是因为デフォルトで設定されるボリュームは `emptyDir` であり、これらは Pod のライフサイクルに依存するためです。ライン上の運用環境では、ステートフルなデータ保持が必要です。
Kubernetes では PersistentVolumeClaim (PVC) と StorageClass を利用してデータを保存領域へマウントさせることができます。まずは適切な StorageClass を定義します。ここでは NFS 共有ディスクをバックエンドとする場合の例を示します。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-shared-storage
provisioner: fuseim.pri/ifs
次に、Prometheus の仕様(Spec)部分にストレージ設定を追加します。これにより、StatefulSet によって管理されるインスタンスごとに独立した永続ボリュームが自動的に生成されます。
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
name: monitor-main
namespace: monitoring
spec:
version: v2.5.0
replicas: 2
storage:
volumeClaimTemplate:
spec:
storageClassName: nfs-shared-storage
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 20Gi
設定を反映させると、`kubectl get pvc -n monitoring` を実行することで、関連付けられた PVC 状態を確認できます。それぞれの Pod マウント詳細を見ると、データディレクトリ (`/prometheus`) が persistentVolumeClaim に結びついていることがわかります。
$ kubectl get pod monitor-main-0 -n monitoring -o yaml | grep volumeMounts
volumeMounts:
- mountPath: /etc/prometheus/config_out
name: config-out
- mountPath: /prometheus
name: prom-monitor-data
最後に、すべての設定を含む包括的なリソースマニフェストの例を下に示します。これで自動検出とデータ保持の両方が有効化されます。
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
labels:
app: prometheus
name: monitor-main
namespace: monitoring
spec:
alerting:
alertmanagers:
- name: alertmanager-main
namespace: monitoring
port: web
additionalScrapeConfigs:
name: k8s-extra-scrape
key: scrape_targets.yaml
baseImage: quay.io/prometheus/prometheus
nodeSelector:
beta.kubernetes.io/os: linux
replicas: 2
resources:
requests:
memory: 500Mi
ruleSelector:
matchLabels:
prometheus: k8s
role: alert-rules
securityContext:
fsGroup: 2000
runAsNonRoot: true
runAsUser: 1000
serviceAccountName: prom-monitor-sa
serviceMonitorNamespaceSelector: {}
serviceMonitorSelector: {}
secrets:
- etcd-certs
storage:
volumeClaimTemplate:
spec:
storageClassName: nfs-shared-storage
resources:
requests:
storage: 20Gi
version: v2.5.0