TT Lab
はじめる
学ぶ 学習パス コース

OTCA — OpenTelemetry認定アソシエイト

SDKの設定とリソース属性

TT Labで続きを見る

目標

SDKを環境変数で設定し、リソース属性をセマンティック規約に合わせて確定し、KubernetesでインスタンスIDをDownward APIで注入します。最後に、スパン名のカーディナリティを検査するリンターを自分で作ります。

なぜ重要なのか

計装で最もやり直しがきかない決定が、リソース属性です。コードはいつでも直せますが、service.nameを変えた瞬間に、ダッシュボード、アラート、サービスグラフ、そして過去データとのつながりがすべて切れます。そのため、スパンを増やす前にこれを確定します。同じ理由で、名前の規約が重要です。deployment.environmentとdeployment.environment.nameは、人間の目には同じに見えますが、システムにとっては完全に別の2つの属性で、ダッシュボードの変数はそのうち片方しか読みません。スパン名も同様です。名前にIDが混ざると、バックエンドの集計ビューが丸ごと崩れますが、この事故はデプロイ直後ではなく、数週間後に「サービスグラフがおかしい」という形で発見されます。そのため、人の記憶ではなくCIで防ぐ必要があります。

ステップ

  1. /root/otca-sdk/otel.envを作成し、OTEL_SERVICE_NAME=checkout-api、OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector.observability.svc:4317、OTEL_EXPORTER_OTLP_PROTOCOL=grpcを書いてください。1行に1つずつ、키=값の形式です(プレースホルダーはキーと値です)。
  2. 同じファイルにOTEL_RESOURCE_ATTRIBUTESを追加してください。値は、カンマでつないだservice.version=2.7.1、deployment.environment.name=prod、service.namespace=commerceです。古い名前のdeployment.environmentは使わないでください。
  3. 同じファイルにOTEL_TRACES_SAMPLER=parentbased_traceidratio、OTEL_TRACES_SAMPLER_ARG=0.1、OTEL_PROPAGATORS=tracecontext,baggageを追加してください。
  4. 同じファイルに4つの上限を追加してください。OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT=64、OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT=2048、OTEL_BSP_MAX_QUEUE_SIZE=4096、OTEL_BSP_MAX_EXPORT_BATCH_SIZE=512です。
  5. /root/otca-sdk/deployment.yamlにDeploymentを書いてください。metadata.name: checkout-api、metadata.namespace: otca-sdkにします。最初のコンテナのenvに、POD_NAME(fieldRef metadata.name)、POD_NAMESPACE(fieldRef metadata.namespace)、OTEL_SERVICE_NAME=checkout-api、OTEL_EXPORTER_OTLP_ENDPOINT(4317を含む)、そしてOTEL_RESOURCE_ATTRIBUTESを入れてください。その値には、deployment.environment.name=prod、service.instance.id=$(POD_NAME)、k8s.namespace.name=$(POD_NAMESPACE)が含まれている必要があります。
  6. ネームスペースotca-sdkを作成し、ステップ5のマニフェストをクラスターに適用してください。
  7. /root/otca-sdk/span-names.txtにスパン名を6行以上書いてください。そのうち最低4行はGET /...のようにHTTPメソッドで始まり、最低3行は:idプレースホルダーを含む必要があります。3桁以上連続する数字やUUIDは、1行も含まれていてはいけません。
  8. /root/otca-sdk/lint-span-names.shを作成してください。1つ目の引数で受け取ったファイルに、3桁以上連続する数字やUUID形式が含まれていたら、その行を出力して0以外のコードで終了し、なければ0で終了するようにします。

参考

サービス名とエンドポイント

/root/otca-sdk/otel.envを作成し、OTEL_SERVICE_NAME=checkout-api、OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector.observability.svc:4317、OTEL_EXPORTER_OTLP_PROTOCOL=grpcを書いてください。1行に1つずつ、키=값の形式です(プレースホルダーはキーと値です)。

