Kubernetes でのバックエンドアプリケーションのゼロコードインストルメンテーション

Kubernetes 環境におけるバックエンドアプリケーションと言語ランタイムのゼロコードインストルメンテーションを開始します。

Splunk Distribution of OpenTelemetry Collector は、ゼロコードインストルメンテーションによるオートディスカバリを使用して、Kubernetes 環境で実行されているバックエンドアプリケーションを自動的に検出します。ゼロコードインストルメンテーションで Collector を展開することで、アプリケーションのコードを編集したりファイルを設定したりせずに、アプリケーションをインストルメンテーションし、データを Splunk Observability Cloud に送信できます。

Kubernetes のゼロコードインストルメンテーションは、以下のアプリケーションと言語ランタイムを検出し、設定することができます:

  • Java

  • .NET

  • Node.js

Kubernetesのゼロコードインストルメンテーションの仕組み

Kubernetes のゼロコードインストルメンテーションは、Helm でインストールする Kubernetes DaemonSet として動作します。Helm を使用すると、ゼロコードインストルメンテーションを検索する言語ランタイムを指定できます。インストール後、Helm はクラスターに Kubernetes ポッドのセットを展開します。これには、Splunk Distribution of OpenTelemetry Collector、Kubernetes Operator、およびその他のサポートリソースが含まれます。

Collector と Kubernetes Operator は、アプリケーションへのリクエストをリッスンし、アプリケーションのアクティビティを検出するとテレメトリデータを収集します。その後、Collector はこのデータを Splunk Application Performance Monitoring(APM)に送信します。

はじめに

Kubernetes のゼロコードインストルメンテーションをインストールするには、以下の手順を実行します:

  1. Kubernetes OperatorでHelmチャートをデプロイする

  2. すべての OpenTelemetry リソースが正常にデプロイされていることを検証します。

  3. インストルメンテーションアプリケーションに注釈を設定する

  4. Splunk Observability APM で結果を表示する

要件

バックエンドの Kubernetes アプリケーションにゼロコードインストルメンテーションを使用するには、以下のコンポーネントが必要です:

使用言語のランタイムに固有のコンポーネントがインストールされていることも確認してください。

Java

Java 8 以上とサポートされているライブラリ。詳細については、「Java エージェントの互換性と要件」を参照してください。

.NET
  • .NETバージョン6.0以上、およびサポートされている.NETアプリケーションライブラリ。

  • X86 または AMD64(x86-64)アーキテクチャ。ARM アーキテクチャはサポートされていません。

Node.js

Node.js バージョン 14 以上とサポートされているライブラリ。詳しくは、「Splunk OTel JS の互換性と要件」を参照してください。

Kubernetes OperatorでHelmチャートをデプロイする

Helm チャートをデプロイするには、values.yaml というファイルを作成します。このファイルでは、Helm チャートとともに OpenTelemetry Collector をインストールするときにアクティブ化または非アクティブ化する設定を定義できます。

values.yamlに以下のフィールドと値を入力します:

clusterName: <your_cluster_name>

# Your Splunk Observability Cloud realm and access token
splunkObservability:
  realm: <splunk_realm>
  accessToken: <splunk_access_token>

# Activates the OpenTelemetry Kubernetes Operator
operator:
  enabled: true

# Installs the Custom Resource Definitions (CRDs) required by the operator
# Must be set unless CRDs are pre-installed manually
operatorcrds:
  install: true

ご利用の環境によっては、このファイルに追加の値を入力する必要がある可能性があります。詳細については 、「証明書と OpenTelemetry CRD の追加」と「デプロイメント環境の設定」を参照してください。

OpenTelemetry CRDを追加する

Kubernetes 用の Operator は、OpenTelemetry Custom Resource Definitions(CRDs)をインストールする必要があります。これを行うには、operatorcrds.install=true を values.yaml ファイルに追加します。

次の例のYAMLにはcertmanager.enabled=trueoperatorcrds.install=trueが含まれています:

clusterName: my-cluster

splunkObservability:
  realm: <splunk_realm>
  accessToken: <splunk_access_token>

operator:
  enabled: true
operatorcrds:
  install: true

デプロイメント環境の設定

トレーステレメトリデータを適切に取り込むには、エクスポートされたトレースに属性 deployment.environment が含まれている必要があります。次の表は、この属性を設定するためのさまざまな方法を示しています。

メソッド

スコープ

実装

values.yamlファイル environment 設定を介して

コレクターを介してエクスポートされるすべてのテレメトリデータ (メトリクス、ログ、トレース) に属性を適用します。

