ウクライナ国旗 ウクライナの友人や同僚を支援します。ウクライナを支援するには このページ をご覧ください。

Kubernetes用オペレーター

バージョン  1.62 最新

オペレーターについて

Jaeger オペレーターは、Kubernetes オペレーターexternal link の実装です。オペレーターは、別のソフトウェアを実行する際の運用上の複雑さを軽減するソフトウェアです。より技術的には、オペレーターは、Kubernetes アプリケーションのパッケージ化、デプロイ、および管理の方法です。

Kubernetes アプリケーションとは、Kubernetes にデプロイされ、Kubernetes API と kubectl(Kubernetes)または oc(OKD)ツールを使用して管理されるアプリケーションです。Kubernetes を最大限に活用するには、Kubernetes 上で実行されるアプリのサービスと管理を拡張するための、一貫性のある API のセットが必要です。オペレーターは、Kubernetes 上でこのタイプのアプリを管理するランタイムと考えてください。

オペレーターのインストール

Jaeger オペレーターは、Kubernetes ベースのクラスタにインストールでき、特定のネームスペース内、またはクラスタ全体で新しい Jaeger カスタムリソース (CR) を監視できます。通常、クラスタごとに 1 つの Jaeger オペレーターしかありませんが、マルチテナントシナリオでは、ネームスペースごとに最大 1 つの Jaeger オペレーターが存在する可能性があります。新しい Jaeger CR が検出されると、オペレーターはリソースの所有者になることを試み、ラベル jaegertracing.io/operated-by を新しい CR に設定し、オペレーターのネームスペースと名前をラベルの値として設定します。

できるだけ多くの Kubernetes バージョンで Jaeger オペレーターが動作することを目指していますが、Kubernetes の最新の 3 つのマイナーバージョン (currentcurrent-1current-2) で再現できるバグのみを修正できると予想するのが現実的です。

複数のオペレーターが同じネームスペースのセットを監視している場合でも、どのオペレーターが CR の所有者になるかは未定義の動作です。サイドカーの自動注入も未定義の動作になる可能性があります。したがって、各ネームスペースを監視するオペレーターは最大 1 つにすることを強くお勧めします。ネームスペースには任意の数の Jaeger インスタンス (CR) を含めることができることに注意してください。

Jaeger オペレーターのバージョンは、Jaeger コンポーネント(**jaeger-query**、**jaeger-collector**、**jaeger-agent**)の 1 つのバージョンを追跡します。Jaeger コンポーネントの新しいバージョンがリリースされると、以前のバージョンの実行中のインスタンスを新しいバージョンにアップグレードする方法を理解する、オペレーターの新しいバージョンがリリースされます。

前提条件

バージョン 1.31 以降、Jaeger オペレーターは Webhook を使用して Jaeger カスタムリソース (CR) を検証します。これには、cert-managerexternal link がインストールされている必要があります。サポートされているバージョンの詳細なリストは、互換性マトリックスexternal link にあります。インストールガイドは こちらexternal link をご覧ください。

cert-manager バージョン 1.6.1 以降をインストールする必要があります。

インストールモード

Jaeger オペレーターは、クラスタ全体または特定のネームスペースのいずれかで、新しい Jaeger カスタムリソース (CR) を監視するようにインストールできます。クラスタモードで構成されている場合、オペレーターは

  • すべてのネームスペースで Jaeger リソースに関連するイベントを監視する
  • sidecar.jaegertracing.io/inject アノテーションを検索するためにネームスペース自体を監視する
  • sidecar.jaegertracing.io/inject アノテーションに基づいてサイドカーを挿入または削除するために、すべてのデプロイメントを監視する
  • 必要に応じて、クラスタロールバインディングを作成する

クラスタ全体の資源(ClusterRoleClusterRoleBinding)を使用しない場合は、Jaeger オペレーターが Jaeger リソースに関連するイベントを監視する必要があるネームスペースをコンマ区切りリストで WATCH_NAMESPACE に設定します。特定のネームスペース(例:observability)で Jaeger オペレーターを実行し、別のネームスペース(例:myproject)で Jaeger リソースを管理することができます。そのためには、オペレーターがリソースを監視する必要がある各ネームスペースに対して、次のような RoleBinding を使用します。

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: jaeger-operator-in-myproject
  namespace: myproject
subjects:
- kind: ServiceAccount
  name: jaeger-operator
  namespace: observability
roleRef:
  kind: Role
  name: jaeger-operator
  apiGroup: rbac.authorization.k8s.io

Kubernetes へのオペレーターのインストール

次の手順では、observability ネームスペースを作成し、そこに Jaeger オペレーターをインストールします。デフォルトでは、オペレーターはすべてのネームスペースを監視します。

kubectlコマンドが有効なKubernetesクラスタと正しく通信するように設定されていることを確認してください。クラスタを持っていない場合は、minikubeexternal link を使用してローカルに作成できます。

オペレータをインストールするには、次のコマンドを実行します。

kubectl create namespace observability # <1>
kubectl create -f https://github.com/jaegertracing/jaeger-operator/releases/download/v1.62.0.0/jaeger-operator.yaml -n observability # <2>

<1> これは、展開ファイルでデフォルトで使用される名前空間を作成します。Jaegerオペレータを別の名前空間にインストールする場合は、展開ファイルを編集してobservabilityを目的の名前空間値に変更する必要があります。

<2> これは、apiVersion: jaegertracing.io/v1の「カスタムリソース定義」をインストールします。

オペレータはクラスタ全体モードでインストールされます。特定の名前空間だけを監視する場合は、オペレータマニフェストのClusterRoleClusterRoleBindingRoleRoleBindingに変更し、JaegerオペレータDeploymentでWATCH_NAMESPACE環境変数を設定する必要があります。

この時点で、jaeger-operatorデプロイメントが利用可能になっているはずです。次のコマンドを実行して確認できます。

$ kubectl get deployment jaeger-operator -n observability

NAME              DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
jaeger-operator   1         1         1            1           48s

オペレータは、Jaegerインスタンスの作成準備ができました。

OKD/OpenShiftへのオペレータのインストール

前のセクションの手順は、OKDまたはOpenShiftへのオペレータのインストールにも有効です。ロールベースのアクセス制御(RBAC)ルール、カスタムリソース定義、およびオペレータをインストールする際は、特権ユーザーとしてログインしていることを確認してください。

oc login -u <privileged user>

oc new-project observability # <1>
oc create -f https://github.com/jaegertracing/jaeger-operator/releases/download/v1.62.0.0/jaeger-operator.yaml -n observability # <2>

<1> これは、展開ファイルでデフォルトで使用される名前空間を作成します。Jaegerオペレータを別の名前空間にインストールする場合は、展開ファイルを編集してobservabilityを目的の名前空間値に変更する必要があります。

<2> これは、apiVersion: jaegertracing.io/v1の「カスタムリソース定義」をインストールします。

オペレータはクラスタ全体モードでインストールされます。特定の名前空間だけを監視する場合は、オペレータマニフェストのClusterRoleClusterRoleBindingRoleRoleBindingに変更し、JaegerオペレータDeploymentでWATCH_NAMESPACE環境変数を設定する必要があります。

オペレータがインストールされたら、個々のJaegerインスタンスをインストールできるユーザーにjaeger-operatorロールを付与します。次の例では、ユーザーdeveloperがJaegerインスタンスを作成できるようにするロールバインディングを作成します。

