エッジにおけるオブザーバビリティ: Envoy と Istio の新しい OTel 機能

Blog posts are not updated after publication. This post is more than a year old, so its content may be outdated, and some links may be invalid. Cross-verify any information before relying on it.

クラウドネイティブで分散されたアプリケーションのダイナミックな世界では、マイクロサービスを効果的に管理することが極めて重要です。 Kubernetes はコンテナオーケストレーションの事実上の標準となり、コンテナ化されたアプリケーションのシームレスなデプロイ、スケーリング、管理を可能にしています。

しかし、このようなシステムの分散的な性質は、クラスター内通信のネットワーキングという形で複雑さのレイヤーを追加します。 Envoy と Istio という2つの著名なプロジェクトが、このような複雑な環境を円滑に管理・運用するための基盤として登場しました。

これらの技術を組み合わせることで、組織はスケーラブルでレジリエントかつ安全な分散システムを構築できます。

Istio はサービスメッシュであり、マイクロサービス間の通信をオーケストレーションし、トラフィック管理、セキュリティ、そしてもちろんオブザーバビリティなどの機能を提供します。 Istio はデータプレーンとして Envoy プロキシを使用しています。 Envoy は高性能プロキシであり、単一のアプリケーション/サービス向けだけでなく、サービスメッシュのための通信バスおよび「ユニバーサルデータプレーン」としても設計されています。

EnvoyIstio はオープンソースプロジェクトであり、Cloud Native Computing Foundation の一部です。

Envoy と Istio におけるオブザーバビリティ

Istio サービスメッシュによってデプロイされた Envoy プロキシは、受信および送信リクエストが適切にトレースされることを保証するための最適な候補です。 このアプローチにより、サービスメッシュ全体の分散トレースが提供され、アプリケーション自体が計装されていない場合でも、サービス間の通信の概要を把握できます。

Note: 最低限、アプリケーションは traceparent ヘッダーを伝搬するよう設定されている必要があります。

Envoy はリクエストのトレーシングのために、いくつかの HTTP トレーサーを提供しており、OpenTelemetry トレーサーもその1つです。 トレーサーは、Envoy 内で直接設定する(スタンドアロンコンポーネントとして使用する場合)か、Istio を使用してすべての Envoy インスタンスに対して設定できます。

以下は、Istio と Envoy が連携してリクエストをトレースする方法の例です。

Istio と Envoy による分散トレース

Envoy と Istio の新しい OTel トレーシング機能

Envoy はすでに gRPC を使用した OpenTelemetry トレースのエクスポートをサポートしていましたが、HTTP を使用したエクスポートのサポートが不足していました。 OpenTelemetry は両方のプロトコルをファーストクラスでサポートしています。 さらに、リソース属性の提供や設定可能なサンプリング決定など、その他の領域も OpenTelemetry 仕様の安定部分に対して遅れをとっていました。

Envoy 1.29 と Istio 1.22 以降、ユーザーは以下に説明する新機能を利用できるようになりました。

OTLP HTTP エクスポーター

Envoy の OpenTelemetry トレーサーは、HTTP を使用して OTLP トレースをエクスポートするよう設定できるようになりました。 これにより、Envoy プロキシから直接 OTLP/HTTP を使用してオブザーバビリティシンクにテレメトリーを送信できます。

リソースディテクター

Envoy には環境リソースディテクターが同梱されるようになりました。 このリソースディテクターは OTel 仕様に準拠しており、ユーザーは Envoy プロキシが生成するスパンをさらに充実させることができます。

リソースディテクター機能は環境ディテクターを追加しただけでなく、Envoy の組み込みエクステンション機能を使用して他のリソースディテクターも容易に追加できるようにしました。

カスタムサンプラー

Envoy に追加されたもう1つのエキサイティングな機能は、カスタムサンプラーの実装と設定が可能になったことです。 Envoy は OTel サンプラーインターフェースに準拠しており、誰でも独自のサンプラーを簡単にコントリビュートできます。

Envoy には Always On サンプラーが同梱されており、すべてのスパンをそのまま転送します。 この基本実装は、よりスマートなサンプラーのリファレンス実装として使用できます。

デモ