SDKは環境変数だけで制御できます。そのため、計装の設定はコードではなくデプロイ用のマニフェストにあり、エンドポイントを変えるのにコードレビューは要りません。ポートとプロトコルは、必ず対応が合っている必要があります。

リソース属性を確定する

同じファイルにOTEL_RESOURCE_ATTRIBUTESを追加してください。値は、カンマでつないだservice.version=2.7.1、deployment.environment.name=prod、service.namespace=commerceです。古い名前のdeployment.environmentは使わないでください。

リソース属性は、このプロセスが出力するすべてのシグナルに付きます。複数ある場合はカンマでつなぎ、それぞれキー=値の形式です。環境属性の名前は最近の規約で変わったので、古い名前を使わないよう注意してください。

サンプラーとプロパゲーター

同じファイルにOTEL_TRACES_SAMPLER=parentbased_traceidratio、OTEL_TRACES_SAMPLER_ARG=0.1、OTEL_PROPAGATORS=tracecontext,baggageを追加してください。

サンプラー名にparentbasedが付いていてはじめて、親の判断に従います。付けないと、サービスごとに独立して確率判定を行い、トレースが途中で切れます。プロパゲーターはカンマで複数指定できます。

スパンのサイズとキューの上限

同じファイルに4つの上限を追加してください。OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT=64、OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT=2048、OTEL_BSP_MAX_QUEUE_SIZE=4096、OTEL_BSP_MAX_EXPORT_BATCH_SIZE=512です。

属性の個数にはデフォルトの上限がありますが、値の長さにはありません。リクエスト本文がそのまま入ると、1つのスパンが数百KBになります。バッチスパンプロセッサーのキューサイズとバッチサイズも一緒に決めておきます。

Downward APIでインスタンス識別子を注入する

/root/otca-sdk/deployment.yamlにDeploymentを書いてください。metadata.name: checkout-api、metadata.namespace: otca-sdkにします。最初のコンテナのenvに、POD_NAME(fieldRef metadata.name)、POD_NAMESPACE(fieldRef metadata.namespace)、OTEL_SERVICE_NAME=checkout-api、OTEL_EXPORTER_OTLP_ENDPOINT(4317を含む)、そしてOTEL_RESOURCE_ATTRIBUTESを入れてください。その値には、deployment.environment.name=prod、service.instance.id=$(POD_NAME)、k8s.namespace.name=$(POD_NAMESPACE)が含まれている必要があります。

Pod名をハードコードすると、再起動のたびに誤った値が残ります。fieldRefでmetadata.nameとmetadata.namespaceを環境変数として受け取り、別の環境変数の中で括弧表記で参照すると、kubeletが置換してくれます。複数行の値は、折りたたみブロックで書くと読みやすくなります。

クラスターに適用する

ネームスペースotca-sdkを作成し、ステップ5のマニフェストをクラスターに適用してください。

先にネームスペースを作成してから、マニフェストを適用します。採点はクラスターに実際に入ったPodテンプレートを読むため、ファイルを直しただけで適用しないと合格しません。

低カーディナリティのスパン名リスト

/root/otca-sdk/span-names.txtにスパン名を6行以上書いてください。そのうち最低4行はGET /...のようにHTTPメソッドで始まり、最低3行は:idプレースホルダーを含む必要があります。3桁以上連続する数字やUUIDは、1行も含まれていてはいけません。

バックエンドはスパン名でグループ化して、レイテンシの統計とサービスグラフを作ります。名前に注文番号やUUIDが入ると、グループがリクエスト数だけできてしまいます。ルートはテンプレートで書き、具体的な値は属性で送ります。

スパン名リンター

/root/otca-sdk/lint-span-names.shを作成してください。1つ目の引数で受け取ったファイルに、3桁以上連続する数字やUUID形式が含まれていたら、その行を出力して0以外のコードで終了し、なければ0で終了するようにします。

スクリプトは、1つ目の引数として一覧ファイルを受け取ります。3桁以上連続する数字やUUID形式が含まれていたら、その行を出力して失敗で終了すればよいです。前のステップで作った一覧は、合格する必要があります。