oc create \
  rolebinding developer-jaeger-operator \
  --role=jaeger-operator \
  --user=developer

ロールが付与されたら、特権のないユーザーに戻ってください。

クイックスタート - AllInOneイメージの展開

Jaegerインスタンスを作成する最も簡単な方法は、次の例のようなYAMLファイルを作成することです。これにより、デフォルトのAllInOne戦略がインストールされ、**all-in-one**イメージ(**jaeger-agent**、**jaeger-collector**、**jaeger-query**、およびJaeger UIを組み合わせたもの)が単一のポッドに展開され、デフォルトでインメモリストレージが使用されます。

このデフォルトの戦略は、本番環境ではなく、開発、テスト、デモの目的を意図したものです。
apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: simplest

YAMLファイルは、kubectlで使用できます。

kubectl apply -f simplest.yaml

数秒後、クイックデモと開発目的のための新しいインメモリall-in-oneインスタンスのJaegerが利用可能になります。作成されたインスタンスを確認するには、jaegerオブジェクトを一覧表示します。

$ kubectl get jaegers
NAME        CREATED AT
simplest    28s

ポッド名を取得するには、simplest Jaegerインスタンスに属するポッドを照会します。

$ kubectl get pods -l app.kubernetes.io/instance=simplest
NAME                        READY     STATUS    RESTARTS   AGE
simplest-6499bb6cdd-kqx75   1/1       Running   0          2m

同様に、ログは、前の例で取得したポッド名を使用してポッドから直接、またはインスタンスに属するすべてのポッドから照会できます。

$ kubectl logs -l app.kubernetes.io/instance=simplest
...
{"level":"info","ts":1535385688.0951214,"caller":"healthcheck/handler.go:133","msg":"Health Check state change","status":"ready"}
OKD/OpenShiftでは、コンテナ名を指定する必要があります。
$ kubectl logs -l app.kubernetes.io/instance=simplest -c jaeger
...
{"level":"info","ts":1535385688.0951214,"caller":"healthcheck/handler.go:133","msg":"Health Check state change","status":"ready"}

オペレータの設定

Jaegerオペレータは、コマンドラインインターフェースパラメータ、環境変数、または設定ファイルを使用して設定できます。同じ変数が異なるレベルで指定されている場合、優先順位は次のとおりです。

  1. コマンドラインパラメータ(フラグ)
  2. 環境変数
  3. 設定ファイル

各項目は、その下の項目よりも優先されます。利用可能なオプションは、--helpフラグを使用してオペレータを実行することで確認できます。

$ podman run jaegertracing/jaeger-operator:master start --help

特定のJaegerオペレータデプロイメントのフラグを使用してlog-levelパラメータを設定する(抜粋)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: jaeger-operator
spec:
  template:
    spec:
      containers:
      - name: jaeger-operator
        image: jaegertracing/jaeger-operator:master
        args: ["start", "--log-level=debug"]

特定のJaegerオペレータデプロイメントで環境変数を使用してlog-levelパラメータを設定する(抜粋)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: jaeger-operator
spec:
  template:
    spec:
      containers:
      - name: jaeger-operator
        image: jaegertracing/jaeger-operator:master
        args: ["start"]
        env:
        - name: LOG-LEVEL
          value: debug

設定ファイルでlog-levelパラメータを設定する

log-level: debug

設定ファイルを使用するには、${HOME}/.jaeger-operator.yamlにファイルを作成するか、--configで場所を指定します。

展開戦略

Jaegerインスタンスを作成すると、戦略に関連付けられます。戦略はカスタムリソースファイルで定義され、Jaegerバックエンドに使用されるアーキテクチャを決定します。デフォルトの戦略はallInOneです。他の可能な値はproductionstreamingです。

利用可能な戦略については、次のセクションで説明します。

AllInOne(デフォルト)戦略

この戦略は、開発、テスト、デモの目的を意図したものです。

主なバックエンドコンポーネントである**jaeger-agent**、**jaeger-collector**、および**jaeger-query**サービスはすべて、単一のexecutableにパッケージ化されており、(デフォルトで)インメモリストレージを使用するように構成されています。この戦略は、1つのレプリカを超えてスケーリングできません。

Production戦略

production戦略は(名前が示すように)、トレースデータの長期的なストレージが重要であり、よりスケーラブルで高可用性のアーキテクチャが必要な本番環境を対象としています。したがって、各バックエンドコンポーネントは別々に展開されます。

**jaeger-agent**は、インストルメント化されたアプリケーションのサイドカーとして、またはデーモンセットとして注入できます。

**jaeger-collector**は、オンデマンドで自動スケーリングするように構成できます。.Spec.Collector.Replicasの値が提供されていない場合、デフォルトでは、Jaegerオペレータは**jaeger-collector**のHorizontal Pod Autoscaler(HPA)構成を作成します。**jaeger-collector**のポッドが消費すると予想されるリソースについて、.Spec.Collector.MaxReplicasの明示的な値と妥当な値を設定することをお勧めします。.Spec.Collector.MaxReplicasが設定されていない場合、オペレータは値として100を設定します。Kubernetesのウェブサイトexternal link でHPAの詳細を参照してください。.Spec.Collector.Autoscalefalseに設定することで、この機能を明示的に無効にすることができます。**jaeger-collector**の制限とレプリカの最大数を設定する例を次に示します。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: simple-prod
spec:
  strategy: production
  collector:
    maxReplicas: 5
    resources:
      limits:
        cpu: 100m
        memory: 128Mi

**jaeger-query**および**jaeger-collector**サービスは、サポートされているストレージタイプ(現在CassandraまたはElasticsearch)で構成されています。パフォーマンスと復元力のために、これらのコンポーネントの複数のインスタンスを必要に応じてプロビジョニングできます。

主な追加要件は、ストレージタイプとオプションの詳細を提供することです。

    storage:
      type: elasticsearch
      options:
        es:
          server-urls: http://elasticsearch:9200

Streaming戦略

streaming戦略は、コレクタとバックエンドストレージ(CassandraまたはElasticsearch)の間に効果的に位置するストリーミング機能を提供することで、production戦略を拡張するように設計されています。これにより、高負荷状況下でのバックエンドストレージへの圧力を軽減し、ストリーミングプラットフォーム(Kafka)からリアルタイムのspanデータに直接アクセスできる他のトレース後処理機能を有効にすることができます。

「Production戦略」セクションで説明されているように、**jaeger-collector**はオンデマンドで自動スケーリングするように構成できます。

**jaeger-ingester**もオンデマンドで自動スケーリングするように構成できます。.Spec.Ingester.Replicasの値が提供されていない場合、デフォルトでは、Jaegerオペレータは**jaeger-ingester**のHorizontal Pod Autoscaler(HPA)構成を作成します。**jaeger-ingester**のポッドが消費すると予想されるリソースについて、.Spec.Ingester.MaxReplicasの明示的な値と妥当な値を設定することをお勧めします。.Spec.Ingester.MaxReplicasが設定されていない場合、オペレータは値として100を設定します。Kubernetesのウェブサイトexternal link でHPAの詳細を参照してください。.Spec.Ingester.Autoscalefalseに設定することで、この機能を明示的に無効にすることができます。**jaeger-ingester**の制限とレプリカの最大数を設定する例を次に示します。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: simple-streaming
spec:
  strategy: streaming
  ingester:
    maxReplicas: 8
    resources:
      limits:
        cpu: 100m
        memory: 128Mi