チャートは、コレクターによって処理されるすべてのテレメトリデータに deployment.environment=prd を追加する属性プロセッサーを設定します。

values.yamlファイルと instrumentation.env または instrumentation.{instrumentation_library}.env 設定を介して

すべての自動インストルメンテーションされたアプリケーションを一括して、または自動インストルメンテーション言語ごとに deployment.environment を設定できます。

OTEL_RESOURCE_ATTRIBUTES 環境変数を追加し、その値を deployment.environment=prd に設定します。

Kubernetesアプリケーションのデプロイ、DaemonSet、またはポッドの仕様を通して

個々のデプロイ、デーモンセット、またはポッドのレベルでdeployment.environmentを設定できます。

環境変数 OTEL_RESOURCE_ATTRIBUTES を使用し、値 deployment.environment=prd を代入します。

以下の例では、それぞれのメソッドを使って属性を設定する方法を示しています:

環境オプション

values.yaml ファイルで environment オプションを設定します。これにより、自動的にインストルメンテーションされたポッドからのデータを含め、Collector が受信するすべてのテレメトリデータに deployment.environment 属性が追加されます。

  clusterName: my-cluster

  splunkObservability:
    realm: <splunk_realm>
    accessToken: <splunk_access_token>

  environment: prd

  certmanager:
    enabled: true
  operatorcrds:
    install: true
  operator:
    enabled: true
インストルメンテーションの仕様

次のコード例に示すように、values.yaml インストルメンテーション仕様に環境変数を追加します。このメソッドにより、自動的にインストルメンテーションされたポッドからのすべてのテレメトリデータに deployment.environment 属性が追加されます。

operatorcrds:
  install: true
operator:
  enabled: true
instrumentation:
  env:
    - name: OTEL_RESOURCE_ATTRIBUTES
      value: "deployment.environment=prd"
  java:
    env:
      - name: OTEL_RESOURCE_ATTRIBUTES
        value: "deployment.environment=prd-canary-java"
デプロイメント YAML

アプリケーションデプロイメント YAML ファイルを更新します。このメソッドは、指定した環境変数を含むポッドからのすべてのテレメトリデータに deployment.environment 属性を追加します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-java-app
spec:
  template:
    spec:
      containers:
      - name: my-java-app
        image: my-java-app:latest
      env:
      - name: OTEL_RESOURCE_ATTRIBUTES
        value: "deployment.environment=prd"
kubectl

環境変数 OTEL_RESOURCE_ATTRIBUTESkubectl set env を使用して更新します。例:

kubectl set env deployment/<my-deployment> OTEL_RESOURCE_ATTRIBUTES=environment=prd

Helm チャートのデプロイ

values.yamlを設定したら、次のコマンドを使用してHelmチャートをデプロイします:

helm install splunk-otel-collector -f ./values.yaml splunk-otel-collector-chart/splunk-otel-collector

Collector インスタンスの名前と、Collector をインストールする名前空間を変更できます。

たとえば、Collector インスタンスの名前を otel-collector に変更し、o11y 名前空間にインストールするには、次のコマンドを使用します:

helm install otel-collector -f ./values.yaml splunk-otel-collector-chart/splunk-otel-collector --namespace o11y

すべての OpenTelemetry リソースが正常にデプロイされていることを検証します。

リソースには、Collector、Operator、Webhook およびインストルメンテーションが含まれます。以下のコマンドを実行し、リソースが正しくデプロイされていることを確認します。

Collector名前空間で実行されるポッドには、以下が含まれている必要があります:

kubectl get pods
# NAME                                                          READY
# NAMESPACE     NAME                                                            READY   STATUS
# monitoring    splunk-otel-collector-agent-lfthw                               2/2     Running
# monitoring    splunk-otel-collector-k8s-cluster-receiver-856f5fbcf9-pqkwg     1/1     Running
# monitoring    splunk-otel-collector-opentelemetry-operator-56c4ddb4db-zcjgh   2/2     Running

Collector名前空間のWebhookには、以下を含める必要があります:

kubectl get mutatingwebhookconfiguration.admissionregistration.k8s.io
# NAME                                      WEBHOOKS   AGE
# splunk-otel-collector-opentelemetry-operator-mutation   3          14m

コレクター名前空間のインストルメンテーションには、以下を含める必要があります:

kubectl get otelinst
# NAME                          AGE   ENDPOINT
# splunk-instrumentation        3m   http://$(SPLUNK_OTEL_AGENT):4317

インストルメンテーションアプリケーションに注釈を設定する

