試しにGrafanaを起動してみる
Grafanaは可視化ツールで、Monitoring/Observabilityの分野でよく使われています。
デフォルトでSQLiteを使っているので、Litestreamを使ってGrafanaを起動してみます。
公式サイト: https://grafana.com
terraformで環境を用意する
main.tf
※ 簡易にしてあるので、専用のGoogle Cloudプロジェクトを作成することをお勧めします。自己責任でお願いします
terraformの main.tf のgoogle_cloud_run_serviceとgoogle_cloud_run_service_iam_memberのresourceをコメントアウトしておき、terraformのフォルダでterraformを実行する。
サービスをEnabledにしろというメッセージでエラーになるので、Cloud Runのコンソールから手動でEnabledにして何度かやり直してください。
$ terraform init
$ TF_VAR_project_id=<Google CloudのProject_id> TF_VAR_grafana_settings_bucket_name=<gcsのバケット名> TF_VAR_google_artifact_registry_repository_name=<Artifact Registryに作るRepository名> TF_VAR_image_name=<Dockerのイメージ名> terraform apply
リソースが4つ作成されます。
コンテナイメージの作成
Litestreamの設定ファイルを修正します
Litestreamの設定ファイル にあるGCSのバケット名をterraformで作成したバケット名に変更します。
<GRAFANA_SETTINGS_BUCKET_NAME> を修正します。
url: gcs://<GRAFANA_SETTINGS_BUCKET_NAME>/grafana.db
Dockerのbuildとpush
Dockerfileのあるディレクトリで以下のコマンドを実行します。
私はApple SiliconのMacを使っているので、 --platform linux/amd64 をつけていますが、IntelのMacやLinuxの場合は不要です。
$ docker build --platform linux/amd64 . -t <Dockerのイメージ名>
$ docker tag <Dockerのイメージ名> asia-northeast1-docker.pkg.dev/<Google CloudのProject_id>/<Artifact Registryに作るRepository名>/<Dockerのイメージ名>
$ docker push asia-northeast1-docker.pkg.dev/<Google CloudのProject_id>/<Artifact Registryに作るRepository名>/<Dockerのイメージ名>:latest
terraformでCloudRunのサービスを起動する
コメントアウトしておいたresourceを有効にして再びterraform applyを実行します。前回と同じコマンドです。
$ TF_VAR_project_id=<Google CloudのProject_id> TF_VAR_grafana_settings_bucket_name=<gcsのバケット名> TF_VAR_google_artifact_registry_repository_name=<Artifact Registryに作るRepository名> TF_VAR_image_name=<Dockerのイメージ名> terraform apply
動作を確認する
Google CloudのコンソールからCloud RunのサービスのURLを確認し、URLにアクセスしてください。
Grafanaの初期ユーザーはユーザー名 admin 、パスワード admin です。初回サインインするとパスワードの変更を求められますので、簡単に推測できないパスワードを設定してください。
しばらく放置するとCloudRunのサービスが終了します。再度アクセスすると起動にしばらく時間がかかりますが、パスワードの変更が反映されたまま起動します。
Litestreamの設定を見る
litestream.yml
dbs:
- path: /var/lib/grafana/grafana.db
replicas:
- url: gcs://<GRAFANA_SETTINGS_BUCKET_NAME>/grafana.db # GCSのバケット名はグローバルに一意(重複できない)のでそれっぽい名前にする
retention: 12h
retention-check-interval: 3m
snapshot-interval: 4h
sync-interval: 30s
pathはgrafanaがデータベースファイルを保存している場所です。
replicasはレプリケーション先の設定です。ここではGCSにレプリケーションしています。コンテナは短い時間で終了してしまうので、頻繁にsyncし、また、履歴がどんどん増えていってしまうので定期的に削除するようにしています。
Dockerfile
Dockerfile
Cloud Runのコンテナで動作させるLitestreamのバイナリをダウンロードして展開しています。
ADD https://github.com/benbjohnson/litestream/releases/download/v0.3.13/litestream-v0.3.13-linux-amd64.tar.gz /tmp/litestream.tar.gz
RUN tar -C /usr/local/bin -xzf /tmp/litestream.tar.gz
続いて、Grafanaのイメージを使い、Litestreamのバイナリをコピー、Litestreamの設定ファイルをコピーしています。
FROM grafana/grafana-enterprise
COPY --from=builder /usr/local/bin/litestream /usr/local/bin/litestream
COPY litestream.yml /etc/litestream.yml
残りは、Cloud Runが期待しているアプリケーションのポートに設定ファイルを置換したり、LitestreamとGrafanaを起動するスクリプトをコピーしています。
start.sh
start.sh
コンテナの起動時に呼び出されるので、SQLiteのデータベースファイルのリストアを行います。リストア前にデフォルトのデータベースファイルが存在していたら、バックアップをとっておき、リストアするデータベースがなかった場合にはデフォルトのデータベースを元に戻すような処理をしています。関数にしてファイルパスを引数に取るようにすれば他のアプリケーションでも使いまわせると思います。
最後の行で、Litestreamを起動しつつ、Grafanaを起動(/run.sh)しています。
#!/bin/sh
set -e # 失敗したら終了する
# 起動時にすでにデータベースファイルが存在する場合は、一旦バックアップする
if [ -f /var/lib/grafana/grafana.db ]; then
mv /var/lib/grafana/grafana.db /var/lib/grafana/grafana.db.bk
fi
# replicaが存在したらリストアする
litestream restore -if-replica-exists -config /etc/litestream.yml /var/lib/grafana/grafana.db
# replicaのレストアができた && バックアップしたデータベースファイルが存在する場合は削除する
if [ -f /var/lib/grafana/grafana.db ]; then
if [ -f /var/lib/grafana/grafana.db.bk ]; then
rm /var/lib/grafana/grafana.db.bk
fi
else
# replicaのレストアができなかった場合 && バックアップしたデータベースファイルがあれば元に戻す
if [ -f /var/lib/grafana/grafana.db.bk ]; then
mv /var/lib/grafana/grafana.db.bk /var/lib/grafana/grafana.db
fi
fi
# Litestreamを起動しつつGrafanaを起動する
exec litestream replicate -exec "/run.sh"