既存のKafkaクラスタ

必要な追加情報は、Kafkaプラットフォームへのアクセスに関する詳細を提供することだけです。これは、collectorコンポーネント(プロデューサーとして)とingesterコンポーネント(コンシューマーとして)で構成されています。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: simple-streaming
spec:
  strategy: streaming
  collector:
    options:
      kafka: # <1>
        producer:
          topic: jaeger-spans
          brokers: my-cluster-kafka-brokers.kafka:9092
  ingester:
    options:
      kafka: # <1>
        consumer:
          topic: jaeger-spans
          brokers: my-cluster-kafka-brokers.kafka:9092
      ingester:
        deadlockInterval: 5s # <2>
  storage:
    type: elasticsearch
    options:
      es:
        server-urls: http://elasticsearch:9200

<1> **jaeger-collector**がメッセージを生成し、**jaeger-ingester**がメッセージを消費するために使用するKafka構成を識別します。

<2> デッドロックインターバルはデフォルトで無効になっています(0に設定)。これにより、メッセージが到着しない場合でも**jaeger-ingester**が終了するのを防ぎます。メッセージを待機してから終了するまでの分数を指定するように構成できます。

自己プロビジョニングされたKafkaクラスタ

自己プロビジョニングされたアプローチを使用するには、プロデューサー/コンシューマーブローカーのプロパティを定義しないでください。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: auto-provision-kafka
spec:
  strategy: streaming
  storage:
    type: elasticsearch
    options:
      es:
        # Note: This assumes elasticsearch is running in the "default" namespace.
        server-urls: http://elasticsearch.default.svc:9200

フラグ--kafka-provisionfalseに設定することで、Kafkaクラスタの自己プロビジョニングを無効にできます。デフォルト値はautoであり、JaegerオペレータはKubernetesクラスタに対してKafkaカスタムリソースを処理する機能を照会します。これは通常、Kafkaオペレータのインストールプロセス中に設定されるため、KafkaオペレータがJaegerオペレータの*後*に実行されることが予想される場合は、フラグをtrueに設定できます。

カスタムリソース定義の理解

Kubernetes APIでは、リソースとは、特定の種類のAPIオブジェクトのコレクションを格納するエンドポイントです。たとえば、組み込みのPodsリソースには、Podオブジェクトのコレクションが含まれています。カスタムリソース定義(CRD)オブジェクトは、クラスタに新しい一意のオブジェクトKindを定義し、Kubernetes APIサーバーがそのライフサイクル全体を処理できるようにします。

カスタムリソース(CR)オブジェクトを作成するには、クラスタ管理者は最初にカスタムリソース定義(CRD)を作成する必要があります。CRDにより、クラスタユーザーはCRを作成して、新しいリソースタイプをプロジェクトに追加できます。オペレータは、カスタムリソースオブジェクトが作成されるのを監視し、カスタムリソースが作成されると、カスタムリソースオブジェクトに定義されているパラメータに基づいてアプリケーションを作成します。

クラスタ管理者だけがCRDを作成できますが、開発者は、読み取りと書き込みの権限がある場合は、既存のCRDからCRを作成できます。

参考として、より複雑なall-in-oneインスタンスを作成する方法を次に示します。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: my-jaeger
spec:
  strategy: allInOne # <1>
  allInOne:
    image: jaegertracing/all-in-one:latest # <2>
    options: # <3>
      log-level: debug # <4>
  storage:
    type: memory # <5>
    options: # <6>
      memory: # <7>
        max-traces: 100000
  ingress:
    enabled: false # <8>
  agent:
    strategy: DaemonSet # <9>
  annotations:
    scheduler.alpha.kubernetes.io/critical-pod: "" # <10>

<1> デフォルトの戦略はallInOneです。他の可能な値はproductionstreamingです。

<2> 通常のDocker構文で使用されるイメージ。

<3> 基になるバイナリにそのまま渡される(ストレージ関連ではない)オプション。利用可能なすべてのオプションについては、Jaegerのドキュメントまたは関連バイナリの--helpオプションを参照してください。

<4> オプションは単純なkey: valueマップです。この場合、オプション--log-level=debugをバイナリに渡す必要があります。

<5> 使用するストレージタイプ。デフォルトではmemoryになりますが、他のサポートされているストレージタイプ(Cassandra、Elasticsearch、Kafka)にすることができます。

<6> すべてのストレージ関連オプションは、'allInOne'またはその他のコンポーネントオプションの下ではなく、ここに配置する必要があります。

<7> 一部のオプションは名前空間化されており、代わりにネストされたオブジェクトに分割できます。memory.max-traces: 100000のように指定することもできました。

<8> デフォルトでは、jaeger-queryサービス用のイングレスオブジェクトが作成されます。そのenabledオプションをfalseに設定することで無効にできます。OpenShiftにデプロイする場合は、Routeオブジェクトとして表されます。

<9> デフォルトでは、オペレーターはjaeger-agentがターゲットポッド内でサイドカーとしてデプロイされていると想定しています。戦略を「DaemonSet」に指定すると、オペレーターはjaeger-agentをDaemonSetとしてデプロイするようになります。ただし、トレーサークライアントはノードのIPを使用するために「JAEGER_AGENT_HOST」環境変数をオーバーライドする必要がある可能性があります。

<10> すべてのデプロイメント(サービスではない)に適用するアノテーションを定義します。これらは、個々のコンポーネントで定義されたアノテーションによってオーバーライドできます。

さまざまなJaeger構成の例となるカスタムリソースは、GitHub外部リンク で確認できます。

カスタムリソースの構成

上記の最も簡単な例を使用して、デフォルト値を使用してJaegerインスタンスを作成するか、独自のカスムリソースファイルを作成できます。

Spanストレージオプション

Cassandraストレージ

ストレージタイプがCassandraに設定されている場合、オペレーターはJaegerの実行に必要なスキーマを作成するバッチジョブを自動的に作成します。このバッチジョブはJaegerのインストールをブロックするため、スキーマが正常に作成された後でのみ起動します。このバッチジョブの作成は、enabledプロパティをfalseに設定することで無効にできます。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: cassandra-without-create-schema
spec:
  strategy: allInOne
  storage:
    type: cassandra
    cassandraCreateSchema:
      enabled: false # <1>

<1> デフォルトはtrueです。

バッチジョブのその他の側面も構成できます。可能なすべてのオプションを含む例を以下に示します。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: cassandra-with-create-schema
spec:
  strategy: allInOne # <1>
  storage:
    type: cassandra
    options: # <2>
      cassandra:
        servers: cassandra
        keyspace: jaeger_v1_datacenter3
    cassandraCreateSchema: # <3>
      datacenter: "datacenter3"
      mode: "test"

<1> productionstreamingでも同じように機能します。

<2> これらのオプションは、collectorqueryなどの通常のJaegerコンポーネント用です。

<3> create-schemaジョブのオプションです。

デフォルトのcreate-schemaジョブはMODE=prodを使用します。これは、NetworkTopologyStrategyをクラスとして使用してレプリケーションファクターを2にすることを意味し、実際にはCassandraクラスタに少なくとも3つのノードが必要であることを意味します。SimpleStrategyが必要な場合は、モードをtestに設定します。これにより、レプリケーションファクターが1に設定されます。create-schemaスクリプト外部リンク を参照してください。

Elasticsearchストレージ

