OpenTelemetry CollectorをDaemonSetとしてデプロイすることで、Kubernetes内のRedisインスタンスをモニターします。コレクターはk8s_observerとreceiver_creatorを使用して、ラベルに基づいてRedisポッドを自動検出します — 既存のRedisデプロイメントに変更を加える必要はありません。
重要
複合パターン(server.address:server.port)はKubernetesではサポートされていません。ポッドのIPは一時的なものであり、再起動のたびに変更されるため、重複するエンティティが作成されます。安定した識別子(例:cluster-name.namespace:port)を持つredis.instance.idパターンを使用してください。
あなたが始める前に
コレクターを設定する前に、以下のものが必要です:
- あなたのNew Relic
kubectl管理者権限でのKubernetesクラスタへのアクセス- Kubernetesクラスタで実行されているRedis — バージョン6.0以降を推奨(4.0以降は縮小されたメトリクスセットで動作します)
- NRDOTおよびOpenTelemetry Collector Contribパスの場合、Redisポッドには検出可能なラベル(たとえば、
app: redis)が付与されている必要があります。 - New RelicのOTLPエンドポイントへのアウトバウンドHTTPS(ポート443)
インストレーションオプションでコレクターのディストリビューションを選択します:NRDOTコレクター、OpenTelemetry Collector Contrib、またはPrometheusレシーバー。NRDOTおよびContribパスは、k8s_observerを使用してRedisポッドを自動検出します;Prometheusレシーバーパスは、Redisと一緒にデプロイするredis_exporterをスクレイピングします。
インストールオプション
ネームスペースと認証情報を作成します
newrelicネームスペースを作成し、ライセンスキーとOTLPエンドポイントをKubernetes Secretに保存します。コレクターは実行時にこれを読み取るため、認証情報が設定ファイルに保存されることはありません:
$kubectl create namespace newrelic$
$# Set OTEL_EXPORTER_OTLP_ENDPOINT for your region.$# See https://docs.newrelic.com/docs/opentelemetry/best-practices/opentelemetry-otlp$kubectl create secret generic newrelic-credentials \> --from-literal=NEW_RELIC_LICENSE_KEY=YOUR_LICENSE_KEY \> --from-literal=OTEL_EXPORTER_OTLP_ENDPOINT=YOUR_OTLP_ENDPOINT \> -n newrelicRBACの設定
k8s_observerには、ポッドを監視する権限が必要です。rbac.yamlを作成します:
apiVersion: v1kind: ServiceAccountmetadata: name: otel-collector-redis namespace: newrelic---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: name: otel-collector-redisrules: - apiGroups: [""] resources: ["pods", "namespaces", "nodes"] verbs: ["get", "list", "watch"] - apiGroups: ["apps"] resources: ["replicasets"] verbs: ["get", "list", "watch"]---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata: name: otel-collector-redissubjects: - kind: ServiceAccount name: otel-collector-redis namespace: newrelicroleRef: kind: ClusterRole name: otel-collector-redis apiGroup: rbac.authorization.k8s.io$kubectl apply -f rbac.yamlコレクターを構成する
このConfigMapは、Redisポッドを検出し、そのメトリクスを収集して、New Relicに送信する方法をコレクターに指示します。3つの主なジョブを処理します:
{…} と Redis ポッドを自動的に検出します。
receiver_creatorデータを形成する — カーディナリティを削減し、カウンターをデルタに変換し、エンティティIDを設定する
処理されたメトリクスをOTLP経由でNew Relicにエクスポートする
otel-collector-config.yamlを作成します:apiVersion: v1kind: ConfigMapmetadata:name: otel-collector-redis-confignamespace: newrelicdata:config.yaml: |extensions:health_check:endpoint: "0.0.0.0:13133"k8s_observer:auth_type: serviceAccountobserve_pods: trueobserve_nodes: falsereceivers:receiver_creator/redis:watch_observers: [k8s_observer]receivers:redis:rule: type == "pod" && labels["app"] == "redis" # Update with your Redis pod labelsconfig:endpoint: "`endpoint`:6379"collection_interval: 10smetrics:redis.maxmemory:enabled: trueredis.role:enabled: falseredis.cmd.calls:enabled: trueredis.cmd.usec:enabled: trueredis.clients.max_input_buffer:enabled: falseredis.clients.max_output_buffer:enabled: falseredis.replication.backlog_first_byte_offset:enabled: falseresource_attributes:server.address:enabled: falseserver.port:enabled: falseprocessors:memory_limiter:check_interval: 5slimit_mib: 256spike_limit_mib: 64resource/k8s_cluster:attributes:- key: k8s.cluster.namevalue: "my-cluster" # Update with your cluster nameaction: upsert- key: redis.instance.idvalue: "my-cluster.default:6379" # Update with cluster.namespace:portaction: upsertattributes/entity_tags:actions:- key: instrumentation.providervalue: opentelemetryaction: upsertcumulativetodelta:include:match_type: regexpmetrics:- redis\.commands\.processed- redis\.connections\.received- redis\.connections\.rejected- redis\.keys\.evicted- redis\.keys\.expired- redis\.keyspace\.hits- redis\.keyspace\.misses- redis\.net\.input- redis\.net\.output- redis\.cpu\.time- redis\.cmd\.calls- redis\.cmd\.usec- redis\.uptimefilter/cardinality:metrics:datapoint:- 'metric.name == "redis.cpu.time" and attributes["state"] != "sys" and attributes["state"] != "user"'- 'metric.name == "redis.cmd.calls" and attributes["cmd"] != "get" and attributes["cmd"] != "set" and attributes["cmd"] != "del" and attributes["cmd"] != "hget" and attributes["cmd"] != "hset" and attributes["cmd"] != "hgetall" and attributes["cmd"] != "lpush" and attributes["cmd"] != "rpop" and attributes["cmd"] != "zadd" and attributes["cmd"] != "expire"'- 'metric.name == "redis.cmd.usec" and attributes["cmd"] != "get" and attributes["cmd"] != "set" and attributes["cmd"] != "del" and attributes["cmd"] != "hget" and attributes["cmd"] != "hset" and attributes["cmd"] != "hgetall" and attributes["cmd"] != "lpush" and attributes["cmd"] != "rpop" and attributes["cmd"] != "zadd" and attributes["cmd"] != "expire"'transform/metadata_nullify:metric_statements:- context: metricstatements:- set(description, "")- set(unit, "")batch:send_batch_size: 2048send_batch_max_size: 4096timeout: 10sexporters:otlp_http:endpoint: ${env:OTEL_EXPORTER_OTLP_ENDPOINT}headers:api-key: ${env:NEW_RELIC_LICENSE_KEY}compression: gzipservice:extensions: [health_check, k8s_observer]pipelines:metrics/redis:receivers: [receiver_creator/redis]processors: [memory_limiter, resource/k8s_cluster, attributes/entity_tags, cumulativetodelta, filter/cardinality, transform/metadata_nullify, batch]exporters: [otlp_http]bash$kubectl apply -f otel-collector-config.yamlこの設定で行うこと
パイプラインの各コンポーネントには特定の役割があります:
コンポーネント 説明 health_checkコレクターが実行されていることを確認できるように、 0.0.0.0:13133でヘルスエンドポイントを公開します。k8s_observerコレクターがRedisインスタンスを動的に検出できるように、Kubernetes APIでポッドを監視します。 receiver_creator/redisルール( labels["app"] == "redis")に一致する各ポッドに対してredisレシーバーを開始し、10秒ごとにRedisのINFOコマンドからそのメトリクスを読み取ります。memory_limiterポッドを保護するためにコレクターのメモリ使用量(256 MiBのソフトリミット、64 MiBのスパイク)を制限します。 resource/k8s_clusterRedisエンティティの安定したIDである k8s.cluster.nameとredis.instance.idを設定します(複合server.address:server.portパターンはKubernetesでは使用されません)。attributes/entity_tagsクエリをOpenTelemetryパスにスコープできるように、すべてのメトリクスに instrumentation.provider: opentelemetryをスタンプします。cumulativetodeltaNew Relicがレートを正しくチャート化できるように、Redisの累積カウンター — コマンド、キースペースヒット、エビクションなど — をデルタ値に変換します。 filter/cardinality取り込みコストを制御するために、高いカーディナリティのデータポイント( userとsys以外のCPUステータス、および一般的ではないコマンドのコマンドごとのメトリクス)をドロップします。transform/metadata_nullifyペイロードのサイズを縮小するために、メトリクスの説明と単位をクリアします。 batchネットワークのオーバーヘッドを削減するために、エクスポートする前にデータポイントをグループ化し(バッチあたり2,048、最大4,096)、少なくとも10秒ごとにフラッシュします。 otlp_http処理されたメトリクスを、ライセンスキーで認証し、gzip圧縮を使用してOTLP経由でNew Relicにエクスポートします。
オプション:Redisログの収集
メトリクスに加えて、コレクターはRedisのログをNew Relicに転送できるため、ログイベント — 再起動、永続化イベント、またはエラー — を同じエンティティ上のメトリクスのスパイクと関連付けることができます。これらを収集するには、ConfigMapにfilelogレシーバーを追加し、DaemonSetに/var/log/podsをマウントします。
ConfigMapのreceiversセクションに追加します:
file_log/redis: include: - /var/log/pods/<namespace>_*redis*/*/*.log # Update <namespace> with your Redis namespace (e.g., default, production) start_at: end include_file_path: true operators: - type: regex_parser regex: '^\S+ stdout F \d+:[XCSM] \d+ \w+ \d+ \d+:\d+:\d+\.\d+ (?P<level>.) ' on_error: send resource: db.system: redisresource/redis_logsプロセッサを追加します:
resource/redis_logs: attributes: - key: redis.instance.id value: "my-cluster.default:6379" # Update with cluster.namespace:port action: upsert - key: instrumentation.provider value: "opentelemetry" action: upsertserviceセクションにログパイプラインを追加します:
service: pipelines: metrics/redis: # ... existing metrics pipeline ... logs/redis: receivers: [file_log/redis] processors: [memory_limiter, resource/redis_logs, batch] exporters: [otlp_http]以下のDaemonSetでvarlogpodsボリュームマウントのコメントを解除します。
オプション:Redis Clusterの監視を有効にする
現在、Redis Clusterの監視にはPrometheusレシーバーのアプローチ(redis_exporterを使用)が必要です。NRDOT CollectorのネイティブRedisレシーバーは、クラスタメトリクスに必要なCLUSTER INFOコマンドをまだサポートしていません。クラスタ監視のセットアップには、Prometheusレシーバータブを使用します。
DaemonSetをデプロイします
otel-collector-daemonset.yamlを作成します:
apiVersion: apps/v1kind: DaemonSetmetadata: name: otel-collector-redis namespace: newrelicspec: selector: matchLabels: app: otel-collector-redis template: metadata: labels: app: otel-collector-redis spec: serviceAccountName: otel-collector-redis containers: - name: otel-collector image: newrelic/nrdot-collector:latest args: ["--config=/etc/otel/config.yaml"] env: - name: NEW_RELIC_LICENSE_KEY valueFrom: secretKeyRef: name: newrelic-credentials key: NEW_RELIC_LICENSE_KEY - name: OTEL_EXPORTER_OTLP_ENDPOINT valueFrom: secretKeyRef: name: newrelic-credentials key: OTEL_EXPORTER_OTLP_ENDPOINT - name: K8S_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName resources: limits: cpu: 500m memory: 512Mi requests: cpu: 100m memory: 128Mi volumeMounts: - name: config mountPath: /etc/otel - name: machine-id mountPath: /etc/machine-id readOnly: true # Uncomment if collecting logs: # - name: varlogpods # mountPath: /var/log/pods # readOnly: true livenessProbe: httpGet: path: / port: 13133 initialDelaySeconds: 15 readinessProbe: httpGet: path: / port: 13133 initialDelaySeconds: 5 volumes: - name: config configMap: name: otel-collector-redis-config - name: machine-id hostPath: path: /etc/machine-id # Uncomment if collecting logs: # - name: varlogpods # hostPath: # path: /var/log/pods$kubectl apply -f otel-collector-daemonset.yaml確認
コレクターのポッドが実行されていることを確認します:
$kubectl get pods -n newrelic -l app=otel-collector-redisポッドは、すべてのコンテナが準備完了の状態でRunningを表示するはずです。CrashLoopBackOffまたはErrorの場合は、kubectl logs -n newrelic -l app=otel-collector-redisでそのログを確認してください — 最も一般的な原因は、ConfigMap YAMLエラー、RBAC ClusterRoleの欠落、またはディスカバリルールがRedisポッドのラベルと一致していないことです。
次に、メトリクスがNew Relicに到達していることを確認します。ポッドが起動してから約1分待ち、クエリビルダーでこのクエリを実行します:
SELECT count(*) FROM MetricWHERE metricName LIKE 'redis.%'AND instrumentation.provider = 'opentelemetry'AND k8s.cluster.name IS NOT NULLSINCE 5 minutes agoゼロ以外のカウントにより、Redisメトリクスが流れていることが確認できます。0が返される場合は、Redisのトラブルシューティング(OpenTelemetry)を参照してください。
ネームスペースと認証情報を作成します
newrelicネームスペースを作成し、ライセンスキーとOTLPエンドポイントをKubernetes Secretに保存します。コレクターは実行時にこれを読み取るため、認証情報が設定ファイルに保存されることはありません:
$kubectl create namespace newrelic$
$# Set OTEL_EXPORTER_OTLP_ENDPOINT for your region.$# See https://docs.newrelic.com/docs/opentelemetry/best-practices/opentelemetry-otlp$kubectl create secret generic newrelic-credentials \> --from-literal=NEW_RELIC_LICENSE_KEY=YOUR_LICENSE_KEY \> --from-literal=OTEL_EXPORTER_OTLP_ENDPOINT=YOUR_OTLP_ENDPOINT \> -n newrelicRBACの設定
k8s_observerには、ポッドを監視する権限が必要です。rbac.yamlを作成します:
apiVersion: v1kind: ServiceAccountmetadata: name: otel-collector-redis namespace: newrelic---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: name: otel-collector-redisrules: - apiGroups: [""] resources: ["pods", "namespaces", "nodes"] verbs: ["get", "list", "watch"] - apiGroups: ["apps"] resources: ["replicasets"] verbs: ["get", "list", "watch"]---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata: name: otel-collector-redissubjects: - kind: ServiceAccount name: otel-collector-redis namespace: newrelicroleRef: kind: ClusterRole name: otel-collector-redis apiGroup: rbac.authorization.k8s.io$kubectl apply -f rbac.yamlコレクターを構成する
このConfigMapは、Redisポッドを検出し、そのメトリクスを収集して、New Relicに送信する方法をコレクターに指示します。3つの主なジョブを処理します:
{…} と Redis ポッドを自動的に検出します。
receiver_creatorデータを形成する — カーディナリティを削減し、カウンターをデルタに変換し、エンティティIDを設定する
処理されたメトリクスをOTLP経由でNew Relicにエクスポートする
otel-collector-config.yamlを作成します:apiVersion: v1kind: ConfigMapmetadata:name: otel-collector-redis-confignamespace: newrelicdata:config.yaml: |extensions:health_check:endpoint: "0.0.0.0:13133"k8s_observer:auth_type: serviceAccountobserve_pods: trueobserve_nodes: falsereceivers:receiver_creator/redis:watch_observers: [k8s_observer]receivers:redis:rule: type == "pod" && labels["app"] == "redis" # Update with your Redis pod labelsconfig:endpoint: "`endpoint`:6379"collection_interval: 10smetrics:redis.maxmemory:enabled: trueredis.role:enabled: falseredis.cmd.calls:enabled: trueredis.cmd.usec:enabled: trueredis.clients.max_input_buffer:enabled: falseredis.clients.max_output_buffer:enabled: falseredis.replication.backlog_first_byte_offset:enabled: falseresource_attributes:server.address:enabled: falseserver.port:enabled: falseprocessors:memory_limiter:check_interval: 5slimit_mib: 256spike_limit_mib: 64resource/k8s_cluster:attributes:- key: k8s.cluster.namevalue: "my-cluster" # Update with your cluster nameaction: upsert- key: redis.instance.idvalue: "my-cluster.default:6379" # Update with cluster.namespace:portaction: upsertattributes/entity_tags:actions:- key: instrumentation.providervalue: opentelemetryaction: upsertcumulativetodelta:include:match_type: regexpmetrics:- redis\.commands\.processed- redis\.connections\.received- redis\.connections\.rejected- redis\.keys\.evicted- redis\.keys\.expired- redis\.keyspace\.hits- redis\.keyspace\.misses- redis\.net\.input- redis\.net\.output- redis\.cpu\.time- redis\.cmd\.calls- redis\.cmd\.usec- redis\.uptimefilter/cardinality:metrics:datapoint:- 'metric.name == "redis.cpu.time" and attributes["state"] != "sys" and attributes["state"] != "user"'- 'metric.name == "redis.cmd.calls" and attributes["cmd"] != "get" and attributes["cmd"] != "set" and attributes["cmd"] != "del" and attributes["cmd"] != "hget" and attributes["cmd"] != "hset" and attributes["cmd"] != "hgetall" and attributes["cmd"] != "lpush" and attributes["cmd"] != "rpop" and attributes["cmd"] != "zadd" and attributes["cmd"] != "expire"'- 'metric.name == "redis.cmd.usec" and attributes["cmd"] != "get" and attributes["cmd"] != "set" and attributes["cmd"] != "del" and attributes["cmd"] != "hget" and attributes["cmd"] != "hset" and attributes["cmd"] != "hgetall" and attributes["cmd"] != "lpush" and attributes["cmd"] != "rpop" and attributes["cmd"] != "zadd" and attributes["cmd"] != "expire"'transform/metadata_nullify:metric_statements:- context: metricstatements:- set(description, "")- set(unit, "")batch:send_batch_size: 2048send_batch_max_size: 4096timeout: 10sexporters:otlp_http:endpoint: ${env:OTEL_EXPORTER_OTLP_ENDPOINT}headers:api-key: ${env:NEW_RELIC_LICENSE_KEY}compression: gzipservice:extensions: [health_check, k8s_observer]pipelines:metrics/redis:receivers: [receiver_creator/redis]processors: [memory_limiter, resource/k8s_cluster, attributes/entity_tags, cumulativetodelta, filter/cardinality, transform/metadata_nullify, batch]exporters: [otlp_http]bash$kubectl apply -f otel-collector-config.yamlこの設定で行うこと
パイプラインの各コンポーネントには特定の役割があります:
コンポーネント 説明 health_checkコレクターが実行されていることを確認できるように、 0.0.0.0:13133でヘルスエンドポイントを公開します。k8s_observerコレクターがRedisインスタンスを動的に検出できるように、Kubernetes APIでポッドを監視します。 receiver_creator/redisルール( labels["app"] == "redis")に一致する各ポッドに対してredisレシーバーを開始し、10秒ごとにRedisのINFOコマンドからそのメトリクスを読み取ります。memory_limiterポッドを保護するためにコレクターのメモリ使用量(256 MiBのソフトリミット、64 MiBのスパイク)を制限します。 resource/k8s_clusterRedisエンティティの安定したIDである k8s.cluster.nameとredis.instance.idを設定します(複合server.address:server.portパターンはKubernetesでは使用されません)。attributes/entity_tagsクエリをOpenTelemetryパスにスコープできるように、すべてのメトリクスに instrumentation.provider: opentelemetryをスタンプします。cumulativetodeltaNew Relicがレートを正しくチャート化できるように、Redisの累積カウンター — コマンド、キースペースヒット、エビクションなど — をデルタ値に変換します。 filter/cardinality取り込みコストを制御するために、高いカーディナリティのデータポイント( userとsys以外のCPUステータス、および一般的ではないコマンドのコマンドごとのメトリクス)をドロップします。transform/metadata_nullifyペイロードのサイズを縮小するために、メトリクスの説明と単位をクリアします。 batchネットワークのオーバーヘッドを削減するために、エクスポートする前にデータポイントをグループ化し(バッチあたり2,048、最大4,096)、少なくとも10秒ごとにフラッシュします。 otlp_http処理されたメトリクスを、ライセンスキーで認証し、gzip圧縮を使用してOTLP経由でNew Relicにエクスポートします。
オプション:Redisログの収集
メトリクスに加えて、コレクターはRedisのログをNew Relicに転送できるため、ログイベント — 再起動、永続化イベント、またはエラー — を同じエンティティ上のメトリクスのスパイクと関連付けることができます。これらを収集するには、ConfigMapにfilelogレシーバーを追加し、DaemonSetに/var/log/podsをマウントします。
ConfigMapのreceiversセクションに追加します:
file_log/redis: include: - /var/log/pods/<namespace>_*redis*/*/*.log # Update <namespace> with your Redis namespace (e.g., default, production) start_at: end include_file_path: true operators: - type: regex_parser regex: '^\S+ stdout F \d+:[XCSM] \d+ \w+ \d+ \d+:\d+:\d+\.\d+ (?P<level>.) ' on_error: send resource: db.system: redisresource/redis_logsプロセッサを追加します:
resource/redis_logs: attributes: - key: redis.instance.id value: "my-cluster.default:6379" # Update with cluster.namespace:port action: upsert - key: instrumentation.provider value: "opentelemetry" action: upsertserviceセクションにログパイプラインを追加します:
service: pipelines: metrics/redis: # ... existing metrics pipeline ... logs/redis: receivers: [file_log/redis] processors: [memory_limiter, resource/redis_logs, batch] exporters: [otlp_http]オプション:Redis Clusterの監視を有効にする
Redis Clusterの監視には、現在Prometheusレシーバーのアプローチ(redis_exporterを使用)が必要です。OTel Collector ContribのネイティブRedisレシーバーは、クラスタメトリクスに必要なCLUSTER INFOコマンドをまだサポートしていません。クラスタ監視のセットアップには、Prometheusレシーバータブを使用します。
DaemonSetをデプロイします
otel-collector-daemonset.yamlを作成します:
apiVersion: apps/v1kind: DaemonSetmetadata: name: otel-collector-redis namespace: newrelicspec: selector: matchLabels: app: otel-collector-redis template: metadata: labels: app: otel-collector-redis spec: serviceAccountName: otel-collector-redis containers: - name: otel-collector image: otel/opentelemetry-collector-contrib:latest args: ["--config=/etc/otel/config.yaml"] env: - name: NEW_RELIC_LICENSE_KEY valueFrom: secretKeyRef: name: newrelic-credentials key: NEW_RELIC_LICENSE_KEY - name: OTEL_EXPORTER_OTLP_ENDPOINT valueFrom: secretKeyRef: name: newrelic-credentials key: OTEL_EXPORTER_OTLP_ENDPOINT - name: K8S_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName resources: limits: cpu: 500m memory: 512Mi requests: cpu: 100m memory: 128Mi volumeMounts: - name: config mountPath: /etc/otel - name: machine-id mountPath: /etc/machine-id readOnly: true # Uncomment if collecting logs: # - name: varlogpods # mountPath: /var/log/pods # readOnly: true livenessProbe: httpGet: path: / port: 13133 initialDelaySeconds: 15 readinessProbe: httpGet: path: / port: 13133 initialDelaySeconds: 5 volumes: - name: config configMap: name: otel-collector-redis-config - name: machine-id hostPath: path: /etc/machine-id # Uncomment if collecting logs: # - name: varlogpods # hostPath: # path: /var/log/pods$kubectl apply -f otel-collector-daemonset.yaml確認
コレクターのポッドが実行されていることを確認します:
$kubectl get pods -n newrelic -l app=otel-collector-redisポッドは、すべてのコンテナが準備完了の状態でRunningを表示するはずです。CrashLoopBackOffまたはErrorの場合は、kubectl logs -n newrelic -l app=otel-collector-redisでそのログを確認してください — 最も一般的な原因は、ConfigMap YAMLエラー、RBAC ClusterRoleの欠落、またはディスカバリルールがRedisポッドのラベルと一致していないことです。
次に、メトリクスがNew Relicに到達していることを確認します。ポッドが起動してから約1分待ち、クエリビルダーでこのクエリを実行します:
SELECT count(*) FROM MetricWHERE metricName LIKE 'redis.%'AND instrumentation.provider = 'opentelemetry'AND k8s.cluster.name IS NOT NULLSINCE 5 minutes agoゼロ以外のカウントにより、Redisメトリクスが流れていることが確認できます。0が返される場合は、Redisのトラブルシューティング(OpenTelemetry)を参照してください。
ネームスペースと認証情報を作成します
newrelicネームスペースを作成し、ライセンスキーとOTLPエンドポイントをKubernetes Secretに保存します。コレクターは実行時にこれを読み取るため、認証情報が設定ファイルに保存されることはありません:
$kubectl create namespace newrelic$
$# Set OTEL_EXPORTER_OTLP_ENDPOINT for your region.$# See https://docs.newrelic.com/docs/opentelemetry/best-practices/opentelemetry-otlp$kubectl create secret generic newrelic-credentials \> --from-literal=NEW_RELIC_LICENSE_KEY=YOUR_LICENSE_KEY \> --from-literal=OTEL_EXPORTER_OTLP_ENDPOINT=YOUR_OTLP_ENDPOINT \> -n newrelicredis_exporterをデプロイする
redis_exporterをRedisポッドのサイドカーとして、または個別のデプロイメントとしてデプロイします。この例では、コレクターがスクレイプするためのServiceを備えたスタンドアロンのデプロイメントとしてデプロイします。
redis-exporter.yamlを作成します:
apiVersion: apps/v1kind: Deploymentmetadata: name: redis-exporter namespace: default # Update with your Redis namespacespec: replicas: 1 selector: matchLabels: app: redis-exporter template: metadata: labels: app: redis-exporter spec: containers: - name: redis-exporter image: oliver006/redis_exporter:latest env: - name: REDIS_ADDR value: "redis://redis:6379" # Update with your Redis service name:port # Uncomment if using Redis authentication: # - name: REDIS_PASSWORD # valueFrom: # secretKeyRef: # name: redis-credentials # key: password ports: - containerPort: 9121 name: metrics livenessProbe: httpGet: path: /health port: 9121 initialDelaySeconds: 5 readinessProbe: httpGet: path: /health port: 9121 initialDelaySeconds: 5---apiVersion: v1kind: Servicemetadata: name: redis-exporter namespace: default # Update with your Redis namespacespec: selector: app: redis-exporter ports: - port: 9121 targetPort: 9121 name: metrics$kubectl apply -f redis-exporter.yamlエクスポーターが実行中であることを確認します:
$kubectl port-forward svc/redis-exporter 9121:9121 &$curl -s http://localhost:9121/metrics | grep redis_upコレクターを構成する
このConfigMapはredis_exporterからメトリクスをスクレイプし、New Relicに送信します。これは以下の主なジョブを処理します:
prometheusレシーバーを介してredis_exporterサービスをスクレイプしますPrometheusのメトリクスをNew RelicのRedisメトリクス名に名前変更します
データを形成する — カーディナリティを削減し、カウンターをデルタに変換し、エンティティIDを設定する
処理されたメトリクスをOTLP経由でNew Relicにエクスポートする
otel-collector-config.yamlを作成します:apiVersion: v1kind: ConfigMapmetadata:name: otel-collector-redis-confignamespace: newrelicdata:config.yaml: |extensions:health_check:endpoint: "0.0.0.0:13133"receivers:prometheus:config:scrape_configs:- job_name: 'redis'scrape_interval: 10sstatic_configs:- targets: ['redis-exporter.default.svc.cluster.local:9121'] # Update with your exporter service FQDNmetric_relabel_configs:- source_labels: [__name__]regex: '(go_|process_|promhttp_|redis_exporter_).*'action: dropprocessors:memory_limiter:check_interval: 5slimit_mib: 256spike_limit_mib: 64resource/redis_identity:attributes:- key: k8s.cluster.namevalue: "my-cluster" # Update with your cluster nameaction: upsert- key: redis.instance.idvalue: "my-cluster.default:6379" # Update with cluster.namespace:portaction: upsertattributes/entity_tags:actions:- key: instrumentation.providervalue: opentelemetryaction: upsertmetricstransform:transforms:- include: redis_uptime_in_secondsaction: updatenew_name: redis.uptime- include: redis_connected_clientsaction: updatenew_name: redis.clients.connected- include: redis_blocked_clientsaction: updatenew_name: redis.clients.blocked- include: redis_memory_used_bytesaction: updatenew_name: redis.memory.used- include: redis_memory_max_bytesaction: updatenew_name: redis.maxmemory- include: redis_mem_fragmentation_ratioaction: updatenew_name: redis.memory.fragmentation_ratio- include: redis_memory_used_rss_bytesaction: updatenew_name: redis.memory.rss- include: redis_memory_used_peak_bytesaction: updatenew_name: redis.memory.peak- include: redis_memory_used_lua_bytesaction: updatenew_name: redis.memory.lua- include: redis_connections_received_totalaction: updatenew_name: redis.connections.received- include: redis_rejected_connections_totalaction: updatenew_name: redis.connections.rejected- include: redis_commands_processed_totalaction: updatenew_name: redis.commands.processed- include: redis_keyspace_hits_totalaction: updatenew_name: redis.keyspace.hits- include: redis_keyspace_misses_totalaction: updatenew_name: redis.keyspace.misses- include: redis_evicted_keys_totalaction: updatenew_name: redis.keys.evicted- include: redis_expired_keys_totalaction: updatenew_name: redis.keys.expired- include: redis_net_input_bytes_totalaction: updatenew_name: redis.net.input- include: redis_net_output_bytes_totalaction: updatenew_name: redis.net.output- include: redis_connected_slavesaction: updatenew_name: redis.slaves.connected- include: redis_db_keysaction: updatenew_name: redis.db.keys- include: redis_db_keys_expiringaction: updatenew_name: redis.db.expires- include: redis_rdb_changes_since_last_saveaction: updatenew_name: redis.rdb.changes_since_last_save- include: redis_db_avg_ttl_secondsaction: updatenew_name: redis.db.avg_ttl- include: redis_latest_fork_secondsaction: updatenew_name: redis.latest_fork- include: redis_master_repl_offsetaction: updatenew_name: redis.replication.offset- include: redis_repl_backlog_first_byte_offsetaction: updatenew_name: redis.replication.backlog_first_byte_offset- include: redis_commands_totalaction: updatenew_name: redis.cmd.calls- include: redis_commands_duration_seconds_totalaction: updatenew_name: redis.cmd.usec- include: redis_cpu_sys_seconds_totalaction: updatenew_name: redis.cpu.timeoperations:- action: add_labelnew_label: statenew_value: sys- include: redis_cpu_user_seconds_totalaction: updatenew_name: redis.cpu.timeoperations:- action: add_labelnew_label: statenew_value: usercumulativetodelta:include:match_type: regexpmetrics:- redis\.commands\.processed- redis\.connections\.received- redis\.connections\.rejected- redis\.keys\.evicted- redis\.keys\.expired- redis\.keyspace\.hits- redis\.keyspace\.misses- redis\.net\.input- redis\.net\.output- redis\.cpu\.time- redis\.cmd\.calls- redis\.cmd\.usec- redis\.uptimefilter/cardinality:metrics:datapoint:- 'metric.name == "redis.cpu.time" and attributes["state"] != "sys" and attributes["state"] != "user"'- 'metric.name == "redis.cmd.calls" and attributes["cmd"] != "get" and attributes["cmd"] != "set" and attributes["cmd"] != "del" and attributes["cmd"] != "hget" and attributes["cmd"] != "hset" and attributes["cmd"] != "hgetall" and attributes["cmd"] != "lpush" and attributes["cmd"] != "rpop" and attributes["cmd"] != "zadd" and attributes["cmd"] != "expire"'- 'metric.name == "redis.cmd.usec" and attributes["cmd"] != "get" and attributes["cmd"] != "set" and attributes["cmd"] != "del" and attributes["cmd"] != "hget" and attributes["cmd"] != "hset" and attributes["cmd"] != "hgetall" and attributes["cmd"] != "lpush" and attributes["cmd"] != "rpop" and attributes["cmd"] != "zadd" and attributes["cmd"] != "expire"'transform/metadata_nullify:metric_statements:- context: metricstatements:- set(description, "")- set(unit, "")batch:send_batch_size: 2048send_batch_max_size: 4096timeout: 10sexporters:otlp_http:endpoint: ${env:OTEL_EXPORTER_OTLP_ENDPOINT}headers:api-key: ${env:NEW_RELIC_LICENSE_KEY}compression: gzipservice:extensions: [health_check]pipelines:metrics/redis:receivers: [prometheus]processors: [memory_limiter, resource/redis_identity, attributes/entity_tags, metricstransform, cumulativetodelta, filter/cardinality, transform/metadata_nullify, batch]exporters: [otlp_http]bash$kubectl apply -f otel-collector-config.yamlこの設定で行うこと
パイプラインの各コンポーネントには特定の役割があります:
コンポーネント 説明 health_checkコレクターが実行されていることを確認できるように、 0.0.0.0:13133でヘルスエンドポイントを公開します。prometheusレシーバー10秒ごとに redis_exporterサービス(デフォルトはredis-exporter.default.svc.cluster.local:9121)をスクレイプし、エクスポーター自身のgo_*、process_*、promhttp_*、およびredis_exporter_*メトリクスをドロップします。memory_limiterポッドを保護するためにコレクターのメモリ使用量(256 MiBのソフトリミット、64 MiBのスパイク)を制限します。 resource/redis_identityRedisエンティティの安定したIDである k8s.cluster.nameとredis.instance.idを設定します。Prometheusレシーバーはserver.addressまたはserver.portを提供しないため、ここでは必須です。attributes/entity_tagsクエリをOpenTelemetryパスにスコープできるように、すべてのメトリクスに instrumentation.provider: opentelemetryをスタンプします。metricstransformエクスポーターのPrometheusメトリクス(たとえば redis_uptime_in_seconds)をNew RelicのRedis名(redis.uptime)に名前変更し、CPUメトリクスにstateラベルを追加します。cumulativetodeltaNew Relicがレートを正確にグラフ化できるように、累積カウンター — コマンド、キースペースヒット、エビクションなど — をデルタ値に変換します。 filter/cardinality取り込みコストを制御するために、高いカーディナリティのデータポイント( userとsys以外のCPUステータス、および一般的ではないコマンドのコマンドごとのメトリクス)をドロップします。transform/metadata_nullifyペイロードのサイズを縮小するために、メトリクスの説明と単位をクリアします。 batchネットワークのオーバーヘッドを削減するために、エクスポートする前にデータポイントをグループ化し(バッチあたり2,048、最大4,096)、少なくとも10秒ごとにフラッシュします。 otlp_http処理されたメトリクスを、ライセンスキーで認証し、gzip圧縮を使用してOTLP経由でNew Relicにエクスポートします。
オプション:Redis Clusterの監視を有効にする
RedisがClusterモードで実行されている場合、すべてのノードからクラスタのヘルスメトリクスを自動的に収集するために、--is-clusterフラグを付けてredis_exporterを開始します:
$redis_exporter --redis.addr=redis://localhost:7000 --is-cluster上記のPrometheusレシーバーの設定では、すでにクラスタメトリクスの名前が変更されています(例:redis_cluster_state→redis.cluster.state)。New Relicで別のクラスタエンティティを作成するには、redis.instance.idを含まない別のパイプラインにredis.cluster.nameリソース属性を追加します:
resource/cluster: attributes: - key: redis.cluster.name value: "my-redis-cluster" # Update with your cluster name action: upsertサービスセクションにクラスタパイプラインを追加します:
metrics/cluster: receivers: [prometheus] processors: [memory_limiter, resource/cluster, attributes/entity_tags, metricstransform, cumulativetodelta, filter/cardinality, transform/metadata_nullify, batch] exporters: [otlp_http]重要
クラスタエンティティは、redis.cluster.nameが存在し、かつredis.instance.idが存在しないことを必要とします。両方が同じメトリクスに設定されている場合、インスタンスエンティティのみが作成されます。インスタンスとクラスタのメトリクスには、別々のパイプラインを使用します。
オプション:Redisログの収集
メトリクスに加えて、コレクターはRedisのログをNew Relicに転送できるため、ログイベント — 再起動、永続化イベント、またはエラー — を同じエンティティ上のメトリクスのスパイクと関連付けることができます。これらを収集するには、ConfigMapにfile_logレシーバーを追加し、デプロイメントに/var/log/podsをマウントします。
ConfigMapのreceiversセクションに追加します:
file_log/redis: include: - /var/log/pods/<namespace>_*redis*/*/*.log # Update <namespace> with your Redis namespace (e.g., default, production) start_at: end include_file_path: true operators: - type: regex_parser regex: '^\S+ stdout F \d+:[XCSM] \d+ \w+ \d+ \d+:\d+:\d+\.\d+ (?P<level>.) ' on_error: send resource: db.system: redisresource/redis_logsプロセッサを追加します:
resource/redis_logs: attributes: - key: redis.instance.id value: "my-cluster.default:6379" # Must match the value in resource/redis_identity action: upsert - key: instrumentation.provider value: "opentelemetry" action: upsertserviceセクションにログパイプラインを追加します:
service: pipelines: metrics/redis: # ... existing metrics pipeline ... logs/redis: receivers: [file_log/redis] processors: [memory_limiter, resource/redis_logs, batch] exporters: [otlp_http]デプロイメントに/var/log/podsボリュームマウントを追加します(以下のデプロイ手順を参照してください)。
コレクターをデプロイする
otel-collector-deployment.yamlを作成します:
apiVersion: apps/v1kind: Deploymentmetadata: name: otel-collector-redis namespace: newrelicspec: replicas: 1 selector: matchLabels: app: otel-collector-redis template: metadata: labels: app: otel-collector-redis spec: containers: - name: otel-collector image: otel/opentelemetry-collector-contrib:latest args: ["--config=/etc/otel/config.yaml"] env: - name: NEW_RELIC_LICENSE_KEY valueFrom: secretKeyRef: name: newrelic-credentials key: NEW_RELIC_LICENSE_KEY - name: OTEL_EXPORTER_OTLP_ENDPOINT valueFrom: secretKeyRef: name: newrelic-credentials key: OTEL_EXPORTER_OTLP_ENDPOINT resources: limits: cpu: 500m memory: 512Mi requests: cpu: 100m memory: 128Mi volumeMounts: - name: config mountPath: /etc/otel # Uncomment if collecting logs: # - name: varlogpods # mountPath: /var/log/pods # readOnly: true livenessProbe: httpGet: path: / port: 13133 initialDelaySeconds: 15 readinessProbe: httpGet: path: / port: 13133 initialDelaySeconds: 5 volumes: - name: config configMap: name: otel-collector-redis-config # Uncomment if collecting logs: # - name: varlogpods # hostPath: # path: /var/log/pods$kubectl apply -f otel-collector-deployment.yamlヒント
代わりにNRDOTコレクターを使用するには、イメージをnewrelic/nrdot-collector:latestに置き換えます。
確認
コレクターのポッドが実行されていることを確認します:
$kubectl get pods -n newrelic -l app=otel-collector-redisポッドは、すべてのコンテナが準備完了の状態でRunningを表示するはずです。CrashLoopBackOffまたはErrorの場合は、kubectl logs -n newrelic -l app=otel-collector-redisを使用してそのログを確認してください — 最も一般的な原因は、ConfigMap YAMLのエラー、または到達不可能なredis_exporterサービスです。
次に、メトリクスがNew Relicに到達していることを確認します。ポッドが起動してから約1分待ち、クエリビルダーでこのクエリを実行します:
SELECT count(*) FROM MetricWHERE metricName LIKE 'redis.%'AND instrumentation.provider = 'opentelemetry'AND k8s.cluster.name IS NOT NULLSINCE 5 minutes agoゼロ以外のカウントにより、Redisメトリクスが流れていることが確認できます。0が返される場合は、Redisのトラブルシューティング(OpenTelemetry)を参照してください。
ヒント
APMとRedisの関連付け: サービスマップでAPMアプリケーションとRedisインスタンスを接続するには、APMメトリクスのリソース属性としてdb.system="redis"とredis.instance.idを含めます。redis.instance.idの値は、コレクターで設定したものと一致する必要があります。これにより、New Relic内でのサービス間の可視性が向上し、トラブルシューティングが迅速化されます。
次のステップ
- ホストのインストレーション: VM/ベアメタル上のRedisをモニターする
- Dockerインストレーション: Docker Composeを使用してデプロイします
- データの表示: ダッシュボードとアラートを探索する
- メトリクスリファレンス: 利用可能なすべてのメトリクス
- トラブルシューティング: 一般的なK8sの問題