コンテンツにスキップ

Istio@サービスメッシュ系ミドルウェア

はじめに

本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。


01. Istio の仕組み

項目 サイドカーモード アンビエントモード
Node のハードウェアリソース消費量 × ⭕️
Node のストレージ使用量 ⭕️
Envoy の冗長性 ⭕️️
マイクロサービスごとの Envoy の設定カスタマイズ ⭕️
単純性 × ⭕️
Istio のアップグレード インプレースアップグレード、カナリアアップグレード DaemonSet のローリングアップデート


01-02. 拡張性設計

コントロールプレーンの性能設計

▼ CPU

  • デプロイ頻度
  • 設定変更頻度
  • istio-proxy 数
  • サービスメッシュのスコープ
  • コントロールプレーンの冗長化数


データプレーンの性能設計

▼ CPU を消費する処理

メモリと同じように、以下の情報によって、データプレーンで必要な CPU が変わる。

  • istio-proxy 内の Envoy プロセスのスレッド数。スレッドが多くなるほど、これに紐づく CPU が必要になる。
  • istio-proxy 内の Envoy プロセスが作成するテレメトリー (ログ、メトリクス、分散トレース) のデータサイズ
  • リクエストやレスポンスのデータサイズ
  • 送信元の接続数
  • など...

▼ メモリを消費する処理

CPU と同じように、以下の情報によって、データプレーンで必要なメモリが変わる。

  • istio-proxy 内の Envoy プロセスのスレッド数。スレッドが多くなるほど、これに紐づく CPU が必要になる。
  • istio-proxy 内の Envoy プロセスが作成するテレメトリー (ログ、メトリクス、分散トレース) のデータサイズ
  • リクエストやレスポンスのデータサイズ
  • 送信元の接続数
  • など...

特に以下でメモリが必要になる。

  • istio-proxy 内の Envoy プロセスが持つ宛先情報量

▼ サービスメッシュ有無による違い

サービスメッシュ有無によって、ハードウェアリソース消費量に違いがある。

Istio のドキュメントでは、以下のハードウェアリソースを消費することが記載されている。

1000 rps/s の場合である。

CPU メモリ
istio-proxy 0.2 vCPU 60 Mi
waypoint-proxy のコンテナ 0.25 vCPU 60 Mi
ztunnel のコンテナ 0.06 vCPU 12 Mi

istio-proxy をインジェクションすると、Pod あたりで以下のハードウェアリソースが増える調査結果も出ている。

  • CPU:0.0002 vCPU 〜0.0003 vCPU
  • メモリ:40 Mi 〜 50 Mi
Pod CPU (導入前) CPU (導入後) メモリ (導入前) メモリ (導入後)
Nginx 0 vCPU 0.0003 vCPU 2 Mi 47 Mi
Database 0.0001 vCPU 0.0003 vCPU 29 Mi 76 Mi
サービス A 0.0001 vCPU 0.0004 vCPU 237 Mi 220 Mi
サービス B 0.0002 vCPU 0.0004 vCPU 219 Mi 288 Mi
サービス C 0.0002 vCPU 0.0004 vCPU 253 Mi 270 Mi
サービス D 0.0002 vCPU 0.0004 vCPU 28 Mi 73 Mi
サービス E 0.0004 vCPU 0.0007 vCPU 35 Mi 78 Mi
サービス F 0.0002 vCPU 0.0004 vCPU 230 Mi 270 Mi
サービス G 0.0003 vCPU 0.0006 vCPU 30 Mi 75 Mi
サービス H 0.0002 vCPU 0.0004 vCPU 393 Mi 311 Mi
サービス I 0.0001 vCPU 0.0004 vCPU 322 Mi 411 Mi
合計 0.0020 vCPU 0.0047 vCPU 1778 Mi 2119 Mi


レイテンシー (≒レスポンスタイム) の大きさ

▼ レイテンシーを大きくする処理

以下により、レイテンシーは大きくなる。

  • istio-proxy、waypoint-proxy のコンテナ、ztunnel のコンテナの経由
  • AuthorizationPolicy によるアクセストークンの検証
  • PeerAuthentication による相互 TLS 認証

▼ サービスメッシュ有無による違い

p99、1000 rps/s、240 秒間の負荷の場合である。