デフォルトでは、Elasticsearchストレージは初期化ジョブを実行する必要がありません。ただし、Elasticsearchストレージでは、古いデータをストレージからクリーンアップするためにcronジョブを実行する必要があります。

ロールオーバー(es.use-aliases)が有効になっている場合、JaegerオペレーターはElasticsearchストレージを初期化するジョブと、必要なインデックス管理アクションを実行する2つのcronジョブもデプロイします。

外部Elasticsearch

Jaegerは外部Elasticsearchクラスタで使用できます。次の例は、外部Elasticsearchクラスタ(Elasticsearch Operator外部リンク で作成)を使用するJaeger CRを示しています。ボリュームからマウントされたTLS CA証明書と、シークレットに保存されているユーザー名/パスワードを使用しています。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: simple-prod
spec:
  strategy: production
  storage:
    type: elasticsearch # <1>
    options:
      es:
        server-urls: https://quickstart-es-http.default.svc:9200 # <2>
        index-prefix: my-prefix
        tls: # <3>
          ca: /es/certificates/ca.crt
    secretName: jaeger-secret # <4>
  volumeMounts: # <5>
    - name: certificates
      mountPath: /es/certificates/
      readOnly: true
  volumes:
    - name: certificates
      secret:
        secretName: quickstart-es-http-certs-public

<1> ストレージタイプElasticsearch。

<2> デフォルトの名前空間で実行されているElasticsearchサービスのURL。

<3> TLS構成。この場合はCA証明書のみですが、相互TLSを使用する場合はes.tls.keyes.tls.certも含まれる場合があります。

<4> 環境変数ES_PASSWORDES_USERNAMEを定義するシークレット。kubectl create secret generic jaeger-secret --from-literal=ES_PASSWORD=changeme --from-literal=ES_USERNAME=elasticで作成されます。

<5> すべてのストレージコンポーネントにマウントされるボリュームマウントとボリューム。

自己プロビジョニング

状況によっては、Jaeger OperatorはElasticsearch Operator外部リンク を使用して適切なElasticsearchクラスタをプロビジョニングできます。Jaeger CRは、OpenShift Cluster Logging外部リンク と同じ構成を公開します。

この機能は、OKD/OpenShiftクラスタでのみサポートされています。この機能ではSpark依存関係はサポートされていません Issue #294外部リンク

Jaegerのproductionインスタンスの一部としてes.server-urlsオプションがなく、ストレージタイプとしてelasticsearchが設定されている場合、Jaeger Operatorはストレージセクションで提供された構成に基づいてカスタムリソースを作成することで、Elasticsearch Operatorを介してElasticsearchクラスタを作成します。Elasticsearchクラスタは、単一のJaegerインスタンス専用にすることを目的としています。

AWS gp2永続ストレージを使用する単一ノードElasticsearchクラスタを持つJaegerの例を次に示します。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: simple-prod
spec:
  strategy: production
  storage:
    type: elasticsearch
    elasticsearch:
      nodeCount: 1 # <1>
      storage: # <2>
        storageClassName: gp2
        size: 5Gi
      resources: # <3>
        requests:
          cpu: 200m
          memory: 4Gi
        limits:
          memory: 4Gi
      redundancyPolicy: ZeroRedundancy # <4>

<1> Elasticsearchノードの数。高可用性のために、少なくとも3つのノードを使用してください。「split brain」問題が発生する可能性があるため、2つのノードは使用しないでください。

<2> 永続ストレージ構成。この場合は、サイズが5GiのAWS gp2です。省略した場合はemptyDirが使用されます。Elasticsearchオペレーターは、Jaegerインスタンスで削除されないPersistentVolumeClaimPersistentVolumeをプロビジョニングします。同じ名前と名前空間を持つJaegerが作成された場合、同じボリュームをマウントできます。OpenShiftのSCCポリシーのため、一部のストレージはデフォルトの名前空間で失敗する可能性があります。

<3> Elasticsearchノードのリソース。この場合は4Giで、デフォルトで必要なヒープスペース2Giになります。ヒープサイズの推奨事項については、Elasticsearchのドキュメント外部リンク を参照してください。

<4> データレプリケーションポリシーは、Elasticsearchシャードがクラスタ内のデータノード間でどのようにレプリケートされるかを定義します。指定されていない場合、Jaeger Operatorはノードの数に基づいて最適なレプリケーションを自動的に決定します。

  • FullRedundancy Elasticsearchは、各インデックスのプライマリシャードをすべてのデータノードに完全にレプリケートします。これにより、最高の安全性を実現できますが、必要なディスク容量が最も多く、パフォーマンスが最も低下します。
  • MultipleRedundancy Elasticsearchは、各インデックスのプライマリシャードをデータノードの半分に完全にレプリケートします。これにより、安全性とパフォーマンスのバランスが取れます。
  • SingleRedundancy Elasticsearchは、各インデックスのプライマリシャードのコピーを1つ作成します。少なくとも2つのデータノードが存在する限り、データは常に利用可能であり、復旧可能です。5つ以上のノードを使用する場合、MultipleRedundancyよりもパフォーマンスが向上します。単一Elasticsearchノードのデプロイメントには、このポリシーを適用できません。
  • ZeroRedundancy Elasticsearchは、プライマリシャードのコピーを作成しません。ノードがダウンしたり、障害が発生したりした場合、データが利用できなくなるか、失われる可能性があります。安全性よりもパフォーマンスを重視する場合、または独自のディスク/PVCバックアップ/リストア戦略を実装している場合は、このモードを使用してください。

フラグ--es-provisionfalseに設定することで、Elasticsearchクラスタの自己プロビジョニングを無効にできます。デフォルト値はautoで、Jaeger OperatorはKubernetesクラスタにElasticsearchカスタムリソースを処理できるかどうかをクエリします。これは通常、Elasticsearch Operatorのインストールプロセス中に設定されるため、Elasticsearch OperatorをJaeger Operatorの*後*に実行する予定がある場合は、フラグをtrueに設定できます。

現時点では、名前空間ごとに自己プロビジョニングされたElasticsearchインスタンスを持つJaegerは1つだけです。

Elasticsearchインデックスクリーナージョブ

elasticsearchストレージを使用する場合、デフォルトでcronジョブが作成され、古いトレースがクリーンアップされます。そのオプションを以下に示しますので、ユースケースに合わせて構成できます。接続構成はストレージオプションから取得されます。

storage:
  type: elasticsearch
  esIndexCleaner:
    enabled: true                                 // turn the cron job deployment on and off
    numberOfDays: 7                               // number of days to wait before deleting a record
    schedule: "55 23 * * *"                       // cron expression for it to run

ストレージへの接続構成は、ストレージオプションから取得されます。

Elasticsearchロールオーバー

このインデックス管理戦略は、デフォルトの日次インデックスを使用するよりも複雑で、ストレージの準備のための初期化ジョブと、インデックスを管理するための2つのcronジョブが必要です。最初のcronジョブは新しいインデックスへのロールオーバーに使用され、2番目のcronジョブは読み取りエイリアスからのインデックスの削除に使用されます。ロールオーバー機能は、ストレージオプションes.use-aliasesが有効になっている場合に使用されます。

Jaegerにおけるロールオーバーインデックス管理の詳細については、この記事external link を参照してください。

storage:
  type: elasticsearch
  options:
    es:
      use-aliases: true
  esRollover:
    conditions: "{\"max_age\": \"2d\"}"          // conditions when to rollover to a new index
    readTTL: 168h                                // how long should be old data available for reading (7 days)
    schedule: "55 23 * * *"                      // cron expression for it to run

