Prometheusのバックアップを取得、リカバリする


コンテナで起動したPrometheusのデータをバックアップする方法の要点は、3つになります。

  • Prometheusのデータは/prometheusに保存されている。
  • PrometheusのTSDB (time series database)のAdminAPIには、"snapshot"という機能があり、/prometheusのある時刻での断面を取得できる
  • 新規Prometheusが起動したら、/prometheusごとスナップショットを上書きすることでリカバリできる

以下の記事を参考にしています。

https://prometheus.io/docs/prometheus/latest/querying/api/#snapshot
https://prometheus.io/docs/operating/security/
https://devopstales.github.io/home/backup-and-retore-prometheus/

検証環境は以下です。

  • Prometheus 2.23.0
  • Kubernetes 1.20

詳細な手順は以下です。

Admin API有効化

PrometheusがKubernetesクラスタ内にDeploymentとして起動中の状態を想定します。データディレクトリ/prometheusはPersistentVolumeなどで永続化されていることを確認してください。(されていなければ以下の作業をやってしまうとデータは消えます)

まず、Admin APIが有効かを確認をします。Deploymentを以下コマンドで確認し、- --web.enable-admin-apiの行がなければ足し、保存して終了します。これでDeploymentは更新されました。

$ kubectl edit deploy prometheus

    spec:
      containers:
      - args:
        - --config.file=/etc/prometheus/prometheus.yml
        - --storage.tsdb.path=/prometheus
        - --storage.tsdb.retention.time=30d
        - --web.console.libraries=/usr/share/prometheus/console_libraries
        - --web.console.templates=/usr/share/prometheus/consoles
+        - --web.enable-admin-api
        image: prom/prometheus:v2.23.0

Podが自動で再起動します。これでAdmin APIは有効化されます。

(注: 有効化前にAdmin APIを実行しても404 page not foundが返ってきます)

"snapshot" APIでバックアップ作成

次に、PrometheusのAPIにport-forwardなどを使い接続します。

$ kubectl port-forward svc/<prometheusのService名> 9090:9090 &
$ curl -XPOST http://localhost:9090/api/v1/admin/tsdb/snapshot
│{"status":"success","data":{"name":"20210106T080347Z-0af2560383d17909"}}
$ bg
(Ctrl+cでport-forwardを終了)

以下コマンドで/prometheus/snapshotsにバックアップのディレクトリ(APIの返り値のnameと同じ)があることを確認します。

$ kubectl exec prometheus-5fd8f7f855-hnhvd -- ls /prometheus/snapshots -lt
total 4
drwxr-xr-x    8 nobody   nogroup       4096 Jan  6 08:03 20210106T080347Z-0af2560383d17909

バックアップをコンテナ内から退避

先程確認したディレクトリをまるごと端末にコピーします。

mkdir backup-prometheus
kubectl cp prometheus-5fd8f7f855-hnhvd:/prometheus/snapshots/20210106T080347Z-0af2560383d17909 ./backup-prometheus

ちゃんと中身があることを確認します。

ls backup-prometheus
01EV938GHBWTFM8ZMTWDWA1FTK 01EVAT6A9S7CV7SGD6HAJHK4WX 01EVAT6AMWFF76KPXWEN14VG23 01EVB121HNVRERS45KPTXXNSA8 01EVB7XRSQZ9WQ57ECD17DV548 01EVBBJ9TQ0XVHGGN5BQ7FD3GJ

新規Prometheus上へのデータリカバリ

新規Prometheusを起動します。

Prometheus上の既存フォルダを一度消します。

kubectl exec -it prometheus-57df548d7c-tvx4d -- /bin/sh -c "rm -rf /prometheus/*"

バックアップ(snapshot)をPrometheusコンテナ内にコピーします。

kubectl cp ./backup-prometheus prometheus-57df548d7c-tvx4d:/prometheus/
kubectl exec -it prometheus-57df548d7c-tvx4d -- /bin/sh -c "mv /prometheus/backup-prometheus/* /prometheus/"

もしデータが復元されていなければ、一度コンテナを停止・再作成すると良いです。

kubectl delete pod prometheus-57df548d7c-tvx4d

これにより、新しい名称でPrometheusコンテナが再起動しており、データは復元されています。

まとめ

/prometheusフォルダをsnapshot APIによりバックアップし、それをkubectl cpで取り出し、新規作成したPrometheusにkubectl cpするという流れで、Prometheusのデータをバックアップ・リカバリしました。