条件 レイテンシー
both (送信元/宛先 istio-proxy の両方) 約 28 ms
serveronly (宛先 istio-proxy のみ) 約 13 ms
baseline (istio-proxy なし) 約 3 ms

istio_sidecar-mode_latency

▼ モードによる違い


02. サイドカーモード

Istio のサイドカーモードとは

サイドカーモードは、サイドカープロキシ型のサービスメッシュを実装したものである。

各 Pod にサイドカーとして Envoy を稼働させ、これが各マイクロサービスのインフラ領域の責務をに担う。


03. アンビエントモード (サイドカーレスパターン)

アンビエントモードとは

アンビエントモードは、サイドカーレスパターンのサービスメッシュを実装したものである。

各 Node 上にエージェントとして Envoy を稼働させ、これが各マイクロサービスのインフラ領域の責務をに担う。


03. トラフィック管理

ネットワークレイヤー

L3/L4/L7 に対応している。

ただし、Cilium サービスメッシュとは異なり、L3 の設定をユーザーは変更できない。

パケット処理の仕組み

  1. istio-proxy にて、リスナーでリクエストを受信する。
  2. EnvoyFilter があれば、これをリスナーフィルターとして Envoy に適用する。
  3. ルートでリクエストを受け取る。
  4. クラスターでリクエストを受け取る。
  5. クラスター配下のエンドポイントにリクエストを送信する。


サービスメッシュ内では kube-proxy は不要

実は、サービスメッシュ内の Pod 間通信では、kube-proxy は使用しない。

istio-init コンテナは、istio-iptables コマンドを実行し、iptables のルールを書き換える。

これにより、送信元 Pod から宛先 Pod へ直接通信できるようになる。


03-02. サービスメッシュ外へのリクエスト送信

安全な通信方式

▼ 任意の外部システムに送信できるようにする

サービスメッシュ内のマイクロサービスから、istio-proxy (マイクロサービスのサイドカーと Istio Egress Gateway の両方) を経由して、任意の外部システムにリクエストを送信できるようにする。

外部システムは識別できない。

▼ 登録した外部システムに送信できるようにする

サービスメッシュ内のマイクロサービスから、istio-proxy (マイクロサービスのサイドカーと Istio Egress Gateway の両方) を経由して、ServiceEntry で登録した外部システムにリクエストを送信できるようにする。

外部システムを識別できる。


安全ではない通信方式

▼ 登録した外部システムに送信できるようにする

サービスメッシュ内のマイクロサービスから、istio-proxy (マイクロサービスのサイドカーのみ) を経由して、任意の外部システムにリクエストを送信できるようにする。

外部システムは識別できない。

▼ istio-proxy を経由せずに送信できるようにする

サービスメッシュ内のマイクロサービスから、istio-proxy を経由せずに、外部システムにリクエストを送信できるようにする。


外部システムの種類

PassthroughCluster

定義されていないが通信が許可されているサービスメッシュ外の送信元 (InPassthroughCluster) /宛先 (OutboundPassthroughCluster) のこと。

Istio v1.3 以降で、デフォルトですべてのサービスメッシュ外へのリクエストのポリシーが ALLOW_ANY となり、PassthroughCluster として扱うようになった。

ServiceEntry を使用すれば、名前をつけられる。

注意点として、REGISTRY_ONLY モードを有効化すると、ServiceEntry で登録された宛先以外のサービスメッシュ外への全通信が BlackHoleCluster 扱いになってしまう。

BlackHoleCluster

IP アドレスを指定して送信できない宛先のこと。

基本的に、サービスメッシュ外へのリクエストは失敗し、502 ステータスになる (502 Bad Gateway)。


04. 回復性の管理

フォールトインジェクション

▼ フォールトインジェクションとは

ランダムな障害を意図的にインジェクションし、サービスメッシュの動作を検証する。

▼ テストの種類

テスト名 内容
Delay インジェクション マイクロサービスに対するインバウンド通信にて、意図的に通信の遅延を発生させる。<br>https://istio.io/latest/docs/tasks/traffic-management/fault-injection/#injecting-an-http-delay-fault
Abort インジェクション マイクロサービスに対するインバウンド通信にて、意図的に通信の中止を発生させる。<br>https://istio.io/latest/docs/tasks/traffic-management/fault-injection/#injecting-an-http-abort-fault