ストレージへの接続構成は、ストレージオプションから取得されます。

Elasticsearchインデックスライフサイクル管理

インデックスライフサイクル管理external link (ILM)は、インデックスのライフサイクルを管理するX-PackプラグインからのElasticsearch機能です。Operatorのコンテキストでは、ILMをロールオーバーcronジョブの代わりに使用できることを意味します。JaegerプロジェクトはILMとの直接的な統合を提供しませんが、Jaegerインスタンスはインデックスエイリアス(ILMで必要)を使用するように構成し、インデックステンプレートの作成とロールオーバーcronジョブを無効にすることができます。これにより、ユーザーはJaegerをデプロイする前に、カスタムインデックステンプレートでILMを構成できます。

spec:
  strategy: production
  collector:
    options:
      es:
        use-aliases: true # <1>
  query:
    options:
      es:
        use-aliases: true  # <1>
  storage:
    type: elasticsearch
    options:
      es:
        create-index-templates: false  # <2>
        server-urls: http://elasticsearch:9200

<1> 読み取りおよび書き込みインデックスエイリアスを使用するようにjaeger-queryjaeger-collectorを構成します。

<2> デフォルトのインデックステンプレートの作成を無効にします。

ストレージプラグイン

v1.58以降、サイドカープラグインはサポートされません。カスタムストレージバックエンドはRemote Storage APIに移行する必要があります。

メトリクスストレージオプション

Prometheus

spec.metricsStorage.typeprometheusに設定すると、サービスパフォーマンスモニタリング機能のjaeger-query R.E.Dメトリクスに対して、PromQL互換のストレージ実装を使用してJaegerを使用できます。

以下は、allInOneデプロイメント戦略、インメモリのスパンストレージ、およびプロメテウスメトリクスストレージを使用するJaeger CRの例です。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: jaeger-spm
spec:
  strategy: allInOne
  allInOne:
    image: jaegertracing/all-in-one:latest
    options:
      log-level: debug
      query:
        base-path: /jaeger
      prometheus: # <1>
        server-url: "http://prometheus:9090" # <2>
    metricsStorage: # <3>
      type: prometheus # <4>
  storage:
    options:
      memory:
        max-traces: 100000

<1> prometheus名前空間の構成の開始。単純なkey: valueマップとして定義されます。使用可能なすべてのオプションについては、Jaeger All-In-One with Prometheus CLIセクションに記載されています。

<2> デフォルトのhttp://localhost:9090プロメテウスサーバーURLをhttp://prometheus:9090でオーバーライドします。

<3> メトリクスのクエリ機能を有効にするセクション。

<4> メトリクスストレージバックエンドとしてprometheusを選択します。

依存関係の導出

依存関係を導出する処理は、ストレージからスパンを収集し、サービス間のリンクを分析して、後でUIに表示するために保存します。このジョブは、production戦略とストレージタイプcassandraまたはelasticsearchでのみ使用できます。

storage:
  type: elasticsearch
  dependencies:
    enabled: true                                 # turn the job deployment on and off
    schedule: "55 23 * * *"                       # cron expression for it to run
    sparkMaster:                                  # spark master connection string, when empty spark runs in embedded local mode
    resources:
      requests:
        memory: 4096Mi
      limits:
        memory: 4096Mi

ストレージへの接続構成は、ストレージオプションから取得されます。

十分なメモリリソースを割り当ててください。Sparkのドキュメントexternal link では、少なくとも8Giのメモリを推奨しています。ただし、このジョブは少なくとも2Giのメモリで開始できます。適切なメモリ設定は、処理されるデータ量によって異なります。このジョブは、当日のすべてのデータをメモリに読み込むことに注意してください。

Jaeger Agentサイドカーの自動注入

現在、jaeger-agentサイドカーの自動注入はDeploymentsのみサポートされています。

他のコントローラータイプについては、以下のJaeger Agentサイドカーの手動定義を参照してください。

他のコントローラータイプの自動注入のサポートは、Issue #750external link で追跡されています。

オペレーターは、デプロイメントまたはその名前空間に適切な値を持つ注釈sidecar.jaegertracing.io/injectがある場合、Deploymentワークロードにjaeger-agentサイドカーを注入できます。値は"true"(文字列として)、またはkubectl get jaegersによって返されるJaegerインスタンス名にすることができます。"true"を使用する場合、デプロイメントと同じ名前空間にJaegerインスタンスが1つだけ存在する必要があります。そうでない場合、オペレーターは自動的にどのJaegerインスタンスを使用するかを判断できません。デプロイメント上の特定のJaegerインスタンス名は、その名前空間に適用されるtrueよりも優先されます。

次のスニペットは、同じ名前空間で使用可能な単一のJaegerインスタンスを指すjaeger-agentが注入されたサイドカーを取得する単純なアプリケーションを示しています。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  annotations:
    "sidecar.jaegertracing.io/inject": "true" # <1>
spec:
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: acme/myapp:myversion

<1> "true"(文字列として)またはJaegerインスタンス名。

完全なサンプルデプロイメントは、deploy/examples/business-application-injected-sidecar.yamlexternal link にあります。

サイドカーが注入されると、jaeger-agentlocalhostのデフォルトの場所からアクセスできます。

注入されたサイドカーのデプロイメントレベルの構成

サイドカーはjaeger-operatorによって管理されていないデプロイメントに注入される可能性があるため、デプロイメントレベルで適用される多くの構成は、jaeger-agentノードの下で指定されていない限り、サイドカーのデプロイメントには適用されません。サイドカーのデプロイメントに対して次の構成がサポートされています。

  • ボリューム(およびVolumeMounts)
  • ImagePullSecrets

たとえば、次のJaeger構成により、agent-volumeagent-imagePullSecretsがサイドカーのデプロイメントに追加されます。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: my-jaeger
spec:
  agent:
    volumeMounts:
    - name: agent-volume
      mountPath: /tmp/agent
      readOnly: true
    volumes:
      - name: agent-volume
        secret:
          secretName: agent-secret
    imagePullSecrets:
    - name: agent-imagePullSecret

Jaeger Agentサイドカーの手動定義

Deployments以外のコンテナタイプ(例:StatefulSetsDaemonSetsなど)の場合、jaeger-agentサイドカーは仕様に手動で定義できます。

次のスニペットは、jaeger-agentサイドカーのcontainersセクションに含めることができる手動定義を示しています。

- name: jaeger-agent
  image: jaegertracing/jaeger-agent:latest
  imagePullPolicy: IfNotPresent
  ports:
    - containerPort: 5775
      name: zk-compact-thrift
      protocol: UDP
    - containerPort: 5778
      name: config-rest
      protocol: TCP
    - containerPort: 6831
      name: jg-compact-thrift
      protocol: UDP
    - containerPort: 6832
      name: jg-binary-thrift
      protocol: UDP
    - containerPort: 14271
      name: admin-http
      protocol: TCP
  args:
    - --reporter.grpc.host-port=dns:///jaeger-collector-headless.observability:14250
    - --reporter.type=grpc

完全なサンプルStatefulSetは、deploy/examples/statefulset-manual-sidecar.yamlexternal link にあります。

jaeger-agentlocalhostのデフォルトの場所からアクセスできます。

AgentのDaemonSetとしてのインストール

