【Kubernetes】Prometheus Adapterでカスタムメトリクス作成

2022.11.13
2024.03.24
Kubernetes
IstioPrometheusPrometheus Adapter

はじめに

Prometheus Adapterを使ってKubernetesのカスタムメトリクスを作成する方法をざっくり紹介します。

また、実際にローカルでIstioのメトリクスからカスタムメトリクスも作成してみたいと思います。

Promethues Adapterとは

Prometheus Adapterとは、Prometheusで使えるメトリクスからカスタムメトリクスが作成できるアダプタになります。

GitHub - kubernetes-sigs/prometheus-adapter: An implementation of the custom.metrics.k8s.io API using Prometheus

GitHub - kubernetes-sigs/prometheus-adapter: An implementation of the custom.metrics.k8s.io API using Prometheus

An implementation of the custom.metrics.k8s.io API using Prometheus - kubernetes-sigs/prometheus-adapter

インストール

Helmを使ってインストールするのが簡単です。

1helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
2helm repo update
3helm install prometheus-adapter prometheus-community/prometheus-adapter
helm-charts/charts/prometheus-adapter at prometheus-adapter-2.7.1 · prometheus-community/helm-charts

helm-charts/charts/prometheus-adapter at prometheus-adapter-2.7.1 · prometheus-community/helm-charts

Prometheus community Helm charts. Contribute to prometheus-community/helm-charts development by creating an account on GitHub.

設定

Prometheus Adapterの設定はコンテナ実行時の引数で渡されています。

例えば、下記のようなものがあります。

  • --prometheus-url=<url>: 接続するPrometheusのURL
  • --config=<yaml-file>: メトリクスの設定をするyamlファイル

具体的には、下記のような感じになっています。

1...
2
3spec:
4  containers:
5  - args:
6    - /adapter
7    - --secure-port=6443
8    - --cert-dir=/tmp/cert
9    - --logtostderr=true
10    - --prometheus-url=http://prometheus-server.monitoring.svc.cluster.local:9090
11    - --metrics-relist-interval=1m
12    - --v=4
13    - --config=/etc/adapter/config.yaml
14
15...

Helmを使っていれば、これらの設定はvalues.yamlで設定可能です。

カスタムメトリクスの定義

カスタムメトリクスはconfigファイルで定義します。(Helmであればvalues.yamlで設定可能)

カスタムメトリクスの定義は、下記の4つに分類できます。

  • Discovery: Prometheusからメトリクスをどう検索するか
  • Association: どのKubernetesリソースと関連しているか
  • Naming: カスタムメトリクスの名前
  • Querying: Prometheusへのクエリ(PromQL)

下記のようにカスタムメトリクスを定義します。

1rules:
2# Discovery
3- seriesQuery: '{__name__=~"^container_.*",container!="POD",namespace!="",pod!=""}'
4  # Association
5  resources:
6    overrides:
7      namespace: # メトリクスのラベル
8        resource: "namespace"
9      pod: # メトリクスのラベル
10        resource: "pod"
11  # Naming
12  name:
13    matches: "^container_(.*)_seconds_total$"
14    as: "${1}_per_second"
15  # Querying
16  metricsQuery: 'sum(rate(<<.Series>>{<<.LabelMatchers>>,container!="POD"}[2m])) by (<<.GroupBy>>)'

