🐾

Cloud Run JobsからDatadogにトレースを送りたい時はServerless-initを使う

に公開

タイトルが全てです。Cloud Run JobならServerless-initを使いましょう。

やりたかったこと

Cloud Run Jobで動くPythonアプリケーションのトレース情報をDatadogに送信したい。
ジョブはGCSへのオブジェクト作成のイベント駆動で実行されるため実行は不定期。

検討したアプローチ

1. Jobのサイドカーとしてdatadog agentコンテナを起動させる

  • 参考: Cloud Run のマルチコンテナ (サイドカー) の基本
  • 実際試してみたところ、エラー等でagentコンテナが先に落ちるとメインコンテナも一緒にexitしてしまう事象が発生
  • メインコンテナが先に終了した場合、バッファがflushされずにトレースデータが失われる可能性がある
  • 並列実行時(例:100並列)にエージェントも同数起動されるため、リソースの無駄遣いになる
    • Cloud Runはサイドカーコンテナ含め8CPU、32GBメモリの制限があり、メインコンテナに割り当てられるリソースが減少

2. Datadog AgentをCloud Run Serviceとして常駐させる

  • Agentを通常のCloud Runで立ち上げて常駐させる方法
  • 不定期実行のジョブに対して、常時Agentを稼働させることはコスト非効率
  • エージェントへのアクセス方法に関する課題
    • インターネットアクセス:IAM認証の問題
    • VPCアクセス:DirectVPCEgressの設定が必要
    • VPCアクセス方式は試したが一発ではうまく動作せず、深く検証していない

解決策:Serverless-initの活用

Serverless-initを使用する。

Serverless-initは、Cloud RunからDatadogに直接ログ・メトリクス・トレースを送信できるライブラリです。名前から推測するに、AWS LambdaやCloud Run Functions(旧Cloud Functions)でも使用できる可能性がありますが、この記事では検証していません。

当初、cloud-initと混同してドキュメントを読み飛ばしていましたが、チームメンバーに指摘されて気づくことができました。

実装方法

Serverless-initでアプリケーションの起動コマンドをラップします。

COPY --from=datadog/serverless-init:1 /datadog-init /app/datadog-init
RUN pip install --target /dd_tracer/python/ ddtrace
ENV DD_SERVICE=datadog-demo-run-python
ENV DD_ENV=datadog-demo
ENV DD_VERSION=1
ENTRYPOINT ["/app/datadog-init"]
CMD ["/dd_tracer/python/bin/ddtrace-run", "python", "app.py"]

今回のアプリケーションはCloud Run Jobのoverrideで起動引数を渡していたため、アプリ起動もENTRYPOINTに含める構成にしました。

ENTRYPOINT ["/app/datadog-init", "python", "app.py"]

Serverless-initの利点と考慮点

  • コンテナ設計の原則に関する考慮事項
    • Cloud RunサイドカーでDataDog APMを利用するでも言及されているように、「1プロセス1コンテナ」の原則から外れる
    • 実際に2つのプロセスが起動しているかは未検証だが、少なくとも2つの関心事が1コンテナに混在する
  • サイドカーパターンの課題
    • コスト最適化の観点からも理想的とは言えない
    • Service Meshの世界でも、Istioはサイドカーに加えてAmbient Modeという選択肢を提供し始めている
    • 将来的にはGoogle Cloud Next '25で発表されたCloud Run Worker Poolsに期待が持てるかもしれない

結論として、現状のCloud Run Jobでは、Serverless-initが最も実用的な選択肢だと考えられます。

Discussion