k8s内のミドルウェアのメトリクスをOpenTelemetry Collectorで取得
はじめに
Kubernetesをモニタリングでもするかとなったとき、コンテナで動かしているNginxやRedisなども監視したい!という要望が当然出てくると思います。
そこで問題になるのは、Podは増減してIPアドレスも自動割り振りである点です。
PrometheusだとSidecarでExporterをデプロイしてlocalhostに対してモニタリングしてね、という感じだと思いますが、構成が手間だったりリソースが重複したりと無駄が多かったりします。
OpenTelemetry Collector(Otel Collector)はこの課題を「Receiver Creator」で解決しています。
この記事ではReceiver Creatorは何をしてくれるものか、どう設定するのかを見てきたいと思います。
Otel CollectorのReceiver Creatorとは
簡単に言うと任意のReceiverを動的に構成してくれるReceiverです。
詳細はこちら。
Extensionの「k8s_observer」が指定した条件のエンドポイントを検出し、receiver_creatorがそのエンドポイントに対するReceiverの設定(IPアドレス、ポート)を構成してくれます。
k8s_observer
extensionにはいくつかの「observer」シリーズがあります。
k8s_observerの他にもdocker_observer、host_observerなど。基本的にreceiver_creatorのためのものだと思われます。
今回使うk8s_observerはNodeまたはPodを検出してくれます。
extensions:
k8s_observer:
auth_type: serviceAccount #k8s APIの認証方法。デフォルト=serviceAccount。
node: ${env:K8S_NODE_NAME} #探索範囲のNodeの制限。デフォルト=空。
observe_pods: true #Podの検出。デフォルト=true。
observe_nodes: true #Nodeの検出。デフォルト=false。
特別な要件がなければデフォルト値でOKだと思います。
extensions:
k8s_observer:
receiver_creator
receiver_creatorは上記で説明した通りreceiverの自動構成の他、メトリクスにAttributeの付与も可能です。PodのLabelやAnnotationから値を引っ張ることができます。例えばサービス名やチーム名をLabelに入れ込んでいた場合にメトリクスにも付与できたら便利ですね。
receiver_creatorはreceiverの一種なので以下のように構成します。
receivers:
receiver_creator:
watch_observers: [k8s_observer]
receivers:
<receiver名>: -- 1
rule: <observe rule> -- 2
config: -- 3
<各receiverのコンフィグ>
resource_attributes: -- 4
<attribute>: <attribute string value>
resource_attributes: -- 5
<pod or port>
<attribute>: <attribute string value>
-
1. receiver名
構成したいreceiver名です。nginx
、redis
などです。 -
2. observe rule
例:rule: type == "port" && port == 80 && pod.name matches "nginx-proxy"
まずtypeをport
、pod
など指定し、各typeに応じた条件を指定します。利用可能な条件はGithubをご覧ください。
上記の例では、ポート80を公開し、pod名にnginx-proxyを含むPodを検出します。
type=portではpod.labels
、pod.annotaions
、pod.namespace
なども使えます。 -
3. 各receiverのコンフィグ
構成したいreceiverで指定すべきコンフィグです。
もしそのreceiverでendpoint
を指定するようになっている場合、receiver_creatorが検出したIPアドレス、ポート番号を元に自動的に設定してくれます。
endpoint
以外のコンフィグにエンドポイント情報の設定が必要な場合、手動で設定することもできます。
IPアドレスは`endpoint`、ポート番号は`kubelet_endpoint_port`で取得できます。 -
4. resource_attributes
Attributeのキーと値のセットを指定します。
ruleと同じ書式で値を取れます。type=portでは`pod.labels["label名"]`、`pod.annotations["annotation名"]`などです。 -
5. receiver_creator.resource_attributes
receiver_creator.resource_attributes
を使うと全てのreceiverにまたがった付与が可能です。
yaml例
上記を組み合わせて、以下のようにすればOKです。nginx receiverで利用可能なコンフィグはendpoint
とcollection_interval
であり、endpoint
は自動構成、collection_interval
はデフォルト値(10秒)のままにするため、configをまるっと排除しています。
extensions:
k8s_observer:
receivers:
receiver_creator:
watch_observers: [k8s_observer]
receivers:
nginx:
rule: type == "port" && port == 80 && pod.name matches "nginx-proxy"
resource_attributes:
team: "`pod.labels['service_name']`"
service:
pipelines:
metrics:
receivers: [receiver_creator]
processors: [<任意のprocessor>]
exporters: [<任意のexporter>]
試してみる
Splunk Observability Cloudに送ってみたいと思います。
OpenTelemetry CollectorをKubernetes用に色々と整備したSplunk OpenTelemetry Collector for Kubernetesが用意されておりますので、こちらを使います。
詳しくはこちら。
Splunk Otel for k8sはHelm Chartが用意されておりOtel Collectorの設定もvalues.yamlから行えます。
(通常のOtelを使う場合は最近だとOpenTelemetry Operator for Kubernetesがいいのではないかと思います)
extensions.k8s_observerとpipelineはデフォルトで用意されているので、receiver_creatorのみの設定だけ行えばOKです。
my_values.yamlで設定をまとめます。ついでに他の必須設定も入れておきます。
- Otel Collectorの設定は
agent.config
配下で設定できます。 -
smartagent/redis
、smartagent/nginx
はSplunk Otelで用意されているreceiverです。 - resource_attributesをreceiver_creatorの配下にセットし、共通的にAttribute付与しています。
clusterName: <クラスタ名>
splunkObservability:
realm: <REALM>
accessToken: <アクセストークン>
agent:
config:
receivers:
receiver_creator:
receivers:
smartagent/redis:
rule: type == "port" && port == 6379 && pod.name matches "redis"
config:
type: collectd/redis
smartagent/nginx:
rule: type == "port" && port == 80 && pod.name matches "nginx-proxy"
config:
type: collectd/nginx
resource_attributes:
port:
k8s.pod.name: "`pod.name`"
k8s.pod.uid: "`pod.uid`"
k8s.namespace.name: "`pod.namespace`"
service_name: "`pod.labels['service_name']`"
team: "`pod.labels['team']`"
HELMでインストールします。
helm repo add splunk-otel-collector-chart https://signalfx.github.io/splunk-otel-collector-chart
helm install my-test splunk-otel-collector-chart/splunk-otel-collector -f ./my_values.yaml
Otel collectorのログを確認すると、nginxの方は「"endpoint": "10.244.2.231:80"」が検出できていました。このIPアドレスはPodに割り当てられたものです。
2023-05-19T11:58:25.628Z info receivercreator@v0.76.3/observerhandler.go:101 starting receiver {"kind": "receiver", "name": "receiver_creator", "data_type": "metrics", "name": "smartagent/nginx", "endpoint": "10.244.2.231:80", "endpoint_id": "k8s_observer/4943d62f-460f-4b87-bd79-ec1b10d233a6/(80)"}
Splunk Observability Cloudを確認すると無事メトリクスが取れておりダッシュボードで表示されました。
Attributeも無事設定されていました。いいですね。
次にnginxのdeploymentのreplica数を1⇒3に変えてみます。
そうするとOtel CollectorもPod増加に伴いreceiver_creatorが新たに2件を検出、メトリクス取得開始してくれました。
2023-05-19T11:59:06.627Z info receivercreator@v0.76.3/observerhandler.go:101 starting receiver {"kind": "receiver", "name": "receiver_creator", "data_type": "metrics", "name": "smartagent/nginx", "endpoint": "10.244.2.233:80", "endpoint_id": "k8s_observer/b41e31ae-9107-436d-a0d1-10d934efe0f4/(80)"}
2023-05-19T11:59:08.627Z info receivercreator@v0.76.3/observerhandler.go:101 starting receiver {"kind": "receiver", "name": "receiver_creator", "data_type": "metrics", "name": "smartagent/nginx", "endpoint": "10.244.2.234:80", "endpoint_id": "k8s_observer/03e4a7f1-79c0-436b-95c8-922ea0a4f325/(80)"}
まとめ
receiver_creatorは初見だとちょっと分かりにくいかもしれませんが、定義を一ヶ所で管理できるのでとても便利だと思います。
Discussion