Kubernetesにおいて、システムがどのように動作しているかを把握することは最大の課題の一つです。Podは安定して稼働しているか?ノードはリソース過負荷になっていないか?アプリケーションに気づかないパフォーマンスの問題はないか?適切な監視システムがなければ、Kubernetesクラスタの管理は霧の中を運転するようなもので、どこへ向かっているのか全く見えません。
以前、物理サーバーや仮想マシンの監視をしていた頃は、PrometheusとGrafanaを手動でインストールしていました。Node ExporterやcAdvisorからメトリクスを収集するために、scrape_configsをprometheus.ymlファイルに定義していました。
その方法はサーバー台数が少ない場合には効果的でした。しかし、Kubernetesに移行し、数百、時には数千ものPodが絶えず変化するようになると、手動での設定は不可能になります。Podが生成され、消滅し、IPアドレスも頻繁に変わる状況で、Prometheusがどのようにメトリクスを自動的に収集すればよいのでしょうか?
その時こそ、Prometheus Operatorが救世主として登場しました。この記事では、Prometheus OperatorとGrafanaを導入してKubernetesクラスタを自動的に監視し、問題の proactive な検出と対処を可能にする方法を説明します。
クイックスタート:Prometheus OperatorとGrafanaを5分でデプロイ
すぐに結果を確認できるよう、Helmを使って監視スタック全体をクラスタにインストールします。このスタックには、Prometheus Operator、Prometheus、Grafana、Alertmanager、Node Exporter、Kube-state-metricsが含まれます。Helmがインストールされており、Kubernetesクラスタへのアクセス権があることを確認してください。
1. Helmリポジトリの追加
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
2. kube-prometheus-stackのインストール
kube-prometheus-stackは、Prometheus Operatorとその他すべての必要なコンポーネントを含むHelmパッケージです。
helm install prometheus prometheus-community/kube-prometheus-stack --namespace monitoring --create-namespace
このコマンドは、monitoringという新しい名前空間を作成し、そこにスタック全体をデプロイします。このプロセスには数分かかる場合があります。
3. Grafanaへのアクセス
Podが安定して稼働したら、Grafanaダッシュボードにアクセスするためにポートフォワードが必要です。まず、Grafanaの管理者パスワードを取得します。
kubectl get secret prometheus-grafana -n monitoring -o jsonpath="{.data.admin-password}" | base64 --decode
次に、Grafanaサービスをポートフォワードします。
kubectl port-forward service/prometheus-grafana 3000:80 -n monitoring
これで、ブラウザを開いてhttp://localhost:3000にアクセスしてください。ユーザー名adminと先ほど取得したパスワードでログインします。Kubernetesクラスタを監視するための多数のダッシュボードが利用可能になっているのがわかるでしょう!
詳細解説:KubernetesにPrometheus Operatorが必要な理由
問題:Kubernetes監視の複雑性
Kubernetesは、Node、Pod、Service、Deployment、StatefulSet、Ingress、Controllerなど、多くの動的なコンポーネントを持つ複雑な分散システムです。各コンポーネントは独自のステータスとパフォーマンスを持っています。これらすべてを手動で追跡することは不可能です。さらに、Podは絶えず作成され、破棄され、IPアドレスも変化するため、Prometheusの静的な設定は無意味になります。
原因:Kubernetesの動的な性質
Kubernetesの動的な性質こそが、従来の監視を困難にする主な原因です。Prometheusはデータを収集するために、メトリクスを提供するターゲット(エンドポイント)を知る必要があります。静的な環境では、IPアドレスを列挙するだけで済みます。しかし、Kubernetesでは、Podはスケールアップ/ダウンしたり、ノード間を移動したり、いつでもIPアドレスを変更したりする可能性があります。
解決策:Prometheus OperatorとGrafana
その時こそ、Prometheus OperatorとGrafanaが力を発揮します。
- Prometheus Operator: これはKubernetes Operatorであり、Kubernetes上でのPrometheusのデプロイ、管理、運用を自動化するために構築されています。Prometheusを手動で設定する代わりに、
Prometheus、ServiceMonitor、PodMonitor、Alertmanagerなどのカスタムリソース(CRD)を定義します。Operatorはこれらの定義を読み取り、対応するPrometheusオブジェクトを自動的に作成および管理します。 - ServiceMonitorとPodMonitor: これらはPrometheus Operatorの最も重要な2つのCRDです。これらを使用すると、Prometheusがラベルセレクタに基づいてクラスタ内のServiceまたはPodからメトリクスを自動的に検出し、収集する方法を定義できます。これにより、Kubernetesの動的な性質の問題が完全に解決されます。
- Grafana: 強力なビジュアライゼーションツールです。Prometheusに接続してメトリクスデータをクエリし、ダッシュボードを通じてグラフや表形式でわかりやすく表示します。
Kubernetes監視システムのアーキテクチャ
kube-prometheus-stackを使用すると、監視システムは次のようなアーキテクチャになります。
- Node Exporter: DaemonSetとしてデプロイされ、各ノード上で動作し、ノードのリソース(CPU、RAM、ディスク、ネットワーク)に関するメトリクスを収集します。
- Kube-state-metrics: Kubernetesオブジェクトのステータス(実行中のPod数、失敗したDeployment、使用中のPersistentVolumeなど)に関するメトリクスを収集します。
- Prometheus: システムの中心であり、Node Exporter、Kube-state-metrics、およびServiceMonitor/PodMonitorを介してアプリケーションからメトリクスを収集します。
- Prometheus Operator: CRD(Prometheus、ServiceMonitor、PodMonitor、Alertmanager)を監視し、PrometheusおよびAlertmanagerインスタンスが適切に設定され、実行されていることを確認します。
- Alertmanager: Prometheusから生成されたアラートを処理し、様々なチャネル(メール、Slack、Telegramなど)に通知を送信します。
- Grafana: Prometheusに接続してデータとダッシュボードを表示します。
高度な機能:ServiceMonitorによるメトリクス自動収集
Prometheus Operatorの強みは、Service/Podを自動的に検出し、メトリクスを収集する能力にあります。Kubernetesでウェブアプリケーションを実行しており、そのアプリケーションがポート8080のパス/metricsでメトリクスを公開しているとします。そのアプリケーションのServiceからPrometheusが自動的にメトリクスを収集するように、ServiceMonitorを作成できます。
ServiceMonitorの例
まず、Prometheusがアクセスできるように、アプリケーションにはServiceが必要です。
apiVersion: v1
kind: Service
metadata:
name: my-app-service
labels:
app: my-app
spec:
selector:
app: my-app
ports:
- name: web
port: 80
targetPort: 8080 # アプリケーションがメトリクスを公開するポート
次に、PrometheusがこのServiceからメトリクスを収集する方法を認識させるために、ServiceMonitorを作成します。
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: my-app-servicemonitor
labels:
app: my-app # このラベルは重要です。Prometheus OperatorがServiceMonitorを選択するために使用します
spec:
selector:
matchLabels:
app: my-app # app: my-app のラベルを持つServiceを選択
endpoints:
- port: web # 上記Serviceのポート名
path: /metrics # アプリケーションのメトリクスパス
namespaceSelector:
matchNames:
- default # またはアプリケーションが含まれる名前空間
このYAMLファイルを適用すると、Prometheus Operatorは新しいServiceMonitorを検出します。これにより、Prometheusはmy-app-serviceからwebポートと/metricsパスでメトリクスのスクレイピングを開始するように自動的に設定されます。Prometheusの設定ファイルをもう手動で編集する必要はありません!
ルールとAlertmanagerの設定
kube-prometheus-stackにはAlertmanagerとPrometheusRule CRDも含まれています。PrometheusRuleリソースを作成することで、アラートルール(例:PodのCPU使用率が5分間80%を超過した場合)を定義できます。
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: my-app-alerts
labels:
app: my-app
spec:
groups:
- name: my-app.rules
rules:
- alert: HighCpuUsage
expr: sum(rate(container_cpu_usage_seconds_total{namespace="default", pod=~"my-app.*"}[5m])) by (pod) > 0.8
for: 5m
labels:
severity: critical
annotations:
summary: "Pod {{ $labels.pod }} のCPU使用率が高い"
description: "Pod {{ $labels.pod }} は5分間80%以上のCPUを使用しています。"