新しい機能を実際に試してみましょう! ここでは、Istio Bookinfo アプリケーションを使用して、以下の方法を説明します。

  • Kubernetes にデプロイし、Istio をサービスメッシュとして使用する
  • HTTP を使用して Jaeger にトレースをエクスポートする

Jaeger のインストール

まず、Jaeger operator をインストールします。

kubectl create namespace observability
kubectl create -f https://github.com/jaegertracing/jaeger-operator/releases/download/v1.57.0/jaeger-operator.yaml -n observability

次に Jaeger all-in-one をデプロイします。

kubectl apply -f - <<EOF
apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: simplest
EOF

Istio のインストールと設定

次に、istioctl を使用して Istio をインストールします。

cat <<EOF | istioctl install -y -f -
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  meshConfig:
    enableTracing: true
    extensionProviders:
    - name: otel-tracing
      opentelemetry:
        port: 4318
        service: simplest-collector.default.svc.cluster.local
        http:
          path: "/v1/traces"
          timeout: 5s
        resource_detectors:
          environment: {}
EOF

これにより Istio がインストールされ、OpenTelemetry トレーシングプロバイダーが OTLP/HTTP 上の http エクスポーターを使用し、Jaeger collector をエンドポイントとして設定されます。 この設定では、resource_detectors で環境リソースディテクターも有効になります。

次に、Istio の Telemetry API を使用してトレーサーを有効にする必要があります。

kubectl apply -f - <<EOF
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: otel-demo
spec:
  tracing:
  - providers:
    - name: otel-tracing
    randomSamplingPercentage: 100
EOF

最後に、Envoy プロキシの OTEL_RESOURCE_ATTRIBUTES 環境変数を設定します。

cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1beta1
kind: ProxyConfig
metadata:
  name: my-proxyconfig
  namespace: istio-system
spec:
  concurrency: 0
  environmentVariables:
    OTEL_RESOURCE_ATTRIBUTES: "host.name=abc-123"
EOF

アプリケーションのデプロイ

最後のステップは、bookinfo アプリケーション(bookinfo.yaml)をデプロイすることです。

kubectl label namespace default istio-injection=enabled
kubectl apply -f bookinfo.yaml

動作確認

セットアップをテストするには、サービスの1つにリクエストを送信します。 たとえば、以下のようにします。

kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"

その後、Jaeger UI で確認できます。 トレースが表示されているはずです!

Jaeger での分散トレース表示

Envoy が生成したスパンから、以下の内容を確認できます(順番に)。

  1. ratings サービスから productpage サービスへの送信(egress)呼び出し。
  2. productpage サービスへの受信(ingress)呼び出し。
  3. OTEL_RESOURCE_ATTRIBUTES を使用して適用した host-name リソース属性。 この属性は環境リソースディテクターによって検出され、Envoy が作成したすべてのスパンに追加されました。

すべてのサービスには Istio によって Envoy サイドカーが注入されているため、その他すべてのダウンストリーム呼び出しも確認できます。 Envoy で OTel トレーサーを有効にするだけで、サービス間の呼び出しの完全なオブザーバビリティが得られます!

次のステップとまとめ

この投稿で説明した新機能により、ユーザーはトレースのエクスポートにおいてより高い柔軟性を得られます。 リソース属性によるデータの充実が可能になり、将来追加されるよりインテリジェントなサンプリング技術の基盤が確立されました。

これらの新機能は、クラウドプロバイダーやオブザーバビリティベンダーを含む、オブザーバビリティ領域の他の関係者にとっても興味深いユースケースを生み出します。 リソースディテクターとサンプラー API が Envoy で利用可能になったことで、誰でもカスタムサンプラーやディテクターのサポートを構築し、Envoy が生成するテレメトリーデータの有用性を向上させることができます。

Envoy と OpenTelemetry のもう1つのエキサイティングな次のステップは、安定版となった Envoy における HTTP セマンティック規約の採用です。 これにより、Envoy は安定版の HTTP セマンティック規約に従ってスパンを生成しているすべての OTel SDK と整合します。

Envoy と Istio のコミュニティと協力して、これらのプロジェクトにより多くの OTel 機能を導入することは素晴らしい経験でした。 OpenTelemetry の採用への意欲と、Istio や Envoy のような関連する CNCF プロジェクトとの強力なコラボレーションは、オブザーバビリティの事実上の標準としての OpenTelemetry の地位を固めるのに役立っています。