Queryingでは、下記のテンプレートが用意されています。

  • Series: メトリクス名
  • LabelMatchers: Associationで設定したラベル
  • GroupBy: グループ化するためのラベル((LabelMatchersと同じラベル)

作成したメトリクスの確認

下記のコマンドで設定されているカスタムメトリクスを確認できます。バージョンはkubectl get apiservicesで確認してください。

1kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1

そのままだと見づらいので、下記のようにjqで整形して、grepで確認したいメトリクスを指定するのがいいかと思います。

1kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1 | jq | grep -A 7 -B 1 {metrics}

やってみる

ローカルでIstioのistio_requests_totalからreqeusts_per_secondというカスタムメトリクスを作成してみます。

作成するファイルは下記のとおりです。

1.
2├── prometheus
3│   ├── helmfile.yaml
4│   └── prometheus.yaml
5├── prometheus-adapter
6│   ├── helmfile.yaml
7│   └── prometheus-adapter.yaml
8├── helmfile.yaml
9├── istio.yaml
10├── deployment.yaml
11└── service.yaml

helmfileを使って、PrometheusとPrometheus Adapterをデプロイします。

Istioのインストール

Istioのインストールをします。

1istioctl install --set profile=demo -y

default Namespaceでサイドカーの有効化をします。

1kubectl label namespace default istio-injection=enabled

デモアプリのデプロイ

次にデモアプリ用のDeployment、Service、Virtual Service、Gatewayをデプロイします。

deployment.yamlは下記の通りです。

1apiVersion: apps/v1
2kind: Deployment
3metadata:
4  name: nginx
5spec:
6  replicas: 1
7  selector:
8    matchLabels:
9      app: nginx
10  template:
11    metadata:
12      labels:
13        app: nginx
14    spec:
15      containers:
16      - image: nginx
17        name: nginx
18        ports:
19        - containerPort: 80

service.yamlは下記の通りです。

1apiVersion: v1
2kind: Service
3metadata:
4  name: nginx-svc
5spec:
6  ports:
7  - protocol: TCP
8    name: http
9    port: 8000
10    targetPort: 80
11  selector:
12    app: nginx

istio.yamlは下記の通りです。

1apiVersion: networking.istio.io/v1alpha3
2kind: Gateway
3metadata:
4  name: nginx-gateway
5spec:
6  selector:
7    istio: ingressgateway
8  servers:
9  - port:
10      number: 80
11      name: http
12      protocol: HTTP
13    hosts:
14    - "*"
15---
16apiVersion: networking.istio.io/v1alpha3
17kind: VirtualService
18metadata:
19  name: nginx
20spec:
21  hosts:
22  - "*"
23  gateways:
24  - nginx-gateway
25  http:
26  - route:
27    - destination:
28        host: nginx-svc
29        port:
30          number: 8000

それぞれデプロイします。

1kubectl apply -f deployment.yaml
2kubectl apply -f service.yaml
3kubectl apply -f istio.yaml

デモアプリの確認

次にIstioのingressgateway経由でデモアプリにアクセスしてみます。

一度もアクセスしないと、Istioのメトリクスが取得できず、カスタムメトリクスが作成できない可能性があります。

まずはingressgatewayのポート番号を環境変数として設定します。

1export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')

設定した環境変数を使って、ポートフォワードします。

1kubectl -n istio-system port-forward svc/istio-ingressgateway $INGRESS_PORT:80

curlでアクセスしてみます。

1curl localhost:$INGRESS_PORT

PrometheusとPrometheus Adapterのデプロイ

続いて、PrometheusとPrometheus Adapterをhelmfileを使ってデプロイします。

Prometheus

prometheus/helmfile.yamlは下記の通りです。

1releases:
2  - name: prometheus
3    namespace: monitoring
4    chart: prometheus-community/prometheus
5    values:
6      - ./prometheus.yaml

prometheus/prometheus.yamlは下記の通りです。

1alertmanager:
2  enabled: false
3kube-state-metrics:
4  enabled: false
5prometheus-pushgateway:
6  enabled: false
7prometheus-node-exporter:
8  enabled: false
9
10server:
11  service:
12    servicePort: 9090
helm-charts/charts/prometheus at prometheus-adapter-2.7.1 · prometheus-community/helm-charts

helm-charts/charts/prometheus at prometheus-adapter-2.7.1 · prometheus-community/helm-charts

Prometheus community Helm charts. Contribute to prometheus-community/helm-charts development by creating an account on GitHub.

Prometheus Adapter

prometheus-adapter/helmfile.yamlは下記の通りです。

1releases:
2  - name: prometheus-adapter
3    namespace: monitoring
4    chart: prometheus-community/prometheus-adapter
5    values:
6      - ./prometheus-adapter.yaml

prometheus-adapter/prometheus-adapter.yamlは下記の通りです。ここでカスタムメトリクスの定義を記入しています。

1prometheus:
2  url: http://prometheus-server.monitoring.svc.cluster.local
3  port: 9090
4
5rules:
6  custom:
7  - seriesQuery: 'istio_requests_total'
8    resources:
9      overrides:
10        destination_service_namespace:
11          resource: "namespace"
12        destination_service_name:
13          resource: "service"
14    name:
15      as: "requests_per_second"
16    metricsQuery: 'sum(rate(<<.Series>>{<<.LabelMatchers>>, reporter=“destination”}[5m])) by (<<.GroupBy>>)'
helm-charts/charts/prometheus-adapter at prometheus-adapter-2.7.1 · prometheus-community/helm-charts

helm-charts/charts/prometheus-adapter at prometheus-adapter-2.7.1 · prometheus-community/helm-charts

Prometheus community Helm charts. Contribute to prometheus-community/helm-charts development by creating an account on GitHub.

デプロイ

最後にhelmfile.yamlを作成して、PrometheusとPrometheus Adapterをデプロイします。

1helmfiles:
2  - ./prometheus/helmfile.yaml
3  - ./prometheus-adapter/helmfile.yaml
1helmfile apply

メトリクスの確認

APIのバージョンを確認します。

1❯ kubectl get apiservices
2
3NAME                                   SERVICE                         AVAILABLE   AGE
4
5...
6
7v1alpha3.networking.istio.io           Local                           True        5m58s
8v1beta1.custom.metrics.k8s.io          monitoring/prometheus-adapter   True        4m43s
9v1beta1.flowcontrol.apiserver.k8s.io   Local                           True        8m42s
10
11...

作成したカスタムメトリクスを確認してみます。

1❯ kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1 | jq | grep -A 7 -B 1 requests_per_second
2
3    {
4      "name": "services/requests_per_second",
5      "singularName": "",
6      "namespaced": true,
7      "kind": "MetricValueList",
8      "verbs": [
9        "get"
10      ]
11    },
12--
13    {
14      "name": "namespaces/requests_per_second",
15      "singularName": "",
16      "namespaced": false,
17      "kind": "MetricValueList",
18      "verbs": [
19        "get"
20      ]
21    },

これで作成したカスタムメトリクスをHPA(Horizontal Pod Autoscaler)で使えるようになりました。

参考

Support

\ この記事が役に立ったと思ったら、サポートお願いします! /

buy me a coffee
Share

Profile

author

Masa

都内のIT企業で働くエンジニア
自分が学んだことをブログでわかりやすく発信していきながらスキルアップを目指していきます!

buy me a coffee