複数のKubernetesをPrometheusで監視したい時、見る側は一箇所に集約したいと思うことが多いと思います。
Federationだと、次の図のように、各Prometheusが自分のクラスタのデータを貯めつつ、集約Prometheusで全クラスタのデータを貯めることになるのでデータサイズ的に無駄が多くなります。
下の図のように、集約側のPrometheusでremote-writeを受付け、その他のPrometheusはagent modeでデータを貯めずに集約側に送るようにすれば無駄なく複数Prometheusを監視できます。Federationにもメリットはあると思いますが、複数クラスタを監視する場合はこちらの構成をイメージすることが多いと思います。
この構成をTanzu Kubernetes Gridのパッケージを使って構築します。
集約Prometheusのセットアップ
まずは共有Kubernetesクラスタで集約Prometheusをセットアップします。
以下のパッケージがインストールされていることが前提です
ℹ️ TKG以外のkubernetesで試したい場合はこちらの記事を参考にしてください
次のYAMLを作成します。Prometheusの起動オプションに--web.enable-remote-write-receiver
を追加するところがポイントです。
各メトリクスがどのクラスタから送られてきたかを区別するためにcluster
というラベルを追加しています。次の設定ファイルではorbstack
となっているので、自環境に合わせて置換してください。
またingress.virtual_host_fqdn
も自環境の値に変更してください。
cat <<'EOF' > prometheus-values.yaml
---
ingress:
enabled: true
virtual_host_fqdn: prometheus.192-168-194-146.sslip.io
prometheus:
deployment:
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=exemplar-storage
- --web.enable-remote-write-receiver
config:
prometheus_yml: |
global:
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
scrape_configs:
- job_name: 'prometheus'
scrape_interval: 5s
static_configs:
- targets: [ 'localhost:9090' ]
labels:
cluster: orbstack
- job_name: 'kube-state-metrics'
static_configs:
- targets: [ 'prometheus-kube-state-metrics.tanzu-system-monitoring.svc.cluster.local:8080' ]
labels:
cluster: orbstack
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [ __meta_kubernetes_pod_annotation_prometheus_io_scrape ]
action: keep
regex: true
- source_labels: [ __meta_kubernetes_pod_annotation_prometheus_io_path ]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [ __address__, __meta_kubernetes_pod_annotation_prometheus_io_port ]
action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
target_label: __address__
- action: labelmap
regex: __meta_kubernetes_pod_label_(.+)
- source_labels: [ __meta_kubernetes_namespace ]
action: replace
target_label: kubernetes_namespace
- source_labels: [ __meta_kubernetes_pod_name ]
action: replace
target_label: kubernetes_pod_name
- source_labels: [ ]
target_label: cluster
replacement: orbstack
- job_name: kubernetes-nodes-cadvisor
kubernetes_sd_configs:
- role: node
relabel_configs:
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
- replacement: kubernetes.default.svc:443
target_label: __address__
- regex: (.+)
replacement: /api/v1/nodes/$1/proxy/metrics/cadvisor
source_labels:
- __meta_kubernetes_node_name
target_label: __metrics_path__
- source_labels: [ ]
target_label: cluster
replacement: orbstack
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
- job_name: kubernetes-apiservers
kubernetes_sd_configs:
- role: endpoints
relabel_configs:
- action: keep
regex: default;kubernetes;https
source_labels:
- __meta_kubernetes_namespace
- __meta_kubernetes_service_name
- __meta_kubernetes_endpoint_port_name
- source_labels: [ ]
target_label: cluster
replacement: orbstack
scheme: https
tls_config:
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.tanzu-system-monitoring.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
EOF
次のコマンドでインストールします。
tanzu package install -n tkg-system -p prometheus.tanzu.vmware.com -v 2.43.0+vmware.2-tkg.1 --values-file prometheus-values.yaml prometheus
$ kubectl get pod,httpproxy -n tanzu-system-monitoring -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/prometheus-node-exporter-2qjmj 1/1 Running 0 55s 192.168.194.48 orbstack <none> <none>
pod/prometheus-kube-state-metrics-7d4b54447c-5m7vs 1/1 Running 0 53s 192.168.194.50 orbstack <none> <none>
pod/prometheus-pushgateway-5f6d8695d4-w4f5w 1/1 Running 0 53s 192.168.194.52 orbstack <none> <none>
pod/alertmanager-85796b8bc9-6dlbk 1/1 Running 0 54s 192.168.194.53 orbstack <none> <none>
pod/prometheus-server-5f784b75fd-kpf4d 2/2 Running 0 53s 192.168.194.54 orbstack <none> <none>
NAME FQDN TLS SECRET STATUS STATUS DESCRIPTION
httpproxy.projectcontour.io/prometheus-httpproxy prometheus.192-168-194-146.sslip.io prometheus-tls valid Valid HTTPProxy
ingress.virtual_host_fqdn
に指定したURLにアクセスするとPrometheusのUIが表示されます。
--web.enable-remote-write-receiver
フラグが有効になっていることを確認します。
各メトリクスにcluster
ラベルがついていることを確認します。
agent modeのPrometheusのセットアップ
次にその個々のKubernetes側でagent modeのPrometheusをセットアップします。 前提となるパッケージはありません。
次のYAMLを作成します。Prometheusの起動オプションに--enable-feature=agent
を追加するところがポイントです。
またprometheus.yaml
のremote_write
で集約PrometheusのURLを設定します。global.external_labels
でremote write時に追加するlabelを指定できます。
ここではクラスタ名としてcluster
ラベルにkind
を設定しています。自環境に合わせて修正してください。agent modeの場合はprometheus.yaml
にalertの設定ができないので、設定を削除します。
PVCは不要ですが、Tanzu Packageだとvalues fileで無効にできないので小さいサイズを設定します。 同じくAlertManagerやPush Gatewayも不要ですが、values fileで無効にできないのでreplica数を0にしておきます。
cat <<'EOF' > prometheus-agent-values.yaml
---
prometheus:
deployment:
containers:
args:
- --config.file=/etc/config/prometheus.yml
- --enable-feature=exemplar-storage
- --enable-feature=agent
- --storage.agent.retention.max-time=5m
pvc:
storage: 1Gi
config:
prometheus_yml: |
global:
evaluation_interval: 1m
scrape_interval: 1m
scrape_timeout: 10s
external_labels:
cluster: kind
remote_write:
- url: https://prometheus.192-168-194-146.sslip.io/api/v1/write
send_exemplars: true
tls_config:
insecure_skip_verify: true
scrape_configs:
- job_name: 'prometheus'
scrape_interval: 5s
static_configs:
- targets: [ 'localhost:9090' ]
- job_name: 'kube-state-metrics'
static_configs:
- targets: [ 'prometheus-kube-state-metrics.tanzu-system-monitoring.svc.cluster.local:8080' ]
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [ __meta_kubernetes_pod_annotation_prometheus_io_scrape ]
action: keep
regex: true
- source_labels: [ __meta_kubernetes_pod_annotation_prometheus_io_path ]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [ __address__, __meta_kubernetes_pod_annotation_prometheus_io_port ]
action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
target_label: __address__
- action: labelmap
regex: __meta_kubernetes_pod_label_(.+)
- source_labels: [ __meta_kubernetes_namespace ]
action: replace
target_label: kubernetes_namespace
- source_labels: [ __meta_kubernetes_pod_name ]
action: replace
target_label: kubernetes_pod_name
- job_name: kubernetes-nodes-cadvisor
kubernetes_sd_configs:
- role: node
relabel_configs:
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
- replacement: kubernetes.default.svc:443
target_label: __address__
- regex: (.+)
replacement: /api/v1/nodes/$1/proxy/metrics/cadvisor
source_labels:
- __meta_kubernetes_node_name
target_label: __metrics_path__
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
- job_name: kubernetes-apiservers
kubernetes_sd_configs:
- role: endpoints
relabel_configs:
- action: keep
regex: default;kubernetes;https
source_labels:
- __meta_kubernetes_namespace
- __meta_kubernetes_service_name
- __meta_kubernetes_endpoint_port_name
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
alertmanager:
deployment:
replicas: 0
pushgateway:
deployment:
replicas: 0
EOF
次のコマンドでインストールします。
tanzu package install -n tkg-system -p prometheus.tanzu.vmware.com -v 2.43.0+vmware.2-tkg.1 --values-file prometheus-agent-values.yaml prometheus
$ kubectl get pod -n tanzu-system-monitoring
NAME READY STATUS RESTARTS AGE
prometheus-kube-state-metrics-c7f4d6f6f-j4vfj 1/1 Running 0 4m34s
prometheus-node-exporter-xzw7d 1/1 Running 0 4m34s
prometheus-server-6b98c76645-zz69b 2/2 Running 0 3m18s
次のコマンドでprometheusのUIをポートフォワードします。
kubectl port-forward -n tanzu-system-monitoring svc/prometheus-server 9090:8
UIにアクセスすると"Prometheus Agent"と表示されているので、agent modeとして起動していることがわかります。
集約PrometheusのUIで sum(kube_pod_info) by (cluster, namespace)
を取得します。次のようにnamespace単位でのpod数がcluster毎に出力されればセットアップ成功です。
Grafanaのダッシュボードもcluster
ラベルで検索できるようにカスタマイズする必要がありますが、本記事では割愛します。
Tanzu Application Platformのマルチクラスタ構成をPrometheusで監視したい場合は、この構成にすると良いでしょう。