Prometheusは標準ではTSDB(Time Series Database)と呼ばれるフォーマットのローカルストレージ上のDBにメトリクスを蓄積していく。
このDB、耐障害性や冗長化については考慮されておらず、障害が起きた時の対処法は以下のように記載されている。
If your local storage becomes corrupted for whatever reason, the best strategy to address the problem is to shut down Prometheus then remove the entire storage directory.
ざっくり言うと、障害が起きた時は全部消せ、とエンタープライズ用途には厳しいことが書いていて、TSDBは基本的に小規模・短期利用のためのDBとなっている。
では大規模・長期で使いたい場合はどうすればいいかというと、Remote StorageというPrometheus外のストレージに書き込んで保存することで障害によるデータ破損を回避することが出来る。
雰囲気的には以下のような感じになる。
このRemote Storage、どのようなものが対応しているかについてはこちらに一覧がある。
大手パブリッククラウドのストレージから、Splunk、New RelicといったSaaS製品、Kafka、Thanos、InfluxDBなどの自前で用意しやすいものなど様々なストレージが提供されているので、自分が使いやすいものを選ぶと良さそう。
自前で用意する場合は一昔前はThanosがメジャーだったが、どうも今はGrafana LabsがPrometheusのメトリクスの長期保存用に開発しているGrafana Mimir(発音はミーミル?)が流行っているみたいなので、今回はこれを使ってRemote Writeを確認する。
前提
ここでは以下の環境で実施する。
- vSphere with TanzuのTKGクラスタ構築済み (v1.25.7+vmware.3-fips.1を使用)
-
Type: LoadBalancer
が利用できる -
helm
、yq
、tanzu cli
はインストール済み
Prometheus、Grafanaの構築はTanzu Packagesを利用する。
PrometheusとGrafanaの構築
Tanzu Packages(2023.12.18)を使って構築する。
ここはあまり本質ではないのでサクサク行く。
Prometheusを含むPackageRepository
であるtanzu-standard
をデプロイする。バージョンはこちらを確認して、環境に合わせて変更すること。
cat <<EOF | kubectl apply -f -
apiVersion: packaging.carvel.dev/v1alpha1
kind: PackageRepository
metadata:
name: tanzu-standard
namespace: tkg-system
spec:
fetch:
imgpkgBundle:
image: projects.registry.vmware.com/tkg/packages/standard/repo:v2.2.0_update.2
EOF
cert-managerをインストールする。
kubectl create ns cert-manager
tanzu package install cert-manager -p cert-manager.tanzu.vmware.com -n cert-manager -v 1.10.2+vmware.1-tkg.1
Contourをインストールする。
CONTOUR_VER=1.23.5+vmware.1-tkg.1
kubectl create ns tanzu-system-ingress
cat <<EOF > ./contour-data-values.yaml
infrastructure_provider: vsphere
namespace: tanzu-system-ingress
contour:
logLevel: info
replicas: 2
useProxyProtocol: false
envoy:
service:
type: LoadBalancer
annotations: {}
externalTrafficPolicy: Cluster
disableWait: false
hostPorts:
enable: true
http: 80
https: 443
hostNetwork: false
terminationGracePeriodSeconds: 300
logLevel: info
certificates:
duration: 8760h
renewBefore: 360h
EOF
tanzu package install contour -p contour.tanzu.vmware.com -v $CONTOUR_VER --values-file contour-data-values.yaml -n tanzu-system-ingress
Prometheusをインストールする。なおデフォルトでは"default"という名前のStorageClass
をAlertManagerが使おうとするため、もしそのような名前のStorageClass
がない場合は作成するか、StorageClass
の設定を変更すること。
PROM_VER=2.37.0+vmware.3-tkg.1
tanzu package available get prometheus.tanzu.vmware.com/$PROM_VER --generate-default-values-file
cp prometheus-default-values.yaml prometheus-data-values.yaml
tanzu package install prometheus -p prometheus.tanzu.vmware.com -v $PROM_VER --values-file prometheus-data-values.yaml -n tanzu-system-monitoring --create-namespace
Grafanaも同様に構築する。なお、7.5.7を使うとcert-managerの古いAPIバージョンを要求するためインストールに失敗する。
また、既知不良があるので、ワークアラウンドをあわせて実施する。
kubectl create ns tanzu-system-dashboards
kubectl create secret generic grafana -n tanzu-system-dashboards --from-literal=admin=admin
GRAFANA_VER=7.5.16+vmware.1-tkg.2
tanzu package available get grafana.tanzu.vmware.com/$GRAFANA_VER --generate-default-values-file
cp grafana-default-values.yaml grafana-data-values.yaml
sed -i "s/grafana.system.tanzu/grafana.$(kubectl get svc -n tanzu-system-ingress envoy -o jsonpath={.status.loadBalancer.ingress[0].ip}).nip.io/g" grafana-data-values.yaml
yq eval 'del(.grafana.secret)' grafana-data-values.yaml -i
tanzu package install grafana -p grafana.tanzu.vmware.com -v $GRAFANA_VER --values-file grafana-data-values.yaml -n tanzu-system-dashboards --create-namespace
Grafana Mimirの構築
Get started with Grafana Mimir using the Helm chartを参考にMimirを構築する。
最初にHelmに渡すyamlを作成し、Ingressで外部にサービスを公開するようにする。
※今回の構成ではこの工程は省くことも出来るが、実利用では外部サービスとして利用することが多そうなのでIngressで公開した。
cat <<EOF > ./custom.yaml
nginx:
ingress:
enabled: true
hosts:
- host: mimir.$(kubectl get svc -n tanzu-system-ingress envoy -o jsonpath={.status.loadBalancer.ingress[0].ip}).nip.io
paths:
- path: /
pathType: Prefix
EOF
Minirをインストールする。
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
helm -n mimir-test upgrade -i mimir grafana/mimir-distributed --create-namespace -f ./custom.yaml
インストールすると以下のようなメッセージが出る。
Remote write endpoints for Prometheus or Grafana Agent:
From outside the cluster via ingress:
http://mimir.10.220.16.163.nip.io/api/v1/push
From inside the cluster:
http://mimir-nginx.mimir-test.svc:80/api/v1/push
Read address, Grafana data source (Prometheus) URL:
From outside the cluster via ingress:
http://mimir.10.220.16.163.nip.io/prometheus
From inside the cluster:
http://mimir-nginx.mimir-test.svc:80/prometheus
それぞれMimirのアクセス方法になるので念の為残しておくと後々便利。
構築したMimirのエンドポイントをGrafanaのデータソースに追加する。
"http://grafana..nip.io"にアクセスすればGrafanaのUIが見れるので、admin/adminでログインし、`Configuration`->`Data Sources`->Add data source
でPrometheusを選択する。
データソースにmimir-nginx.mimir-test.svc/prometheus
を追加して、Save&Test
をクリックして追加する。
以上でGrafana、Mimirの設定は完了となる。
PrometheusからMimirにwriteする
PrometheusにはRemote Write向けのモードとしてAgentモードがあり、これを設定するとPrometheusはDiscovery, Scrape, Remote Writeしかしないシンプルなモードに移行する。
ここではPrometheusをAgentモードで起動し、Remote WriteでMimirに書き込むよう設定を変更する。
設定の変更方法についてはmakingさんの「Tanzu Kubernetes GridのPrometheus Packageでremote-write-receiverとagent modeをセットアップして複数のKubernetesクラスタを監視する」を参考にした。
prometheus-data-values.yamlを開き、PrometheusのDeploymentの引数に--enable-feature=agent
を追加する。また、Agentモード時は以下の制約があるのでそれぞれ削除する。
-
--storage.tsdb.retention.time
と--storage.tsdb.path
は使えない - prometheus_yml内にalertの設定やrule_filesが書けない
ファイルの差分は以下となる。
@@ -12,7 +12,7 @@
receiver: default-receiver
repeat_interval: 3h
deployment:
- replicas: 1
+ replicas: 0
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
@@ -65,11 +65,8 @@
evaluation_interval: 1m
scrape_interval: 1m
scrape_timeout: 10s
- rule_files:
- - /etc/config/alerting_rules.yml
- - /etc/config/recording_rules.yml
- - /etc/config/alerts
- - /etc/config/rules
+ remote_write:
+ - url: http://mimir.10.220.16.163.nip.io/api/v1/push
scrape_configs:
- job_name: 'prometheus'
scrape_interval: 5s
@@ -140,30 +137,6 @@
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
- alerting:
- alertmanagers:
- - scheme: http
- static_configs:
- - targets:
- - alertmanager.prometheus.svc:80
- - kubernetes_sd_configs:
- - role: pod
- relabel_configs:
- - source_labels: [__meta_kubernetes_namespace]
- regex: default
- action: keep
- - source_labels: [__meta_kubernetes_pod_label_app]
- regex: prometheus
- action: keep
- - source_labels: [__meta_kubernetes_pod_label_component]
- regex: alertmanager
- action: keep
- - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_probe]
- regex: .*
- action: keep
- - source_labels: [__meta_kubernetes_pod_container_port_number]
- regex:
- action: drop
recording_rules_yml: |
groups:
- name: kube-apiserver.rules
@@ -680,12 +653,11 @@
- --webhook-url=http://127.0.0.1:9090/-/reload
containers:
args:
- - --storage.tsdb.retention.time=42d
- --config.file=/etc/config/prometheus.yml
- - --storage.tsdb.path=/data
- --web.console.libraries=/etc/prometheus/console_libraries
- --web.console.templates=/etc/prometheus/consoles
- --web.enable-lifecycle
+ - --enable-feature=agent
replicas: 1
rollingUpdate:
maxSurge: 25%
@@ -700,7 +672,7 @@
type: ClusterIP
pushgateway:
deployment:
- replicas: 1
+ replicas: 0
service:
port: 9091
targetPort: 9091
AlertManagerとPushGatewayは使用しないためレプリカ数を0にした。
設定を反映する。
tanzu package installed update prometheus -f prometheus-data-values.yaml -n tanzu-system-monitoring
Agentモードで動作していることを確認する。
ポートフォワードでPrometheus Serverにアクセスする。
kubectl port-forward service/prometheus-server -n tanzu-system-monitoring 9090:80
アクセスすると、以下のようにAgentモードで起動していることが分かる。
Grafanaにアクセスする。
Agentモードになっているため、DatasourceがPrometheusだと表示に失敗する。
左上のdatasource
のプルダウンから先ほど登録したMimir
に切り替えてみる。
データが確認できた。
これにより、Remote Writeが適切に行われ、PrometheusはローカルのTSDBを使わずMimirにメトリクスを溜め込むことが確認できた。