📈

prometheus-operatorでPodのメトリクスを収集する

2021/09/18に公開

はじめに

PodのCPU使用率やメモリ使用率をPrometheusで収集しようとしたところ、長い間ハマってしまいました。やっと解決したので、prometheus-operatorで収集する方法を記します。

環境

  • macOS Big Sur 11.6
  • kind v0.11.1
  • Kubernetes v1.21.2
  • prometheus-operator v0.48.1

結論

prometheus-operatorはkube-system namespaceにkubelet serviceを作成します。こちらを利用してhttps://kubelet.kube-system:10250/metrics/cadvisorでPodのメトリクスを取得できます。

今回適用したマニフェストはこちらです。
https://github.com/cloudnativedaysjp/dreamkast-infra/tree/19be1639a7e356e00561ba6066d8f27b2e17dd9c/manifests/infra/prometheus/base

特に関係深いのはこちらです。

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: cadvisor
  namespace: kube-system
spec:
  endpoints:
  - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
    path: "/metrics/cadvisor"
    port: https-metrics
    scheme: https
    tlsConfig:
      insecureSkipVerify: true
  namespaceSelector:
    matchNames:
      - kube-system
  selector:
    matchLabels:
      app.kubernetes.io/name: kubelet

紆余曲折

node-exporterはNodeのメトリクスしか公開していない

最低限、prometheus/node-exporterを入れることが要件となっていました。これだけで済めばよかったのですが、そんなに甘くはありませんでした。node-expoterはその名の通り、Nodeのメトリクスを取得するものでした。

https://gist.github.com/oke-py/d402c844076eb7202e8961ae3d15a24f

metrics-serverはPodのメトリクスを公開していない

次はmetrics-serverを調べました。metrics-serverのメトリクスを公開しているだけでした。
https://gist.github.com/oke-py/ae9f2e1b2b9e0fe2dfa52c4e49b1596a

cAdvisorでいけるらしい

ここまでで一度タイムアップで燃え尽きたのですが、さらに調べてみるとcAdvisorがコンテナのメトリクスを公開していることがわかりました[1][2]。cAdvisorはkubeletバイナリの一部として実行されるそうです。つまり、kubeletにアクセスできればいけそうです。

prometheus-operatorによりkubelet serviceが作られている

ゴール目前と思いきや、prometheus-operatorにはPodMonitorServiceMonitorしか用意されていません。自前でscrape_configを記述すればよいかもしれませんが、美しくはありません。(闇雲に?)調べてみるとkube-system namespaceにkubelet serviceを見つけました。

$ kubectl -n kube-system get svc kubelet -o yaml 
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2021-09-17T13:01:49Z"
  labels:
    app.kubernetes.io/managed-by: prometheus-operator
    app.kubernetes.io/name: kubelet
    k8s-app: kubelet
  name: kubelet
  namespace: kube-system
  resourceVersion: "6308"
  uid: 97213adf-62c4-4fcc-83cf-03d45ec2ee17
spec:
  clusterIP: None
  clusterIPs:
  - None
  ipFamilies:
  - IPv4
  - IPv6
  ipFamilyPolicy: RequireDualStack
  ports:
  - name: https-metrics
    port: 10250
    protocol: TCP
    targetPort: 10250
  - name: http-metrics
    port: 10255
    protocol: TCP
    targetPort: 10255
  - name: cadvisor
    port: 4194
    protocol: TCP
    targetPort: 4194
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}

どのportを使うのか

  1. http-metrics
  2. cadvisor
  3. https-metrics

の順に試しました。特に意味はありません。強いて挙げれば、httpの方が楽そうという怠慢です。ところが、1と2はいずれもconnection refusedとなりました。それらしいIssue[3]を見つけました。どうやら最近のkubeletは10255と4194でLISTENしていなさそうです。また、/metrics/cadvisorでメトリクスを公開していることもわかりました。実際には、/metricsでkubeletのメトリクスを、/metrics/cadvisorでコンテナのメトリクスを公開していました。

https://gist.github.com/oke-py/208a2250f4be0e6c3d497098c7399281
https://gist.github.com/oke-py/1acd62fa23b15508da0b0872ce1c3b7c

おわりに

当初のターゲットには間に合いませんでしたが、なんとかPodのメトリクスをとれるようになりました。あとはGrafanaダッシュボードを用意するだけです(きっと)。

脚注
  1. Prometheus と Grafana を使用して AWS Fargate で Amazon EKS をモニタリングする
    https://aws.amazon.com/jp/blogs/news/monitoring-amazon-eks-on-aws-fargate-using-prometheus-and-grafana/ ↩︎

  2. Kubernetes のメトリクスを Prometheus を使って監視する
    https://qiita.com/kkohtaka/items/59007f0ada56d9f9a8f4 ↩︎

  3. https://github.com/prometheus-operator/prometheus-operator/issues/1741 ↩︎

GitHubで編集を提案

Discussion