ターゲットアロケーター
OpenTelemetryオペレーター上でターゲットアロケーターのサービスディスカバリーを有効にしていて、ターゲットアロケーターがスクレイプ対象の検出に失敗した場合に、何が起きているのかを理解し、通常の動作を復元するためにいくつかのトラブルシューティング手順を実行できます。
トラブルシューティング手順
すべてのリソースをKubernetesにデプロイしましたか?
最初のステップとして、関連するすべてのリソースがKubernetesクラスターにデプロイされていることを確認してください。
メトリクスは実際にスクレイプされていますか?
すべてのリソースをKubernetesにデプロイしたら、ターゲットアロケーターが
ServiceMonitor
またはPodMonitorからスクレイプ対象を検出していることを確認してください。
次のような ServiceMonitor
の定義があるとします。
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: sm-example
namespace: opentelemetry
labels:
app.kubernetes.io/name: py-prometheus-app
release: prometheus
spec:
selector:
matchLabels:
app: my-app
namespaceSelector:
matchNames:
- opentelemetry
endpoints:
- port: prom
path: /metrics
- port: py-client-port
interval: 15s
- port: py-server-port
これは Service
の定義です。
apiVersion: v1
kind: Service
metadata:
name: py-prometheus-app
namespace: opentelemetry
labels:
app: my-app
app.kubernetes.io/name: py-prometheus-app
spec:
selector:
app: my-app
app.kubernetes.io/name: py-prometheus-app
ports:
- name: prom
port: 8080
これは OpenTelemetryCollector
の定義です。
apiVersion: opentelemetry.io/v1beta1
kind: OpenTelemetryCollector
metadata:
name: otelcol
namespace: opentelemetry
spec:
mode: statefulset
targetAllocator:
enabled: true
serviceAccount: opentelemetry-targetallocator-sa
prometheusCR:
enabled: true
podMonitorSelector: {}
serviceMonitorSelector: {}
config:
receivers:
otlp:
protocols:
grpc: {}
http: {}
prometheus:
config:
scrape_configs:
- job_name: 'otel-collector'
scrape_interval: 10s
static_configs:
- targets: ['0.0.0.0:8888']
processors:
batch: {}
exporters:
debug:
verbosity: detailed
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [debug]
metrics:
receivers: [otlp, prometheus]
processors: []
exporters: [debug]
logs:
receivers: [otlp]
processors: [batch]
exporters: [debug]
まず、Kubernetesで port-forward
を設定し、ターゲットアロケーターのサービスを公開できるようにします。
kubectl port-forward svc/otelcol-targetallocator -n opentelemetry 8080:80
otelcol-targetallocator
は OpenTelemetryCollector
CRの metadata.name
の値と -targetallocator
サフィックスを連結したもので、opentelemetry
は OpenTelemetryCollector
CRがデプロイされている名前空間です。
次のコマンドを実行してサービス名を取得することもできます。
kubectl get svc -l app.kubernetes.io/component=opentelemetry-targetallocator -n <namespace>
次に、ターゲットアロケーターに登録されているジョブのリストを取得します。
curl localhost:8080/jobs | jq
サンプル出力は次のようになります。
{
"serviceMonitor/opentelemetry/sm-example/1": {
"_link": "/jobs/serviceMonitor%2Fopentelemetry%2Fsm-example%2F1/targets"
},
"serviceMonitor/opentelemetry/sm-example/2": {
"_link": "/jobs/serviceMonitor%2Fopentelemetry%2Fsm-example%2F2/targets"
},
"otel-collector": {
"_link": "/jobs/otel-collector/targets"
},
"serviceMonitor/opentelemetry/sm-example/0": {
"_link": "/jobs/serviceMonitor%2Fopentelemetry%2Fsm-example%2F0/targets"
},
"podMonitor/opentelemetry/pm-example/0": {
"_link": "/jobs/podMonitor%2Fopentelemetry%2Fpm-example%2F0/targets"
}
}
serviceMonitor/opentelemetry/sm-example/0
は、ServiceMonitor
が取得した Service
ポートのひとつを表しています。
opentelemetry
はServiceMonitor
リソースが存在する名前空間です。sm-example
はServiceMonitor
の名前です。0
は、ServiceMonitor
とService
の間で一致するポートエンドポイントのひとつです。
同様に、PodMonitor
は curl
の出力で podMonitor/opentelemetry/pm-example/0
として表示されます。
これは、スクレイプ構成の検出が機能していることを示す朗報です!
これは、(otel-collector
という名前の)OpenTelemetryCollector
リソースの spec.config.receivers.prometheusReceiver
でセルフスクレイプが有効になっているためです。
prometheus:
config:
scrape_configs:
- job_name: 'otel-collector'
scrape_interval: 10s
static_configs:
- targets: ['0.0.0.0:8888']
上記の _link
の出力値に対して curl
を実行して、serviceMonitor/opentelemetry/sm-example/0
の詳細を確認し、どのスクレイプ対象が取得されているかを確認できます。
curl localhost:8080/jobs/serviceMonitor%2Fopentelemetry%2Fsm-example%2F0/targets | jq
サンプル出力
{
"otelcol-collector-0": {
"_link": "/jobs/serviceMonitor%2Fopentelemetry%2Fsm-example%2F0/targets?collector_id=otelcol-collector-0",
"targets": [
{
"targets": ["10.244.0.11:8080"],
"labels": {
"__meta_kubernetes_endpointslice_port_name": "prom",
"__meta_kubernetes_pod_labelpresent_app_kubernetes_io_name": "true",
"__meta_kubernetes_endpointslice_port_protocol": "TCP",
"__meta_kubernetes_endpointslice_address_target_name": "py-prometheus-app-575cfdd46-nfttj",
"__meta_kubernetes_endpointslice_annotation_endpoints_kubernetes_io_last_change_trigger_time": "2024-06-21T20:01:37Z",
"__meta_kubernetes_endpointslice_labelpresent_app_kubernetes_io_name": "true",
"__meta_kubernetes_pod_name": "py-prometheus-app-575cfdd46-nfttj",
"__meta_kubernetes_pod_controller_name": "py-prometheus-app-575cfdd46",
"__meta_kubernetes_pod_label_app_kubernetes_io_name": "py-prometheus-app",
"__meta_kubernetes_endpointslice_address_target_kind": "Pod",
"__meta_kubernetes_pod_node_name": "otel-target-allocator-talk-control-plane",
"__meta_kubernetes_pod_labelpresent_pod_template_hash": "true",
"__meta_kubernetes_endpointslice_label_kubernetes_io_service_name": "py-prometheus-app",
"__meta_kubernetes_endpointslice_annotationpresent_endpoints_kubernetes_io_last_change_trigger_time": "true",
"__meta_kubernetes_service_name": "py-prometheus-app",
"__meta_kubernetes_pod_ready": "true",
"__meta_kubernetes_pod_labelpresent_app": "true",
"__meta_kubernetes_pod_controller_kind": "ReplicaSet",
"__meta_kubernetes_endpointslice_labelpresent_app": "true",
"__meta_kubernetes_pod_container_image": "otel-target-allocator-talk:0.1.0-py-prometheus-app",
"__address__": "10.244.0.11:8080",
"__meta_kubernetes_service_label_app_kubernetes_io_name": "py-prometheus-app",
"__meta_kubernetes_pod_uid": "495d47ee-9a0e-49df-9b41-fe9e6f70090b",
"__meta_kubernetes_endpointslice_port": "8080",
"__meta_kubernetes_endpointslice_label_endpointslice_kubernetes_io_managed_by": "endpointslice-controller.k8s.io",
"__meta_kubernetes_endpointslice_label_app": "my-app",
"__meta_kubernetes_service_labelpresent_app_kubernetes_io_name": "true",
"__meta_kubernetes_pod_host_ip": "172.24.0.2",
"__meta_kubernetes_namespace": "opentelemetry",
"__meta_kubernetes_endpointslice_endpoint_conditions_serving": "true",
"__meta_kubernetes_endpointslice_labelpresent_kubernetes_io_service_name": "true",
"__meta_kubernetes_endpointslice_endpoint_conditions_ready": "true",
"__meta_kubernetes_service_annotation_kubectl_kubernetes_io_last_applied_configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Service\",\"metadata\":{\"annotations\":{},\"labels\":{\"app\":\"my-app\",\"app.kubernetes.io/name\":\"py-prometheus-app\"},\"name\":\"py-prometheus-app\",\"namespace\":\"opentelemetry\"},\"spec\":{\"ports\":[{\"name\":\"prom\",\"port\":8080}],\"selector\":{\"app\":\"my-app\",\"app.kubernetes.io/name\":\"py-prometheus-app\"}}}\n",
"__meta_kubernetes_endpointslice_endpoint_conditions_terminating": "false",
"__meta_kubernetes_pod_container_port_protocol": "TCP",
"__meta_kubernetes_pod_phase": "Running",
"__meta_kubernetes_pod_container_name": "my-app",
"__meta_kubernetes_pod_container_port_name": "prom",
"__meta_kubernetes_pod_ip": "10.244.0.11",
"__meta_kubernetes_service_annotationpresent_kubectl_kubernetes_io_last_applied_configuration": "true",
"__meta_kubernetes_service_labelpresent_app": "true",
"__meta_kubernetes_endpointslice_address_type": "IPv4",
"__meta_kubernetes_service_label_app": "my-app",
"__meta_kubernetes_pod_label_app": "my-app",
"__meta_kubernetes_pod_container_port_number": "8080",
"__meta_kubernetes_endpointslice_name": "py-prometheus-app-bwbvn",
"__meta_kubernetes_pod_label_pod_template_hash": "575cfdd46",
"__meta_kubernetes_endpointslice_endpoint_node_name": "otel-target-allocator-talk-control-plane",
"__meta_kubernetes_endpointslice_labelpresent_endpointslice_kubernetes_io_managed_by": "true",
"__meta_kubernetes_endpointslice_label_app_kubernetes_io_name": "py-prometheus-app"
}
}
]
}
}
上記の出力の _link
フィールドのクエリパラメータ collector_id
は、これらのターゲットが otelcol-collector-0
(OpenTelemetryCollector
リソースのために作成された StatefulSet
の名前) に関連することを示しています。
/jobs
エンドポイントのより詳細な情報については、ターゲットアロケーターのREADMEを参照してください。
ターゲットアロケーターは有効ですか?Prometheusのサービスディスカバリーは有効ですか?
上記の curl
コマンドで期待される ServiceMonitor
や PodMonitor
のリストが表示されない場合、それらの値を設定する機能が有効になっているかを確認する必要があります。
留意すべきことは、OpenTelemetryCollector
CRに targetAllocator
セクションを含めたからといって、それが有効になるわけではないということです。
ターゲットアロケーターは明示的に有効化する必要があります。
さらに、Prometheusのサービスディスカバリーを使用する場合は、明示的に有効化する必要があります。
spec.targetAllocator.enabled
をtrue
に設定するspec.targetAllocator.prometheusCR.enabled
をtrue
に設定する
OpenTelemetryCollector
リソースは次のようになります。
apiVersion: opentelemetry.io/v1beta1
kind: OpenTelemetryCollector
metadata:
name: otelcol
namespace: opentelemetry
spec:
mode: statefulset
targetAllocator:
enabled: true
serviceAccount: opentelemetry-targetallocator-sa
prometheusCR:
enabled: true
完全な OpenTelemetryCollector
リソース定義については"メトリクスは実際にスクレイプされていますか?"を参照してください。
ServiceMonitor (または PodMonitor) のセレクターを設定しましたか?
ServiceMonitor
のセレクターを設定した場合、ターゲットアロケーターはserviceMonitorSelector
の値と一致する metadata.label
を持つ ServiceMonitor
のみを探すことになります。
次の例のように、ターゲットアロケーターにserviceMonitorSelector
を設定したとします。
apiVersion: opentelemetry.io/v1beta1
kind: OpenTelemetryCollector
metadata:
name: otelcol
namespace: opentelemetry
spec:
mode: statefulset
targetAllocator:
enabled: true
serviceAccount: opentelemetry-targetallocator-sa
prometheusCR:
enabled: true
serviceMonitorSelector:
matchLabels:
app: my-app
app: my-app
に spec.targetAllocator.prometheusCR.serviceMonitorSelector.matchLabels
の値を設定することで、ServiceMonitor
リソースの metadata.labels
にも同じ値が必要になります。
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: sm-example
labels:
app: my-app
release: prometheus
spec:
完全な ServiceMonitor
リソース定義については"メトリクスは実際にスクレイプされていますか?"を参照してください。
この場合、 OpenTelemetryCollector
リソースの prometheusCR.serviceMonitorSelector.matchLabels
は、前の例にあったように app: my-app
ラベルを持つ ServiceMonitor
のみを探します。
ServiceMonitor
リソースにそのラベルがない場合、ターゲットアロケーターはその ServiceMonitor
からスクレイプ対象を検出できません。
PodMonitorを使用している場合も同様です。
その場合は、serviceMonitorSelector
のかわりに podMonitorSelector
を使用します。
serviceMonitorSelector
および/または podMonitorSelector
の構成を完全に省略しましたか?
“ServiceMonitor (または PodMonitor) のセレクターを設定しましたか?”で述べたように、serviceMonitorSelector
と podMonitorSelector
に一致しない値が設定されている場合、ターゲットアロケーターはそれぞれの ServiceMonitor
と PodMonitor
からスクレイプ対象を検出できなくなります。
同様に、OpenTelemetryCollector
CRのv1beta1
では、この構成を完全に省略すると、ターゲットアロケーターは ServiceMonitor
と PodMonitor
からスクレイプ対象を検出できなくなります。
OpenTelemetryCollector
の v1beta1
では、serviceMonitorSelector
と podMonitorSelector
を使用する予定がない場合でも、次のように含める必要があります。
prometheusCR:
enabled: true
podMonitorSelector: {}
serviceMonitorSelector: {}
この構成は、すべての PodMonitor
および ServiceMonitor
リソースに一致することを意味します。
完全なOpenTelemetryCollectorの定義については、“メトリクスは実際にスクレイプされていますか? “を参照してください。
ServiceMonitorとService(または PodMonitor と Pod)のラベル、名前空間、ポートは一致していますか?
ServiceMonitor
は、次の条件に一致するKubernetesの
Serviceを取得するように構成されています。
- ラベル
- 名前空間 (optional)
- ポート (エンドポイント)
次のような ServiceMonitor
があるとします。
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: sm-example
labels:
app: my-app
release: prometheus
spec:
selector:
matchLabels:
app: my-app
namespaceSelector:
matchNames:
- opentelemetry
endpoints:
- port: prom
path: /metrics
- port: py-client-port
interval: 15s
- port: py-server-port
前述の ServiceMonitor
は、次の条件に一致するサービスを探しています。
- ラベルが
app: my-app
opentelemetry
という名前空間に存在するprom
、py-client-port
、またはpy-server-port
という名前のポート
たとえば、次の Service
リソースは前述の条件に一致するため、ServiceMonitor
によって取得されます。
apiVersion: v1
kind: Service
metadata:
name: py-prometheus-app
namespace: opentelemetry
labels:
app: my-app
app.kubernetes.io/name: py-prometheus-app
spec:
selector:
app: my-app
app.kubernetes.io/name: py-prometheus-app
ports:
- name: prom
port: 8080
次の Service
リソースは、ServiceMonitor
が prom
、py-client-port
、または py-server-port
という名前のポートを探していますが、このサービスのポートは bleh
という名前であるため取得されません。
apiVersion: v1
kind: Service
metadata:
name: py-prometheus-app
namespace: opentelemetry
labels:
app: my-app
app.kubernetes.io/name: py-prometheus-app
spec:
selector:
app: my-app
app.kubernetes.io/name: py-prometheus-app
ports:
- name: bleh
port: 8080
PodMonitor
を使用している場合も同様に、ラベル、名前空間、およびポート名で一致するKubernetesのPodを取得します。
フィードバック
このページは役に立ちましたか?
Thank you. Your feedback is appreciated!
Please let us know how we can improve this page. Your feedback is appreciated!