関連するKubernetesオブジェクト(デプロイ、デーモンセット、またはポッド)がデプロイされていない場合は、アプリケーションオブジェクトのYAMLにinstrumentation.opentelemetry.io/inject-javaアノテーションを追加します。

設定するアノテーションは、使用している言語ランタイムによって異なります。同じ Kubernetes オブジェクトに複数のアノテーションを設定できます。利用可能なアノテーションを次に示します。

Java

アプリケーションデプロイメント YAML に instrumentation.opentelemetry.io/inject-java アノテーションを追加します。

たとえば、次のようなデプロイメントYAMLがあるとします:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-java-app
  namespace: monitoring
spec:
  template:
    spec:
    containers:
    - name: my-java-app
        image: my-java-app:latest

instrumentation.opentelemetry.io/inject-java: "true"spec を追加してゼロコードインストルメンテーションを有効化します:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-java-app
  namespace: monitoring
spec:
  template:
    metadata:
      annotations:
        instrumentation.opentelemetry.io/inject-java: "true"
    spec:
      containers:
      - name: my-java-app-container-name
        image: my-java-app:latest
.NET

アプリケーションデプロイメント YAML に instrumentation.opentelemetry.io/inject-dotnet アノテーションを追加します。

使用環境とランタイム識別子(RID)に応じて、別のアノテーションを追加する必要があります。RID を見つける方法については、「.NET アプリケーションのランタイム識別子を見つける」を参照してください。詳細は以下の表を参照:

RID

アノテーション

備考

linux-x64

instrumentation.opentelemetry.io/otel-dotnet-auto-runtime: "linux-x64"

これはデフォルト値であり、省略することもできます。

linux-musl-x64

instrumentation.opentelemetry.io/otel-dotnet-auto-runtime: "linux-musl-x64"

このアノテーションは、musl ライブラリに基づく環境で動作するアプリケーションに使用します。

linux-x64 ランタイム環境に次のようなデプロイメント YAML があるとします。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-dotnet-app
  namespace: monitoring
spec:
  template:
    spec:
      containers:
      - name: my-dotnet-app-container-name
        image: my-dotnet-app:latest

instrumentation.opentelemetry.io/otel-dotnet-auto-runtime: "linux-x64"instrumentation.opentelemetry.io/inject-dotnet: "monitoring/splunk-otel-collector"spec を追加してゼロコードインストルメンテーションを有効化します:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-dotnet-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-dotnet-app
  template:
    metadata:
      name: my-dotnet-app
      labels:
        app: my-dotnet-app
      annotations:
        instrumentation.opentelemetry.io/inject-dotnet: "true"
        instrumentation.opentelemetry.io/otel-dotnet-auto-runtime: "linux-x64"
    spec:
      automountServiceAccountToken: false
      containers:
        - image: my-dotnet-app:latest
          name: my-dotnet-app-container-name
          imagePullPolicy: IfNotPresent
      nodeSelector:
        kubernetes.io/os: "linux"

linux-musl-x64 ランタイム環境に次のようなデプロイメント YAML があるとします。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-dotnet-app
  namespace: monitoring
spec:
  template:
    spec:
      containers:
       - name: my-dotnet-app-container-name
         image: my-dotnet-app:latest

instrumentation.opentelemetry.io/otel-dotnet-auto-runtime: "linux-musl-x64"instrumentation.opentelemetry.io/inject-dotnet: "monitoring/splunk-otel-collector"spec を追加してゼロコードインストルメンテーションを有効化します:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-dotnet-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-dotnet-app
  template:
    metadata:
      name: my-dotnet-app
      labels:
        app: my-dotnet-app
      annotations:
        instrumentation.opentelemetry.io/inject-dotnet: "true"
        instrumentation.opentelemetry.io/otel-dotnet-auto-runtime: "linux-musl-x64"
    spec:
      automountServiceAccountToken: false
      containers:
        - image: my-dotnet-app:latest
          name: my-dotnet-app-container-name
          imagePullPolicy: IfNotPresent
      nodeSelector:
        kubernetes.io/os: "linux"
Node.js

次のようなデプロイメント YAML があるとします。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nodejs-app
  namespace: monitoring
spec:
  template:
    spec:
      containers:
      - name: my-nodejs-app-container-name
        image: my-nodejs-app:latest

instrumentation.opentelemetry.io/inject-nodejs: "true"spec を追加してゼロコードインストルメンテーションを有効化します:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nodejs-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-nodejs-app
  template:
    metadata:
      name: my-nodejs-app
      labels:
        app: my-nodejs-app
      annotations:
        instrumentation.opentelemetry.io/inject-nodejs: "true"
    spec:
      automountServiceAccountToken: false
      containers:
        - image: my-nodejs-app:latest
          name: my-nodejs-app-container-name
          imagePullPolicy: IfNotPresent
      nodeSelector:
        kubernetes.io/os: "linux"