▼ サーキットブレイカー

istio-proxy でサーキットブレイカーを実現する。

ただし、サーキットブレイカー後のフォールバックは istoi-proxy コンテナでは実装できず、マイクロサービスで実装する必要がある。

istio-proxy は、送信可能な宛先がなくなると 503 レスポンスを返信する。

Envoy は以下の機能を持っている。

  • Envoy では、接続プールの上限を条件として、サーキットブレイカーを発動する
  • Envoy では、ステータスコードの外れ値を条件として、ロードバランシングで異常なホストを排除する

Istio では、外れ値の排除率を 100%とすることで、ステータスコードもサーキットブレイカーの条件にできる。

  • Istio では、接続プールの上限を条件として、サーキットブレイカーを発動する
  • Istio では、ステータスコードの外れ値を条件を 100%とすることにより、サーキットブレイカーを発動する


ヘルスチェック

▼ アクティブヘルスチェック

istio-proxy は、マイクロサービスに対する kubelet のヘルスチェックを受信し、マイクロサービスに転送する。


05. 通信の認証/認可

通信の認証

▼ 仕組み

Pod 間通信時、正しい送信元 Envoy の通信であることを認証する。

▼ 相互 TLS 認証

相互 TLS 認証を実施し、送信元 Pod の通信を認証する。

▼ JWT による Bearer 認証 (ID プロバイダーに認証フェーズを委譲)

JWT による Bearer 認証を実施し、送信元 Pod の通信を認証する。

この場合、認証フェーズを ID プロバイダー (例:Auth0、AWS Cognito、GitHub、Google Cloud Auth、Keycloak、Zitadel) へ委譲することになる。

JWT トークンの取得方法として、例えば以下の方法がある。

  • 送信元 Pod が ID プロバイダーから JWT を直接取得する。
  • 送信元/宛先の間に認証プロキシ (例:OAuth2 Proxy、Dex など) を配置し、認証プロキシで ID プロバイダーから JWT を取得する。

▼ マイクロサービスの認証について

マイクロサービス側の認証については、Istio の管理外である。


通信の認可

▼ 仕組み

Pod 間通信時、AuthorizationPolicy を使用して、スコープに含まれる認証済み Envoy の通信のみを認可する。

istio_authorization-policy

▼ 通信の認可の委譲

AuthorizationPolicy で認可プロバイダー (例:Keycloak、Open Policy Agent) を指定し、認可フェーズを委譲できる。

▼ マイクロサービスの認可について

マイクロサービス側の認可については、Istio の管理外である。


06. パケットのアプリケーションデータの暗号化

記入中...


06-02. 証明書の発行

クライアント証明書/サーバー証明書発行

▼ Istiod コントロールプレーン (discovery コンテナ) をルート認証局として使用する場合

デフォルトでは、Istiod コントロールプレーンがルート認証局として働く。

クライアント証明書/サーバー証明書を提供しつつ、これを定期的に自動更新する。

  1. Istiod コントロールプレーンは、istio-ca-secret (Secret) を自己署名する。
  2. Istiod コントロールプレーンは、istio-proxy から送信された秘密鍵と証明書署名要求で署名済みのクライアント証明書/サーバー証明書を作成する。追加設定がない場合、istio-proxy の pilot-agent プロセスが動作する。pilot-agent プロセスは秘密鍵と証明書署名要求を自動で作成する。
  3. istio-proxy からのリクエストに応じて、Istiod の SDS-API がクライアント証明書/サーバー証明書を istio-proxy に配布する。
  4. Istiod コントロールプレーンは、CA 証明書を持つ istio-ca-root-cert (ConfigMap) を自動的に作成する。istio-ca-root-cert は istio-proxy にマウントされ、証明書を検証するために使用する。
  5. istio-proxy 間で相互 TLS 認証できるようになる。
  6. 証明書が失効すると、istio-proxy の証明書が自動的に差し代わる。Pod の再起動は不要である。

istio_istio-ca-root-cert

▼ 外部ツールをルート認証局として使用する場合

Istiod コントロールプレーン (discovery コンテナ) を中間認証局として使用し、ルート認証局を Istio 以外に委譲できる。

