OpenTelemetry Collector 구현하거나 배포하여 Strimzi 연산자를 사용하여 Kubernetes 에서 실행 중인 Kafka 클러스터를 모니터링합니다. 수집기는 Kafka 브로커를 자동으로 발견하고 포괄적인 정보를 수집합니다.
설치 및 구성
쿠버네티스 클러스터에서 OpenTelemetry Collector 구현하고 배포하고 구성하려면 다음 단계에 따라 Strimzi Kafka 브로커를 자동으로 검색하고 모니터링하세요.
Kafka JMX 메트릭을 위해 Kafka 클러스터를 구성합니다.
Strimzi Kafka 클러스터를 구성하여 Prometheus JMX Exporter를 통해 Kafka JMX 메트릭을 노출하십시오. 이 설정은 ConfigMap으로 구현되고 배포되며 Kafka 클러스터에서 참조됩니다.
JMX 메트릭 ConfigMap을 생성합니다.
수집할 Kafka 메트릭을 정의하는 JMX Exporter 패턴이 포함된 ConfigMap을 생성합니다. kafka-jmx-metrics-config.yaml 으로 저장:
apiVersion: v1kind: ConfigMapmetadata: name: kafka-jmx-metrics namespace: newrelicdata: kafka-metrics-config.yml: | startDelaySeconds: 0 lowercaseOutputName: true lowercaseOutputLabelNames: true
rules: # Cluster-level controller metrics - pattern: 'kafka.controller<type=KafkaController, name=GlobalTopicCount><>Value' name: kafka_cluster_topic_count type: GAUGE
- pattern: 'kafka.controller<type=KafkaController, name=GlobalPartitionCount><>Value' name: kafka_cluster_partition_count type: GAUGE
- pattern: 'kafka.controller<type=KafkaController, name=FencedBrokerCount><>Value' name: kafka_broker_fenced_count type: GAUGE
- pattern: 'kafka.controller<type=KafkaController, name=PreferredReplicaImbalanceCount><>Value' name: kafka_partition_non_preferred_leader type: GAUGE
- pattern: 'kafka.controller<type=KafkaController, name=OfflinePartitionsCount><>Value' name: kafka_partition_offline type: GAUGE
- pattern: 'kafka.controller<type=KafkaController, name=ActiveControllerCount><>Value' name: kafka_controller_active_count type: GAUGE
# Broker-level replica metrics - pattern: 'kafka.server<type=ReplicaManager, name=UnderMinIsrPartitionCount><>Value' name: kafka_partition_under_min_isr type: GAUGE
- pattern: 'kafka.server<type=ReplicaManager, name=LeaderCount><>Value' name: kafka_broker_leader_count type: GAUGE
- pattern: 'kafka.server<type=ReplicaManager, name=PartitionCount><>Value' name: kafka_partition_count type: GAUGE
- pattern: 'kafka.server<type=ReplicaManager, name=UnderReplicatedPartitions><>Value' name: kafka_partition_under_replicated type: GAUGE
- pattern: 'kafka.server<type=ReplicaManager, name=IsrShrinksPerSec><>Count' name: kafka_isr_operation_count type: COUNTER labels: operation: "shrink"
- pattern: 'kafka.server<type=ReplicaManager, name=IsrExpandsPerSec><>Count' name: kafka_isr_operation_count type: COUNTER labels: operation: "expand"
- pattern: 'kafka.server<type=ReplicaFetcherManager, name=MaxLag, clientId=Replica><>Value' name: kafka_max_lag type: GAUGE
# Broker topic metrics (totals) - pattern: 'kafka.server<type=BrokerTopicMetrics, name=MessagesInPerSec><>Count' name: kafka_message_count type: COUNTER
- pattern: 'kafka.server<type=BrokerTopicMetrics, name=TotalFetchRequestsPerSec><>Count' name: kafka_request_count type: COUNTER labels: type: "fetch"
- pattern: 'kafka.server<type=BrokerTopicMetrics, name=TotalProduceRequestsPerSec><>Count' name: kafka_request_count type: COUNTER labels: type: "produce"
- pattern: 'kafka.server<type=BrokerTopicMetrics, name=FailedFetchRequestsPerSec><>Count' name: kafka_request_failed type: COUNTER labels: type: "fetch"
- pattern: 'kafka.server<type=BrokerTopicMetrics, name=FailedProduceRequestsPerSec><>Count' name: kafka_request_failed type: COUNTER labels: type: "produce"
- pattern: 'kafka.server<type=BrokerTopicMetrics, name=BytesInPerSec><>Count' name: kafka_network_io type: COUNTER labels: direction: "in"
- pattern: 'kafka.server<type=BrokerTopicMetrics, name=BytesOutPerSec><>Count' name: kafka_network_io type: COUNTER labels: direction: "out"
# Per-topic metrics (only appear after traffic flows) - pattern: 'kafka.server<type=BrokerTopicMetrics, name=MessagesInPerSec, topic=(.+)><>Count' name: kafka_prod_msg_count type: COUNTER labels: topic: "$1"
- pattern: 'kafka.server<type=BrokerTopicMetrics, name=BytesInPerSec, topic=(.+)><>Count' name: kafka_topic_io type: COUNTER labels: topic: "$1" direction: "in"
- pattern: 'kafka.server<type=BrokerTopicMetrics, name=BytesOutPerSec, topic=(.+)><>Count' name: kafka_topic_io type: COUNTER labels: topic: "$1" direction: "out"
# Request metrics - pattern: 'kafka.network<type=RequestMetrics, name=TotalTimeMs, request=(Produce|FetchConsumer|FetchFollower)><>Count' name: kafka_request_time_total type: COUNTER labels: type: "$1"
- pattern: 'kafka.network<type=RequestMetrics, name=TotalTimeMs, request=(Produce|FetchConsumer|FetchFollower)><>50thPercentile' name: kafka_request_time_50p type: GAUGE labels: type: "$1"
- pattern: 'kafka.network<type=RequestMetrics, name=TotalTimeMs, request=(Produce|FetchConsumer|FetchFollower)><>99thPercentile' name: kafka_request_time_99p type: GAUGE labels: type: "$1"
- pattern: 'kafka.network<type=RequestMetrics, name=TotalTimeMs, request=(Produce|FetchConsumer|FetchFollower)><>Mean' name: kafka_request_time_avg type: GAUGE labels: type: "$1"
- pattern: 'kafka.network<type=RequestChannel, name=RequestQueueSize><>Value' name: kafka_request_queue type: GAUGE
- pattern: 'kafka.server<type=DelayedOperationPurgatory, name=PurgatorySize, delayedOperation=(.+)><>Value' name: kafka_purgatory_size type: GAUGE labels: type: "$1"
# Controller stats - pattern: 'kafka.controller<type=ControllerStats, name=LeaderElectionRateAndTimeMs><>Count' name: kafka_leader_election_rate type: COUNTER
- pattern: 'kafka.controller<type=ControllerStats, name=UncleanLeaderElectionsPerSec><>Count' name: kafka_unclean_election_rate type: COUNTER
# Log flush metrics - pattern: 'kafka.log<type=LogFlushStats, name=LogFlushRateAndTimeMs><>Count' name: kafka_logs_flush_count type: COUNTER
- pattern: 'kafka.log<type=LogFlushStats, name=LogFlushRateAndTimeMs><>50thPercentile' name: kafka_logs_flush_time_50p type: GAUGE
- pattern: 'kafka.log<type=LogFlushStats, name=LogFlushRateAndTimeMs><>99thPercentile' name: kafka_logs_flush_time_99p type: GAUGE
# JVM Garbage Collection - pattern: 'java.lang<name=(.+), type=GarbageCollector><>CollectionCount' name: jvm_gc_collections_count type: COUNTER labels: name: "$1"
- pattern: 'java.lang<name=(.+), type=GarbageCollector><>CollectionTime' name: jvm_gc_collections_elapsed type: COUNTER labels: name: "$1"
# JVM Memory - pattern: 'java.lang<type=Memory><HeapMemoryUsage>committed' name: jvm_memory_heap_committed type: GAUGE
- pattern: 'java.lang<type=Memory><HeapMemoryUsage>max' name: jvm_memory_heap_max type: GAUGE
- pattern: 'java.lang<type=Memory><HeapMemoryUsage>used' name: jvm_memory_heap_used type: GAUGE
# JVM Threading and System - pattern: 'java.lang<type=Threading><>ThreadCount' name: jvm_thread_count type: GAUGE
- pattern: 'java.lang<type=OperatingSystem><>SystemLoadAverage' name: jvm_system_cpu_load_1m type: GAUGE
- pattern: 'java.lang<type=OperatingSystem><>AvailableProcessors' name: jvm_cpu_count type: GAUGE
- pattern: 'java.lang<type=OperatingSystem><>ProcessCpuLoad' name: jvm_cpu_recent_utilization type: GAUGE
- pattern: 'java.lang<type=OperatingSystem><>SystemCpuLoad' name: jvm_system_cpu_utilization type: GAUGE
- pattern: 'java.lang<type=OperatingSystem><>OpenFileDescriptorCount' name: jvm_file_descriptor_count type: GAUGE
- pattern: 'java.lang<type=ClassLoading><>LoadedClassCount' name: jvm_class_count type: GAUGE
# JVM Memory Pool - pattern: 'java.lang<type=MemoryPool, name=(.+)><Usage>used' name: jvm_memory_pool_used type: GAUGE labels: name: "$1"
- pattern: 'java.lang<type=MemoryPool, name=(.+)><Usage>max' name: jvm_memory_pool_max type: GAUGE labels: name: "$1"
- pattern: 'java.lang<type=MemoryPool, name=(.+)><CollectionUsage>used' name: jvm_memory_pool_used_after_last_gc type: GAUGE labels: name: "$1"
# Broker uptime - pattern: 'java.lang<type=Runtime><>Uptime' name: kafka_broker_uptime type: GAUGE팁
메트릭 사용자 지정: 이 ConfigMap에는 Kafka 브로커, 토픽, 요청, 컨트롤러 및 JVM에 대한 포괄적인 메트릭이 포함되어 있습니다. Prometheus JMX Exporter 예제 및 Kafka MBean 문서를 참조하여 패턴을 추가하거나 수정할 수 있습니다. 추가 설정은 JMX Exporter 규칙 문서를 참조하십시오.
중요
지우개 스페이스 요구 사항: JMX 지표 ConfigMap과 Kafka 클러스터는 동일한 지우개 스페이스에 있어야 합니다. 이 가이드에서는 둘 다 newrelic 지우스페이스에 구현하다, 배포하다입니다.
ConfigMap을 적용합니다.
$kubectl apply -f kafka-jmx-metrics-config.yamlKafka 클러스터를 JMX Exporter를 사용하도록 업데이트합니다.
Strimzi Kafka 리소스가 메트릭 ConfigMap을 참조하도록 업데이트하세요.
apiVersion: kafka.strimzi.io/v1beta2kind: Kafkametadata: name: my-cluster namespace: newrelicspec: kafka: version: X.X.X metricsConfig: type: jmxPrometheusExporter valueFrom: configMapKeyRef: name: kafka-jmx-metrics key: kafka-metrics-config.yml # ...rest of your Kafka configuration변경 사항을 적용하세요. Strimzi는 Kafka 브로커를 순차적으로 재시작합니다.
$kubectl apply -f kafka-cluster.yaml롤링 재시작이 완료되면 각 Kafka 브로커는 9404 포트에서 Prometheus 메트릭을 노출합니다.
구현하다, 배포하다 OpenTelemetry Collector
Kafka 클러스터를 모니터링하기 위한 OpenTelemetry Collector 구현하다, 배포합니다. 원하는 설치 방법을 선택하세요.
Helm 설치 방법은 Kubernetes 에서 구현하다, 배포하다 OpenTelemetry Collector 에 권장되는 접근 방식입니다.
뉴렐릭 자격 증명 비밀을 생성합니다.
뉴렐릭 클러스터 키 및 OTLP 엔드포인트가 포함된 Kubernetes 시크릿을 생성하세요. 귀하의 뉴렐릭 지역에 맞는 포인트를 선택하세요:
팁
다른 엔드포인트 설정에 대해서는 OTLP 엔드포인트 구성을 참조하세요.
수집기 설정을 포함하는 values.yaml 파일을 생성합니다.
OpenTelemetry Collector 설정 전체 내용이 포함된 values.yaml 파일을 생성하세요. NRDOT과 OpenTelemetry 수집기 모두 동일한 설정을 사용하고 동일한 Kafka 모니터링 기능을 제공합니다. 원하는 수집기 이미지를 선택하세요:
고급 설정 옵션에 대해서는 다음 수신기 설명서 페이지를 참조하십시오.
Prometheus 수신기 문서 - 추가 수신기 설정 옵션
Kafka 지표 수신기 문서 - 추가 Kafka 지표 설정
Helm을 사용하여 OpenTelemetry Collector를 설치합니다.
Helm 저장소를 추가하고 values.yaml 파일을 사용하여 OpenTelemetry Collector를 설치하세요.
bash$helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts$helm upgrade kafka-monitoring open-telemetry/opentelemetry-collector \>--install \>--namespace newrelic \>--create-namespace \>-f values.yaml구현을 확인하세요.
bash$# Check pod status$kubectl get pods -n newrelic -l app.kubernetes.io/name=opentelemetry-collector$$# View logs to verify metrics collection$kubectl logs -n newrelic -l app.kubernetes.io/name=opentelemetry-collector --tail=50포트 9404의 Kafka 브로커에서 스크래핑이 성공적으로 완료되었음을 나타내는 로그를 확인할 수 있습니다.
매니페스트 설치 방식은 Helm을 사용하지 않고도 Kubernetes 리소스를 직접 제어할 수 있도록 해줍니다.
뉴렐릭 자격 증명 비밀을 생성합니다.
뉴렐릭 클러스터 키 및 OTLP 엔드포인트가 포함된 Kubernetes 시크릿을 생성하세요. 귀하의 뉴렐릭 지역에 맞는 포인트를 선택하세요:
팁
다른 엔드포인트 설정에 대해서는 OTLP 엔드포인트 구성을 참조하세요.
매니페스트 파일 생성
원하는 수집기를 위한 Kubernetes 매니페스트 파일을 생성하세요. 두 수집기 모두 동일한 설정을 사용하며 이미지만 다릅니다.
수집기 옵션을 선택하고 필요한 파일 세 개를 생성하세요.
고급 설정 옵션에 대해서는 다음 수신기 설명서 페이지를 참조하십시오.
Prometheus 수신기 문서 - 추가 수신기 설정 옵션
Kafka 지표 수신기 문서 - 추가 Kafka 지표 설정
구현하다, 배포하다 매니페스트
Kubernetes 매니페스트를 구현에 적용하고 OpenTelemetry Collector 배포합니다.
bash$# Create namespace if it doesn't exist$kubectl create namespace newrelic --dry-run=client -o yaml | kubectl apply -f -$$# Apply RBAC configuration$kubectl apply -f collector-rbac.yaml$$# Apply ConfigMap$kubectl apply -f collector-configmap.yaml$$# Apply Deployment$kubectl apply -f collector-deployment.yaml구현을 확인하세요.
bash$# Check pod status$kubectl get pods -n newrelic -l app=otel-collector$$# View logs to verify metrics collection$kubectl logs -n newrelic -l app=otel-collector --tail=50포트 9404의 Kafka 브로커에서 스크래핑이 성공적으로 완료되었음을 나타내는 로그를 확인할 수 있습니다.
(선택사항) 제작자 또는 소비자를 위해
중요
언어 지원: OpenTelemetry 측 에이전트를 사용하여 즉시 사용 가능한 Kafka 클라이언트 측정을 지원합니다.
Kafka 생산자 및 소비자 근로자로부터 디버그 수준의 텔레메트리를 수집하려면 OpenTelemetry 클라이언트 에이전트를 사용하세요.
당신의 Kafka를 편집하세요
init 컨테이너를 사용하여 런타임에 OpenTelemetry 저항 에이전트를 다운로드합니다.
apiVersion: apps/v1kind: Deploymentmetadata: name: kafka-producer-appspec: template: spec: initContainers: - name: download-java-agent image: busybox:latest command: - sh - -c - | wget -O /otel-auto-instrumentation/opentelemetry-javaagent.jar \ https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar volumeMounts: - name: otel-auto-instrumentation mountPath: /otel-auto-instrumentation
containers: - name: app image: your-kafka-app:latest env: - name: JAVA_TOOL_OPTIONS value: >- -javaagent:/otel-auto-instrumentation/opentelemetry-javaagent.jar -Dotel.service.name=order-process-service -Dotel.resource.attributes=kafka.cluster.name=my-cluster -Dotel.exporter.otlp.endpoint=http://localhost:4317 -Dotel.exporter.otlp.protocol=grpc -Dotel.metrics.exporter=otlp -Dotel.traces.exporter=otlp -Dotel.logs.exporter=otlp -Dotel.instrumentation.kafka.experimental-span-attributes=true -Dotel.instrumentation.messaging.experimental.receive-telemetry.enabled=true -Dotel.instrumentation.kafka.producer-propagation.enabled=true -Dotel.instrumentation.kafka.enabled=true volumeMounts: - name: otel-auto-instrumentation mountPath: /otel-auto-instrumentation
volumes: - name: otel-auto-instrumentation emptyDir: {}설정 참고 사항:
order-process-service생산자 또는 소비자 애플리케이션에 대한 고유한 이름으로 바꾸십시오.my-cluster수집기 설정에 사용된 것과 동일한 클러스터 이름으로 바꾸세요.- 엔드포인트
http://localhost:4317는 수집기가 동일한 파드에서 사이드카로 실행 중이거나 localhost를 통해 액세스할 수 있다고 가정합니다.
팁
위의 설정은 텔레메트리를 OpenTelemetry Collector 로 보냅니다. 망원경을 수집기로 보내야 하는 경우 3단계 에 설명된 대로 다음 설정을 사용하여 구현하고 배포합니다.
잔류 에이전트는 코드 변경이 전혀 없는 기본 Kafka 측정, 캡처 기능을 제공합니다.
- 요청 지연시간
- 처리량 지표
- 오류율
- 분산 추적
고급 설정에 대해서는 Kafka 측정, 로그 문서를 참조하세요.
데이터 찾기
몇 분 후, Kafka 창이 뉴렐릭에 나타날 것입니다. 뉴렐릭 UI 의 다양한 보기에서 Kafka 범위를 탐색하는 방법에 대한 자세한 지침은 "데이터 찾기"를 참조하세요.
NRQL을 사용하여 데이터를 쿼리할 수도 있습니다.
FROM Metric SELECT * WHERE kafka.cluster.name = 'my-kafka-cluster'문제점 해결
다음 단계
- Kafka 메트릭 살펴보기 - 전체 메트릭 참조 자료를 확인하세요
- 맞춤형 대시보드 만들기 - Kafka 데이터에 대한 시각화 구축
- 알림 설정 - 소비자 지연 및 복제되지 않은 파티션과 같은 중요한 지표를 모니터링합니다.