デフォルトでは、Operatorはjaeger-agentがターゲットアプリケーションのサイドカーとしてデプロイされることを想定しています。これは、マルチテナントシナリオやロードバランシングの向上など、いくつかの目的に便利ですが、jaeger-agentDaemonSetとしてインストールしたいシナリオもあります。その場合、jaeger-agentの戦略を次のようにDaemonSetに指定します。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: my-jaeger
spec:
  agent:
    strategy: DaemonSet
戦略としてDaemonSetを使用して、同じクラスタに2つのJaegerインスタンスをインストールしようとすると、エージェントはノード上の既知のポートにバインドする必要があるため、1つだけがDaemonSetをデプロイすることになります。そのため、2番目のデーモンセットはこれらのポートへのバインドに失敗します。

次に、トレーサークライアントは、jaeger-agentの場所を知らせる必要があるでしょう。これは通常、環境変数JAEGER_AGENT_HOSTをKubernetesノードのIPの値(例:)に設定して行います。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: acme/myapp:myversion
        env:
        - name: JAEGER_AGENT_HOST
          valueFrom:
            fieldRef:
              fieldPath: status.hostIP

OpenShift

OpenShiftでは、特別なセキュリティコンテキストが設定されている場合にのみHostPortを設定できます。次の例のように、HostPortにバインドする権限を持つjaeger-agentによって、別のサービスアカウントを使用できます。

oc create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/main/examples/openshift/hostport-scc-daemonset.yaml # <1>
oc new-project myproject
oc create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/main/examples/openshift/service_account_jaeger-agent-daemonset.yaml # <2>
oc adm policy add-scc-to-user daemonset-with-hostport -z jaeger-agent-daemonset # <3>
oc apply -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/main/examples/openshift/agent-as-daemonset.yaml # <4>

<1> allowHostPortsポリシーを持つSecurityContextConstraints

<2> jaeger-agentで使用されるServiceAccount

<3> セキュリティポリシーをサービスアカウントに追加します。

<4> 上記の手順で作成したserviceAccountを使用してJaegerインスタンスを作成します。