外部のルート認証局は、istio-proxy から送信された秘密鍵と証明書署名要求で署名済みのサーバー証明書を作成する。

  • CertManager (ルート認証局、署名済み証明書の発行、マウント用 Secret への証明書埋め込み、自動ローテーション)
  • HashiCorp Vault (ルート認証局) + CertManager (署名済み証明書の発行、マウント用 Secret への証明書埋め込み、自動ローテーション)


06-03. 証明書の認証方式

相互 TLS 認証

▼ 相互 TLS 認証とは

相互 TLS 認証を実施し、L7 のアプリケーションデータを暗号化/復号する。

暗号スイート

  • TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
  • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  • TLS_AES_256_GCM_SHA384
  • TLS_AES_128_GCM_SHA256

▼ TLS タイムアウト

アウトバウンド通信、istio-proxy は宛先に HTTPS リクエストを送信する。

このとき、実際はタイムアウト時間を超過していても、TLS handshake timeout というエラーなってしまう。


07. テレメトリーの作成

他の OSS との連携

istio-proxy は、テレメトリーを作成する。

各監視ツールは、プル型 (ツールが Istiod から収集) やプッシュ型 (Istiod がツールに送信) でこのテレメトリーを収集する。


07-02. メトリクス

メトリクスの作成と送信

istio-proxy はメトリクスの元になるデータポイントを作成し、Istiod コントロールプレーン (discovery コンテナ) に送信する。

Prometheus は、discovery コンテナの /stats/prometheus エンドポイント (15090 番ポート) からメトリクスの元になるデータポイントを収集する。

なお、istio-proxy にも /stats/prometheus エンドポイントはある。


セットアップ

▼ Prometheus の設定ファイル

Prometheus の設定ファイルとして定義できる。

scrape_configs:
  # Istiod の監視
  - job_name: istiod
    kubernetes_sd_configs:
      - role: endpoints
        namespaces:
          names:
            - istio-system
    relabel_configs:
      - source_labels:
          - __meta_kubernetes_service_name
          - __meta_kubernetes_endpoint_port_name
        action: keep
        regex: istiod;http-monitoring
  # istio-proxy の監視
  - job_name: istio-proxy
    metrics_path: /stats/prometheus
    kubernetes_sd_configs:
      - role: pod
    relabel_configs:
      - source_labels:
          - __meta_kubernetes_pod_container_port_name
        action: keep
        regex: .*-envoy-prom

▼ カスタムリソースの場合

Prometheus が discovery コンテナからデータポイントを取得するためには、discovery コンテナの Pod を監視するための ServiceMonitor が必要である。

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: istiod-service-monitor
  namespace: istio-system
spec:
  jobLabel: istio
  targetLabels:
    - app
  selector:
    matchExpressions:
      - key: istio
        operator: In
        values:
          - pilot
  namespaceSelector:
    matchNames:
      - istio-system
  endpoints:
    - port: http-monitoring
      interval: 15s

また、istio-proxy の監視には、PodMonitor が必要である。

apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: istio-proxy-service-monitor
  namespace: istio-system