異なる名前空間でのアノテーションの適用

現在の名前空間が monitoring でない場合は、アノテーションを変更して、OpenTelemetry Collector をインストールした名前空間を指定します。

たとえば、現在の名前空間が <my-namespace> で、Collectorを monitoring にインストールした場合は、アノテーションを "instrumentation.opentelemetry.io/inject-<application_language>": "monitoring/splunk-otel-collector" に設定します:

kubectl patch deployment <my-deployment> -n <my-namespace> -p '{"spec":{"template":{"metadata":{"annotations":{"instrumentation.opentelemetry.io/inject-<application_language>":"monitoring/splunk-otel-collector"}}}}}'

<application_language> を検出するアプリケーションの言語に置き換えます。

マルチコンテナポッドでのインストルメンテーションアプリケーション

デフォルトでは、ゼロコードインストルメンテーションは Kubernetes ポッド仕様の最初のコンテナをインストルメンテーションします。アノテーションを追加することで、インストルメンテーションする複数のコンテナを指定できます。

以下の例では、myapp および myapp2 コンテナで動作するJavaアプリケーションをインストルメンテーションします:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment-with-multiple-containers
spec:
  selector:
    matchLabels:
      app: my-pod-with-multiple-containers
  replicas: 1
  template:
    metadata:
      labels:
        app: my-pod-with-multiple-containers
      annotations:
        instrumentation.opentelemetry.io/inject-java: "true"
        instrumentation.opentelemetry.io/container-names: "myapp,myapp2"

特定の言語で複数のコンテナをインストルメンテーションすることもできます。これを行うには、instrumentation.opentelemetry.io/<language>-container-names アノテーションを使用してインストルメンテーション言語とコンテナを指定します。次の例は、Java アプリケーションを myappmyapp2で、Node.js アプリケーションを myapp3 でインストルメンテーションした状態を示します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment-with-multi-containers-multi-instrumentations
spec:
  selector:
    matchLabels:
      app: my-pod-with-multi-containers-multi-instrumentations
  replicas: 1
  template:
    metadata:
      labels:
        app: my-pod-with-multi-containers-multi-instrumentations
      annotations:
        instrumentation.opentelemetry.io/inject-java: "true"
        instrumentation.opentelemetry.io/java-container-names: "myapp,myapp2"
        instrumentation.opentelemetry.io/inject-nodejs: "true"
        instrumentation.opentelemetry.io/python-container-names: "myapp3"

ゼロコードインストルメンテーションを無効にする

ゼロコードインストルメンテーションを無効にするには、以下のコマンドを使用してアノテーションを削除します:

kubectl patch deployment <my-deployment> -n <my-namespace> --type=json -p='[{"op": "remove", "path": "/spec/template/metadata/annotations/instrumentation.opentelemetry.io~1inject-<application_language>"}]'

<application_language> をインストルメンテーションを無効にするアプリケーションの言語に置き換えます。

インストルメンテーションの検証

インストルメンテーションが成功したことを確認するには、個々のポッドで次のコマンドを実行します:

kubectl describe pod <application_pod_name> -n <namespace>

インストルメンテーションされたポッドには、opentelemetry-auto-instrumentation という名前の initContainer が含まれ、ターゲットアプリケーションコンテナには、以下のデモ出力にあるような OTEL_* 環境変数がいくつかあるはずです:

# Name:             opentelemetry-demo-frontend-57488c7b9c-4qbfb
# Namespace:        otel-demo
# Annotations:      instrumentation.opentelemetry.io/inject-java: true
# Status:           Running
# Init Containers:
#   opentelemetry-auto-instrumentation:
#     Command:
#       cp
#       -a
#       /autoinstrumentation/.
#       /otel-auto-instrumentation/
#     State:          Terminated
#       Reason:       Completed
#       Exit Code:    0
# Containers:
#   frontend:
#     State:          Running
#     Ready:          True
#     Environment:
#       FRONTEND_PORT:                              8080
#       FRONTEND_ADDR:                              :8080
#       AD_SERVICE_ADDR:                            opentelemetry-demo-adservice:8080
#       CART_SERVICE_ADDR:                          opentelemetry-demo-cartservice:8080
#       CHECKOUT_SERVICE_ADDR:                      opentelemetry-demo-checkoutservice:8080
#       CURRENCY_SERVICE_ADDR:                      opentelemetry-demo-currencyservice:8080
#       PRODUCT_CATALOG_SERVICE_ADDR:               opentelemetry-demo-productcatalogservice:8080
#       RECOMMENDATION_SERVICE_ADDR:                opentelemetry-demo-recommendationservice:8080
#       SHIPPING_SERVICE_ADDR:                      opentelemetry-demo-shippingservice:8080
#       WEB_OTEL_SERVICE_NAME:                      frontend-web
#       PUBLIC_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT:  http://localhost:8080/otlp-http/v1/traces
#       NODE_OPTIONS:                                --require /otel-auto-instrumentation/autoinstrumentation.java
#       SPLUNK_OTEL_AGENT:                           (v1:status.hostIP)
#       OTEL_SERVICE_NAME:                          opentelemetry-demo-frontend
#       OTEL_EXPORTER_OTLP_ENDPOINT:                http://$(SPLUNK_OTEL_AGENT):4317
#       OTEL_RESOURCE_ATTRIBUTES_POD_NAME:          opentelemetry-demo-frontend-57488c7b9c-4qbfb (v1:metadata.name)
#       OTEL_RESOURCE_ATTRIBUTES_NODE_NAME:          (v1:spec.nodeName)
#       OTEL_PROPAGATORS:                           tracecontext,baggage,b3
#       OTEL_RESOURCE_ATTRIBUTES:                   splunk.zc.method=autoinstrumentation-java:0.41.1,k8s.container.name=frontend,k8s.deployment.name=opentelemetry-demo-frontend,k8s.namespace.name=otel-demo,k8s.node.name=$(OTEL_RESOURCE_ATTRIBUTES_NODE_NAME),k8s.pod.name=$(OTEL_RESOURCE_ATTRIBUTES_POD_NAME),k8s.replicaset.name=opentelemetry-demo-frontend-57488c7b9c,service.version=1.5.0-frontend
#     Mounts:
#       /otel-auto-instrumentation from opentelemetry-auto-instrumentation (rw)
# Volumes:
#   opentelemetry-auto-instrumentation:
#     Type:        EmptyDir (a temporary directory that shares a pod's lifetime)

Splunk Observability APM で結果を表示する

Operator が作業をできるように許可します。Operator は Kubernetes API リクエストをインターセプトして変更し、注釈が付けられたポッドを作成および更新します。内部ポッドアプリケーションコンテナはインストルメンテーションされ、トレースおよびメトリクスデータは APM ダッシュボードに表示されます。

(オプション)インストルメンテーションの設定

Splunk Distribution of OpenTelemetry Collector は、インストルメンテーションのニーズに合わせて設定できます。ほとんどの場合、基本設定を調整するだけで開始するには十分です。

カスタムサンプリングをアクティブ化したり、環境変数やシステムプロパティを使って報告されるスパンにカスタムデータを含めたりするような、高度な設定を追加することができます。これを実行するには、values.yaml ファイルと instrumentation.sampler 設定を使用します。詳細については、GitHub のドキュメントおよび GitHub の例を参照してください。

また、OTEL_RESOURCE_ATTRIBUTES 環境変数やその他の環境変数を使用してインストルメンテーションを設定するには、「デプロイメント環境の設定」で示した方法を使用できます。たとえば、すべてのスパンにキーと値のペア build.id=feb2023_v2 を含めたい場合、環境変数 OTEL_RESOURCE_ATTRIBUTES を設定します。

kubectl set env deployment/<my-deployment> OTEL_RESOURCE_ATTRIBUTES=build.id=feb2023_v2

詳細については、「Kubernetes でのオートディスカバリとインストルメンテーションのための高度なカスタマイズ」を参照してください。

トラブルシューティング

自動検出の設定に問題がある場合は、以下のトラブルシューティング ガイドラインを参照してください。

失敗のログをチェックする

ログを調査し、オペレーターと証明書マネージャーが機能していることを確認します。

アプリケーション

kubectlコマンド

オペレーター

kubectl logs -l app.kubernetes.io/name=operator

証明書マネージャー

  • kubectl logs -l app=certmanager

  • kubectl logs -l app=cainjector

  • kubectl logs -l app=webhook

証明書を検証する

証明書が使用可能であることを確認します。証明書を検索するには、次のコマンドを使用します。

kubectl get certificates
# NAME                                          READY   SECRET                                                           AGE
# splunk-otel-collector-operator-serving-cert   True    splunk-otel-collector-operator-controller-manager-service-cert   5m

アプリケーションのインストルメンテーション時に発生する一般的なエラーのトラブルシューティングについては、以下ガイドを参照してください:

さらに詳しく