このようなポリシーがない場合、次のようなエラーが発生し、DaemonSetの作成が妨げられます。Warning FailedCreate 4s (x14 over 45s) daemonset-controller Error creating: pods "agent-as-daemonset-agent-daemonset-" is forbidden: unable to validate against any security context constraint: [spec.containers[0].securityContext.containers[0].hostPort: Invalid value: 5775: Host ports are not allowed to be used

数秒後、DaemonSetが稼働状態になるはずです。

$ oc get daemonset agent-as-daemonset-agent-daemonset
NAME                                 DESIRED   CURRENT   READY     UP-TO-DATE   AVAILABLE
agent-as-daemonset-agent-daemonset   1         1         1         1            1

Calico CNI

カスタムCalico CNI Webhookをサービスにポイントするように設定したAWS EKS(またはFargate)で、サービスに接続できません。

jaegerリソースが要求されたときに、以下のエラーが表示されます。

Error from server (InternalError): Internal error occurred: failed calling webhook "myservice.mynamespace.svc": Post "https://myservice.mynamespace.svc:443/mutate?timeout=30s": Address is not allowed

この問題を回避するために

  • jaeger-operatorデプロイメントでhostNetwork:trueを設定します。
  • /healtzおよび/readyzポートを8081から別の値に変更します。
  • kube-rbac-proxyのセキュアポートを8443から別の値に変更します。
  • webhook-serverポートを9443から別の値に変更します。
    • この設定は、webhook-bind-portフラグで制御されます。

Jaeger operatorの設定例

---
apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: jaeger-operator
    name: jaeger-operator
  name: jaeger-operator-webhook-service
  namespace: monitoring
spec:
  ports:
  - port: 443
    protocol: TCP
    targetPort: 10290
  selector:
    app.kubernetes.io/name: jaeger-operator
    name: jaeger-operator
---
...
    spec:
      hostNetwork: true
      containers:
      - args:
        - start
        - --health-probe-bind-address=:10280
        - --webhook-bind-port=10290
        - --leader-elect
        command:
        - /jaeger-operator
      ...
      ports:
        - containerPort: 10290
          name: webhook-server
          protocol: TCP
      ...
      readinessProbe:
          httpGet:
            path: /readyz
            port: 10280
      ...
      livenessProbe:
          httpGet:
            path: /healthz
            port: 10280

Kube-rbac-proxyの設定例

---
apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/component: metrics
    app.kubernetes.io/name: jaeger-operator
    name: jaeger-operator
  name: jaeger-operator-metrics
  namespace: monitoring
spec:
  ports:
  - name: https
    port: 10270
    protocol: TCP
    targetPort: https
  selector:
    app.kubernetes.io/name: jaeger-operator
    name: jaeger-operator
---
...
    spec:
      hostNetwork: true
      containers:
      - args:
        - --secure-listen-address=0.0.0.0:10270
        - --upstream=http://127.0.0.1:8383/
        - --logtostderr=true
        - --v=0
      ...
      ports:
        - containerPort: 10270
          name: https
          protocol: TCP
上記のポート値はグローバルに一意である必要があります。そのため、jaeger-operatorポートはすべてのKubernetesノードで公開できます。

シークレットのサポート

Operatorは、jaeger-collectorjaeger-query、およびall-in-oneデプロイメントにシークレットを渡すことをサポートしています。これは、例えば、基盤となるストレージバックエンド(Elasticsearchなど)へのアクセスのための資格情報(ユーザー名/パスワード)を渡すために使用できます。シークレットは、(Collector/Query/All-In-One)ノードの環境変数として使用できます。

    storage:
      type: elasticsearch
      options:
        es:
          server-urls: http://elasticsearch:9200
      secretName: jaeger-secrets

シークレット自体は、jaeger-operatorカスタムリソースの外で管理されます。

UIの設定

UIのさまざまな設定オプションに関する情報は、こちら(JSON形式で定義されています)にあります。

カスタムリソース内でUI設定の変更を適用するには、以下に示すようにYAML形式で同じ情報を含めることができます。

    ui:
      options:
        dependencies:
          menuEnabled: false
        tracking:
          gaID: UA-000000-2
        menu:
        - label: "About Jaeger"
          items:
            - label: "Documentation"
              url: "https://jaeger.dokyumento.jp/docs/latest"
        linkPatterns:
        - type: "logs"
          key: "customer_id"
          url: /search?limit=20&lookback=1h&service=frontend&tags=%7B%22customer_id%22%3A%22#{customer_id}%22%7D
          text: "Search for other traces for customer_id=#{customer_id}"

サンプリング戦略の定義

トレースがIstioプロキシによって開始された場合、サンプリングの決定はそのプロキシで行われるため、これは関係ありません。Jaegerのサンプリング決定は、Jaegerトレーサー(クライアント)を使用している場合にのみ関係します。

Operatorを使用して、リモートサンプラーを使用するように構成されたトレーサーに提供されるサンプリング戦略を定義できます。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: with-sampling
spec:
  strategy: allInOne
  sampling:
    options:
      default_strategy:
        type: probabilistic
        param: 0.5

この例では、トレースインスタンスがサンプリングされる確率が50%である確率的サンプリング戦略をデフォルトで定義しています。

コレクターサンプリング設定external link のJaegerドキュメントを参照して、サービスとエンドポイントのサンプリングをどのように構成できるかを確認してください。そのドキュメントで説明されているJSON表現は、YAMLに変換することでOperatorで使用できます。

より詳細な設定

カスタムリソースを使用して、すべてのJaegerコンポーネント、または個々のコンポーネントレベルに適用される、より詳細なKubernetes設定を定義できます。

共通の定義(すべてのJaegerコンポーネント用)が必要な場合は、specノードで定義します。定義が個々のコンポーネントに関連する場合は、spec/<component>ノードに配置します。

サポートされている設定の種類には、以下が含まれます。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: simple-prod
spec:
  strategy: production
  storage:
    type: elasticsearch
    options:
      es:
        server-urls: http://elasticsearch:9200
  annotations:
    key1: value1
  labels:
    key2: value2
  resources:
    requests:
      memory: "64Mi"
      cpu: "250m"
    limits:
      memory: "128Mi"
      cpu: "500m"
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/e2e-az-name
            operator: In
            values:
            - e2e-az1
            - e2e-az2
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: another-node-label-key
            operator: In
            values:
            - another-node-label-value
  tolerations:
    - key: "key1"
      operator: "Equal"
      value: "value1"
      effect: "NoSchedule"
    - key: "key1"
      operator: "Equal"
      value: "value1"
      effect: "NoExecute"
  serviceAccount: nameOfServiceAccount
  securityContext:
    runAsUser: 1000
  volumeMounts:
    - name: config-vol
      mountPath: /etc/config
  volumes:
    - name: config-vol
      configMap:
        name: log-config
        items:
          - key: log_level
            path: log_level

注:必要に応じて、imagePullSecretsをサービスアカウントを介してコンポーネントに対して構成できます(https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-image-pull-secret-to-service-accountを参照)。サイドカーについては、「インジェクションされたサイドカーのデプロイメントレベルの設定」セクションを参照してください。

Jaegerコンソール(UI)へのアクセス

Kubernetes

Operatorは、Kubernetes ingressexternal link ルートを作成します。これは、サービスを外部世界に公開するためのKubernetesの標準ですが、デフォルトではIngressプロバイダーが付属していません。Kubernetesドキュメントで、プラットフォームに最適なIngressプロバイダーを実現する方法を確認してください。以下のコマンドは、minikubeでIngressプロバイダーを有効にします。

minikube addons enable ingress

Ingressが有効になったら、Ingressオブジェクトを照会することでJaegerコンソールのアドレスを確認できます。

$ kubectl get ingress
NAME             HOSTS     ADDRESS          PORTS     AGE
simplest-query   *         192.168.122.34   80        3m

この例では、Jaeger UI は http://192.168.122.34 で利用可能です。

Ingress で TLS を有効にするには、TLS 証明書を含むSecretexternal link の名前を指定したsecretNameを渡します。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: ingress-with-tls
spec:
  ingress:
    secretName: my-tls-secret

OpenShift

Operator が OpenShift 上で実行されている場合、Operator はクエリサービスのRouteオブジェクトを自動的に作成します。ホスト名/ポートを確認するには、次のコマンドを使用します。

oc get routes
上記のコマンドから取得したホスト名/ポートには必ずhttpsを使用してください。それ以外の場合は、「アプリケーションを利用できません」のようなメッセージが表示されます。

デフォルトでは、Jaeger UI は OpenShift の OAuth サービスで保護されており、有効なユーザーであれば誰でもログインできます。この機能を無効にして Jaeger UI を無保護にするには、カスタムリソースファイルで Ingress プロパティsecuritynoneに設定します。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: disable-oauth-proxy
spec:
  ingress:
    security: none

カスタムSARDelegate URLの値は、以下のように.Spec.Ingress.OpenShift.SAR.Spec.Ingress.Openshift.DelegateURLsの一部として指定できます。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: custom-sar-oauth-proxy
spec:
  ingress:
    openshift:
      sar: '{"namespace": "default", "resource": "pods", "verb": "get"}'
      delegateUrls: '{"/":{"namespace": "default", "resource": "pods", "verb": "get"}}'

delegateUrlsが設定されている場合、Jaeger Operator は、UI プロキシ({InstanceName}-ui-proxy)で使用されるサービスアカウントとロールsystem:auth-delegatorの間に新しいClusterRoleBindingを作成する必要があります(OpenShift OAuth プロキシで必要)。そのため、Operator 自体で使用されるサービスアカウントにも、同じクラスタロールバインディングが必要です。そのためには、次のようなClusterRoleBindingを作成する必要があります。

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: jaeger-operator-with-auth-delegator
  namespace: observability
subjects:
- kind: ServiceAccount
  name: jaeger-operator
  namespace: observability
roleRef:
  kind: ClusterRole
  name: system:auth-delegator
  apiGroup: rbac.authorization.k8s.io

ユーザーがこのクラスタロールを使用して Jaeger インスタンスをデプロイすることを許可することに抵抗のあるクラスタ管理者は、このクラスタロールをオペレーターのサービスアカウントに追加しないようにすることができます。その場合、Operator は必要な権限がないことを自動的に検出し、次のようなメッセージをログに出力します。the requested instance specifies the delegateUrls option for the OAuth Proxy, but this operator cannot assign the proper cluster role to it (system:auth-delegator). Create a cluster role binding between the operator's service account and the cluster role 'system:auth-delegator' in order to allow instances to use 'delegateUrls'

Jaeger Operator は、OpenShift OAuth プロキシを介してhtpasswdファイルを使用した認証もサポートしています。それを利用するには、OpenShift固有のエントリ内でhtpasswdFileオプションを指定し、ローカルディスク上のhtpasswdファイルの場所を指定します。htpasswdファイルはhtpasswdユーティリティを使用して作成できます。

$ htpasswd -cs /tmp/htpasswd jdoe
New password:
Re-type new password:
Adding password for user jdoe

このファイルは、kubectl create secretコマンドの入力として使用できます。

$ kubectl create secret generic htpasswd --from-file=htpasswd=/tmp/htpasswd
secret/htpasswd created

シークレットが作成されると、Jaeger CR でボリューム/ボリュームマウントとして指定できます。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: with-htpasswd
spec:
  ingress:
    openshift:
      sar: '{"namespace": "default", "resource": "pods", "verb": "get"}'
      htpasswdFile: /usr/local/data/htpasswd
  volumeMounts:
  - name: htpasswd-volume
    mountPath: /usr/local/data
  volumes:
  - name: htpasswd-volume
    secret:
      secretName: htpasswd

Operator とその管理対象インスタンスのアップグレード

Jaeger Operator の各バージョンは、1 つの Jaeger バージョンに従います。新しいバージョンの Jaeger Operator がインストールされると、オペレーターによって管理されるすべての Jaeger インスタンスは、Operator がサポートするバージョンにアップグレードされます。たとえば、Jaeger Operator 1.12.0 で作成されたsimplestという名前のインスタンスは、Jaeger 1.12.0 を実行しています。Jaeger Operator が 1.13.0 にアップグレードされると、インスタンスsimplestは Jaeger プロジェクトの公式アップグレード手順に従って 1.13.0 バージョンにアップグレードされます。

Jaeger Operator は、デプロイメントの変更(kubectl edit deployment jaeger-operator)またはOperator Lifecycle Manager (OLM)external link などの専門ツールを使用して手動でアップグレードできます。

Jaeger インスタンスの更新(実験的)

Jaeger インスタンスは、simplestが Jaeger のインスタンス名であるkubectl edit jaeger simplestを介して、またはkubectl apply -f simplest.yamlを介して更新された YAML ファイルを適用することにより、CustomResourceを変更することで更新できます。

Jaeger インスタンスの名前は、リソースの識別情報の一部であるため、更新できません。

レプリカサイズの変更など、単純な変更はそれほど問題なく適用できますが、戦略の変更は注意深く監視する必要があり、個々のコンポーネント(コレクター/クエリ/エージェント)の停止につながる可能性があります。

バックアップストレージの変更はサポートされていますが、データの移行はサポートされていません。

Jaeger インスタンスの削除

インスタンスを削除するには、インスタンスの作成時に使用したカスタムリソースファイルを使用してdeleteコマンドを使用します。

kubectl delete -f simplest.yaml

または、次を実行して Jaeger インスタンスを削除することもできます。

kubectl delete jaeger simplest
インスタンスを削除しても、このインスタンスで使用されている永続ストレージからデータは削除されません。ただし、インメモリインスタンスのデータは失われます。

Operator のトレースとデバッグ

バージョン 1.16.0 以降、Jaeger Operator は独自の操作に関連するスパンを生成できます。それを利用するには、コンテナのargsにフラグ--tracing-enabled=trueを設定し、Jaeger Agent をポッドのサイドカーとして追加することで、operator.yamlでトレースを有効にする必要があります。これは、トレースが有効になっており、Jaeger インスタンスが Jaeger Operator と同じ名前空間に存在することを前提としたoperator.yamlの抜粋です。

...
        # .Spec.Template.Spec.Containers[0].Args
        args: ["start", "--tracing-enabled=true"]
...
      # add as a second container to .Spec.Template.Spec.Containers
      - name: jaeger-agent
        image: jaegertracing/jaeger-agent:latest # it's best to keep this version in sync with the operator's
        env:
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        args:
        - --reporter.grpc.host-port=dns:///jaeger-collector-headless.$(POD_NAMESPACE).svc.cluster.local:14250
        ports:
        - containerPort: 6831
          name: jg-compact-thrift
          protocol: UDP

Jaeger インスタンスを手動でプロビジョニングする必要があることにも注意してください。これは、Jaeger Operator が初期化された後に行うことができます。jaeger-agentは、Jaeger インスタンスへの接続が確立されるまで、Operator スパンを内部バッファーに保持します。非本番環境に適した Jaeger インスタンスをプロビジョニングするには、次の Jaeger CR を使用できます。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: jaeger

フラグ--log-leveldebugに設定されている場合、Jaeger Operator は広範なログを提供します。これは、ログレベルがデバッグに設定されているoperator.yamlの抜粋です。

        # .Spec.Template.Spec.Containers[0].Args
        args: ["start", "--log-level=debug"]

デバッグレベルでのトレースとロギングは、同時に有効にすることができます。

OLM を使用する場合、Subscriptionconfigプロパティを変更することで Jaeger Operator を構成できます。log-levelパラメーターを設定するには、サブスクリプションは次のようになります(抜粋)。

apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: jaeger
  namespace: openshift-operators
spec:
  channel: stable
  config:
    env:
      - name: LOG-LEVEL
        value: debug
  installPlanApproval: Automatic
  name: jaeger
  source: community-operators
  sourceNamespace: openshift-marketplace

Operator の監視

Jaeger Operator は、プロセスを監視するために使用できる内部メトリックを含む、0.0.0.0:8383/metricsで Prometheus と互換性のあるエンドポイントを開始します。監視する重要なメトリックは次のとおりです。

# Total number of reconciliations and their outcomes (cumulative)
controller_runtime_reconcile_total{controller="jaeger-controller",result="error"}
controller_runtime_reconcile_total{controller="jaeger-controller",result="success"}

# Total number of retries (cumulative)
workqueue_retries_total{name="jaeger-controller"}

# Current number of reconciliation loops in progress (gauge)
workqueue_depth{name="jaeger-controller"}

# How long (in seconds) the oldest reconciliation loop is taking. (gauge)
workqueue_unfinished_work_seconds{name="jaeger-controller"}

# How long (in seconds) it takes to process an item from the workqueue. (bucket)
workqueue_work_duration_seconds_bucket{name="jaeger-controller"}

調整エラーの数が少ないのは正常です(controller_runtime_reconcile_total{controller="jaeger-controller",result="error"})。さまざまな理由で同時にリソースを変更するプロセスがいくつかある可能性があるためです。失敗が発生すると、オペレーターは再度調整を試み、workqueue_retries_total{name="jaeger-controller"}メトリックが増加します。ただし、時間の経過とともにエラー率が増加し続ける場合、または妥当なしきい値を超える場合は、調査が必要になる可能性があります。妥当なしきい値は、クラスタで何が起こっているかによってクラスタごとに異なる可能性がありますが、10%が適切な出発点です。

v1.17.0 以降、Jaeger Operator は、カスタムリソースが変更された場合、または前の調整が失敗した場合にのみ、調整ループをトリガーします。したがって、このメトリック(controller_runtime_reconcile_total{controller="jaeger-controller"})が長い間同じ値を持つことは正常です。これは、カスタムリソースが変更されていないことを示すだけです。この数値が毎秒変化し続ける場合は、クラスタ内の何かが定期的にカスタムリソースを変更しているか、Jaeger Operator が別のコンポーネントによって行われている変更を元に戻していることを示しています。将来のバージョンの Jaeger Operator は、定期的な調整ループをトリガーする可能性があります。

作業キューの深さ(workqueue_depth{name="jaeger-controller"})は、現在アクティブな調整ループの数を示します。小規模なクラスタ、または Jaeger インスタンスのプロビジョニングがあまり頻繁ではないクラスタでは、この数値はほとんどの場合 0 の近くに留まります。長時間にわたって 0 よりも大きい値は、スタックした調整ループを示しています。そのような場合、メトリックworkqueue_unfinished_work_seconds{name="jaeger-controller"}も継続的に増加します。この状況は、Jaeger Operator のバグを示しています。経験則として、Elasticsearch または Kafka のプロビジョニングが関係する場合を除き、調整は数分以内に終了する必要があります。10 分以上かかる調整ループは、「スタック」していると見なすことができます。Elasticsearch または Kafka のプロビジョニングには数分かかる場合があります。通常の場合、調整ループは 1 分未満で完了します。

作業キューのバケット(workqueue_unfinished_work_seconds{name="jaeger-controller"}workqueue_work_duration_seconds_bucket{name="jaeger-controller"})は、各調整ループの処理に費やされた時間に直接関係しています。新しい Jaeger インスタンスの最初の 3 つのループのいずれかが、後続のループよりもはるかに多くの時間を要することは正常です。特に、基礎となるコンポーネントのコンテナーイメージがまだクラスタによってキャッシュされていない場合です。Elasticsearch および/または Kafka クラスタを作成するための自動プロビジョニング機能を使用すると、このメトリックにも影響します。一般的なルールは次のとおりです。特に、メトリックcontroller_runtime_reconcile_total{controller="jaeger-controller"}が増加したのと同じ頃に発生する場合、いくつかの長時間実行される調整ループは正常です。

Jaeger Operator はまだ独自のメトリックを公開していません。代わりに、Operator SDK など、使用するコンポーネントによって報告されるメトリックを使用できます。

Operator のアンインストール

Operator をアンインストールするには、次のコマンドを実行します。

kubectl delete -n observability -f https://github.com/jaegertracing/jaeger-operator/releases/download/v1.62.0.0/jaeger-operator.yaml