spec:
  selector:
    matchExpressions:
      - key: istio-prometheus-ignore
        operator: DoesNotExist
  namespaceSelector:
    # istio-proxy をインジェクションしている Namespace を網羅できるようにする
    any: true
  jobLabel: envoy-stats
  podMetricsEndpoints:
    # istio-proxy コンテナが公開しているデータポイント収集用のエンドポイントを指定する
    - path: /stats/prometheus
      interval: 15s
      relabelings:
        - action: keep
          sourceLabels:
            - __meta_kubernetes_pod_container_name
          regex: "istio-proxy"
        - action: keep
          sourceLabels:
            - __meta_kubernetes_pod_annotationpresent_prometheus_io_scrape
        - action: replace
          regex: (\d+);(([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4})
          replacement: "[$2]:$1"
          sourceLabels:
            - __meta_kubernetes_pod_annotation_prometheus_io_port
            - __meta_kubernetes_pod_ip
          targetLabel: __address__
        - action: replace
          regex: (\d+);((([0-9]+?)(\.|$)){4})
          replacement: $2:$1
          sourceLabels:
            - __meta_kubernetes_pod_annotation_prometheus_io_port
            - __meta_kubernetes_pod_ip
          targetLabel: __address__
        - action: labeldrop
          regex: "__meta_kubernetes_pod_label_(.+)"
        - sourceLabels:
            - __meta_kubernetes_namespace
          action: replace
          targetLabel: namespace
        - sourceLabels:
            - __meta_kubernetes_pod_name
          action: replace
          targetLabel: pod_name


メトリクスの種類

▼ Istiod 全体に関するメトリクス

メトリクス名 単位 説明
istio_build カウント Istio の各コンポーネントの情報を表す。istio_build{component="pilot"} とすることで、Istiod コントロールプレーンの情報を取得できる。

▼ istio-proxy に関するメトリクス

Prometheus 上でメトリクスをクエリすると、Istiod コントロールプレーン (discovery コンテナ) から収集したデータポイントを取得できる。

メトリクス名 単位 説明
istio_requests_total カウント istio-proxy が受信した総リクエスト数を表す。メトリクスの名前空間に対してさまざまなディメンションを設定できる。<br>https://blog.christianposta.com/understanding-istio-telemetry-v2/
istio_request_duration_milliseconds カウント istio-proxy が受信したリクエストの処理時間を表す。
istio_request_messages_total カウント istio-proxy が受信した gRPC による総 HTTP リクエスト数を表す。
istio_request_messages_total カウント istio-proxy が受信した gRPC による総 HTTP リクエスト数を表す。

| istio_request_duration_milliseconds_sum | カウント | istio-proxy が起動以降のすべてのリクエスト期間の合計 | | envoy_cluster_upstream_rq_retry | カウント | istio-proxy のほかの Pod へのリクエストに関するリトライ数を表す。 | | envoy_cluster_upstream_rq_retry_success | カウント | istio-proxy が他の Pod へのリクエストに関するリトライ成功数を表す。 | | envoy_cluster_upstream_rq_retry_backoff_expotential | カウント | 記入中... | | envoy_cluster_upstream_rq_retry_limit_exceeded | カウント | 記入中... |

▼ メトリクスのラベル

メトリクスをフィルタリングできるように、Istio では任意のメトリクスにデフォルトでラベルがついている。

送信元と宛先を表すメトリクスがあり、Kiali と組み合わせることにより、リクエストの送信元 Pod を特定できる。

Istio を使わないと送信元 IP アドレスで特定する必要があるが、プロキシによって書き換えられてしまうため、実際はかなり無理がある。

Istio Ingress Gateway を経由せずにサービスメッシュ外からインバウンド通信 (例えば、Prometheus や kubelet の /metrics スクレイピング) がくると、ラベル値が unknown になってしまう。

ラベル 説明 注意点
connection_security_policy Pod 値の通信方法を表す。 mutual_tls (相互 TLS 認証)
destination_app リクエストの宛先のコンテナ名を表す。 foo-container
destination_cluster リクエストの宛先の Kubernetes Cluster 名を表す。 Kubernetes
destination_service リクエストの宛先の Service 名を表す。 foo-service
destination_workload リクエストの宛先の Deployment 名を表す。 `foo-deployment
destination_workload_namespace 送信元の Namespace 名を表す。
reporter データポイントの作成者を表す。istio-proxy か IngressGateway のいずれかである。 destination (宛先の istio-proxy)<br>source (送信元の IngressGateway または istio-proxy)
response_flags Envoy の %RESPONSE_FLAGS% 変数を表す。 - (値なし)
response_code istio-proxy が返信したレスポンスコードの値を表す。 2004040 reporter="source" の場合、送信元 istio-proxy に対して、宛先 istio-proxy がマイクロサービスから受信したステータスコードを集計する。reporter="destination" の場合、送信元 istio-proxy に対して、宛先 istio-proxy がマイクロサービスから受信したステータスコードを集計する。
source_app 送信元のコンテナ名を表す。 foo-container
source_cluster 送信元の Kubernetes Cluster 名を表す。 Kubernetes
source_workload 送信元の Deployment 名を表す。 foo-deployment


07-03. ログ (アクセスログのみ)

ログの監視

▼ ログの出力

istio-proxy は、マイクロサービスへのアクセスログ (インバウンド通信とアウトバウンド通信の両方) を作成し、標準出力に出力する。

アクセスログにデフォルトで役立つ値が出力される。

ログ収集ツール (例:FluentBit、Fluentd など) を DaemonSet パターンやサイドカーモードで配置し、Node や Pod 内コンテナの標準出力に出力されたログを監視バックエンドへ送信できるようにする必要がある。

# istio-proxy コンテナのアクセスログ
{
  # 相互 TLS 認証の場合の宛先コンテナ名
  "authority": "foo-downstream:<ポート番号>",
  "bytes_received": 158,
  "bytes_sent": 224,
  "connection_termination_details": null,
  # istio-proxy コンテナにとっての送信元
  "downstream_local_address": "*.*.*.*:50010",
  "downstream_remote_address": "*.*.*.*:50011",
  # 送信元から宛先へリクエストを送信し、レスポンスを処理し終えるまでにかかった時間
  # 送信元でタイムアウト時間が超過した場合は、Envoy はその時間の直前にプロキシをやめるため、Duration はタイムアウト時間とおおよそ同じになる
  "duration": 12,
  "method": null,
  "path": null,
  "protocol": null,
  "request_id": null,
  "requested_server_name": null,
  # 宛先からのレスポンスのステータスコード
  "response_code": 200,
  "response_code_details": null,
  # ステータスコードの補足情報
  "response_flags": "-",
  "route_name": null,
  "start_time": "2023-04-12T06:11:46.996Z",
  # istio-proxy コンテナにとっての宛先
  "upstream_cluster": "outbound|50000||foo-pod.foo-namespace.svc.cluster.local",
  "upstream_host": "*.*.*.*:50000",
  "upstream_local_address": "*.*.*.*:50001",
  "upstream_service_time": null,
  "upstream_transport_failure_reason": null,
  "user_agent": null,
  "x_forwarded_for": null,
}

▼ ログの送信

istio-proxy は、アクセスログをログ収集ツール (例:OpenTelemetry Collector) に送信する。


07-04. 分散トレース

分散トレースの監視

▼ スパンの作成

istio_distributed_tracing

istio-proxy は、スパンを作成する。

スパンの作成場所には、いくつか種類がある。

スパン作成パターン istio-proxy マイクロサービス
istio-proxy のみ
マイクロサービスのみ
両方

スパンの作成場所が多いほど、各コンテナの処理時間が細分化された分散トレースを収集できる。

マイクロサービス間でスパンが持つコンテキストを伝播しないため、コンテキストを伝播させる実装が必要になる。

▼ スパンの送信

istio-proxy は、スパンを分散トレース収集ツール (例:Jaeger Collector、OpenTelemetry Collector など) に送信する。

マイクロサービスからスパンを送信する場合であっても、istio-proxy を経由し、分散トレース収集ツールへ送信することになる。

分散トレース収集ツールをサービスメッシュに登録 (VirtualService や ServiceEntry を作成) しないと、マイクロサービスや istio-proxy は分散トレース収集ツールを名前解決できない。

Envoy では宛先としてサポートしていても、istio-proxy では使用できない場合がある。(例:X-Ray デーモン)


スパン名

▼ EnvoyFilter の場合

Istio の設定では、EnvoyFilter を使用しないとデフォルトのスパン名を変更できない。

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: bookinfo-gateway-sampling
  namespace: istio-system
spec:
  configPatches:
    - patch:
        operation: MERGE
        value:
          decorator:
            operation: <スパン名>

▼ OpenTelemetry Collector の場合

Istio の代わりに、OpenTelemetry Collector でスパン名を変更できる。

あらかじめ、Telemetry で http.url.path という属性を設定しておく。

apiVersion: telemetry.istio.io/v1
kind: Telemetry
metadata:
  name: trace-provider
  namespace: foo
spec:
  tracing:
    - providers:
        - name: opentelemetry
      customTags:
        # HTTP ヘッダーから設定する
        http.url.path:
          header:
            name: :path
            defaultValue: unknown

spanprocessor を使用して、スパン名を変更する。

# OpenTelemetry Collector の設定ファイル
config:
  processors:
    span:
      name:
        from_attributes:
          - http.method
          - http.url.path
        # GET /foo のようなスパンになる
        separator: " "
      include:
        match_type: strict
        # istio-proxy コンテナの作成したスパンのみを対象とする
        attributes:
          - key: component
            value: proxy
  service:
    pipelines:
      traces:
        processors:
          - span


属性

istio-proxy コンテナは、デフォルトで以下のようなスパンを作成する。

{
  "batches":
    [
      {
        "resource":
          {
            "attributes":
              [
                {
                  "key": "telemetry.sdk.language",
                  "value": {"stringValue": "cpp"},
                },
                {
                  "key": "telemetry.sdk.name",
                  "value": {"stringValue": "envoy"},
                },
                {
                  "key": "telemetry.sdk.version",
                  "value":
                    {
                      "stringValue": "4382ac5fc1d362094bbba33283dbe60a3e1cef88/1.33.1-dev/Clean/RELEASE/BoringSSL",
                    },
                },
                {"key": "k8s.pod.ip", "value": {"stringValue": "127.0.0.6"}},
                {
                  "key": "service.name",
                  "value": {"stringValue": "reviews.bookinfo"},
                },
              ],
            "droppedAttributesCount": 0,
          },
        "instrumentationLibrarySpans": [{"spans": [
                  {
                    "traceId": "422a513f9dd13cdca4b291187d65ec69",
                    "spanId": "0241f770ee902e2d",
                    "parentSpanId": "61d22fad2b80d1dd",
                    "traceState": "",
                    "name": "proxy./ratings/0",
                    # 送信元 istio-proxy コンテナまたは宛先 istio-proxy コンテナ
                    "kind": "SPAN_KIND_CLIENT",
                    "startTimeUnixNano": 1745220839492363000,
                    "endTimeUnixNano": 1745220839934638800,
                    "attributes":
                      [
                        {
                          "key": "node_id",
                          "value":
                            {
                              "stringValue": "sidecar~10.244.1.6~reviews-v4-7586d5d46d-tgqhb.bookinfo~bookinfo.svc.cluster.local",
                            },
                        },
                        {"key": "zone", "value": {"stringValue": ""}},
                        {
                          "key": "guid:x-request-id",
                          "value":
                            {
                              "stringValue": "5457526c-0e6c-92eb-b0bd-508c75ad85c2",
                            },
                        },
                        {
                          "key": "downstream_cluster",
                          "value": {"stringValue": "-"},
                        },
                        {
                          "key": "user_agent",
                          "value":
                            {
                              "stringValue": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36",
                            },
                        },
                        {
                          "key": "http.protocol",
                          "value": {"stringValue": "HTTP/1.1"},
                        },
                        {
                          "key": "peer.address",
                          "value": {"stringValue": "10.244.1.6"},
                        },
                        {"key": "request_size", "value": {"stringValue": "0"}},
                        {
                          "key": "response_size",
                          "value": {"stringValue": "48"},
                        },
                        {"key": "component", "value": {"stringValue": "proxy"}},
                        {
                          "key": "upstream_cluster",
                          "value":
                            {
                              "stringValue": "outbound|9080|v3|ratings.bookinfo.svc.cluster.local",
                            },
                        },
                        {
                          "key": "upstream_cluster.name",
                          "value":
                            {
                              "stringValue": "outbound|9080|v3|ratings.bookinfo.svc.cluster.local;",
                            },
                        },
                        {
                          "key": "http.status_code",
                          "value": {"stringValue": "200"},
                        },
                        {
                          "key": "response_flags",
                          "value": {"stringValue": "-"},
                        },
                        {
                          "key": "istio.cluster_id",
                          "value": {"stringValue": "Kubernetes"},
                        },
                        {
                          "key": "istio.mesh_id",
                          "value": {"stringValue": "cluster.local"},
                        },
                        {
                          "key": "istio.namespace",
                          "value": {"stringValue": "bookinfo"},
                        },
                        {
                          "key": "istio.canonical_revision",
                          "value": {"stringValue": "v4"},
                        },
                        {
                          "key": "istio.canonical_service",
                          "value": {"stringValue": "reviews"},
                        },
                        {"key": "http.method", "value": {"stringValue": "GET"}},
                        {
                          "key": "http.url",
                          "value":
                            {"stringValue": "http://ratings:9080/ratings/0"},
                        },
                      ],
                    "droppedAttributesCount": 0,
                    "droppedEventsCount": 0,
                    "droppedLinksCount": 0,
                    "status": {"code": 0, "message": ""},
                  },
                ], "instrumentationLibrary": {"name": "envoy", "version": "4382ac5fc1d362094bbba33283dbe60a3e1cef88/1.33.1-dev/Clean/RELEASE/BoringSSL"}}],
      },
    ],
}