Googleドキュメントのアジェンダを自動的に追加する

例えば以下のような定例用のGoogleドキュメントがあったとします。

テンプレートが下のほうにあり、上にその週のアジェンダをどんどん追加していくスタイルのドキュメントです。 ローテーションで司会が変わっていきます。

この毎週のアジェンダ作成が面倒です。テンプレートからコピってきてその週の定例の日付を入力しその週の司会の人の名前を入れる必要があります。 面倒なので自動化しました。

メニューバーの「拡張機能」から「Apps Script」を選択します。

Apps Scriptのエディタが開いたらおもむろに以下のコードを貼り付けて保存します。

var templatePhrase = 'template';
var templateDateFormat = 'YYYY/MM/DD';
var mtgIntervalDays = 7;

function onOpen() {
  const ui = DocumentApp.getUi();
  ui.createMenu('アジェンダ')
    .addItem('テンプレート追加', 'addTemplate')
    .addToUi();
}

const body = DocumentApp.getActiveDocument().getBody();
var previousParagraph;
var templateParagraph;
const templateParagraphs = [];
function setup(body) {
  var inTemplate = false;
  body.getParagraphs().forEach((paragraph) => {
    if (!previousParagraph && paragraph.getText().startsWith('202')) {
      console.log("paragraph.getText()="+ paragraph.getText());
      previousParagraph = paragraph;
    }
    if (paragraph.getText().startsWith(templateDateFormat)) {
      templateParagraph = paragraph;
    }
  
    if (paragraph.getText() === templatePhrase) {
      inTemplate = true;
      return;
    }
    if (inTemplate) {
      templateParagraphs.push(paragraph.copy());
    }
  })
}

function getFacilitator() {
  var facilitatorText = templateParagraph.getText().split(" - ")[1];
  // console.log(facilitatorText);
  facilitators = facilitatorText.match(/(.*)/g)[0].slice(1, -1).split('→');
  var facilitator;
  if (previousParagraph == null) {
    facilitator = facilitators[0];
  } else {
    var previousFacilitator = previousParagraph.getText().split(" - ")[1];
    facilitators.push(facilitators[0]);
    facilitator = facilitators[facilitators.indexOf(previousFacilitator) + 1]
  }

  // console.log(facilitator);
  return facilitator;
}

function getMtgDate() {
  var previousDate;
  if (previousParagraph == null) {
    previousDate = new Date();
  } else {
    const previousDateStr = previousParagraph.getText().split(" - ")[0];
    previousDate = Utilities.parseDate(previousDateStr, "JST", "yyyy/MM/dd");
    previousDate.setDate(previousDate.getDate() + mtgIntervalDays);
  }
    
  var mtgDate = Utilities.formatDate(previousDate, 'JST', 'yyyy/MM/dd');
  // console.log(mtgDate);
  return mtgDate;
}

function addTemplate() {
  setup(body);
  
  // テンプレートパラグラフの挿入
  var horizontalRule = body.findElement(DocumentApp.ElementType.HORIZONTAL_RULE).getElement();
  var horizontalRuleIdnex = body.getChildIndex(horizontalRule.getParent()) + 1;
  templateParagraphs.forEach((paragraph, i) => {
    if (paragraph.getType() === DocumentApp.ElementType.LIST_ITEM) {
      body.insertListItem(i + horizontalRuleIdnex, paragraph);
    } else if (paragraph.getText().startsWith(templateDateFormat)) {
      paragraph.setText(getMtgDate() + " - " + getFacilitator());
      body.insertParagraph(i + horizontalRuleIdnex, paragraph);
    } else {
      body.insertParagraph(i + horizontalRuleIdnex, paragraph);
    }
  });
}

実装の内容を簡単に説明すると、templatePhraseと一致する部分を探しそれから下をテンプレートとしてコピー、ドキュメント内の区切り線(水平線)の下にテンプレートを挿入。このときその週の日付と司会を入れる。ようにしてます。

ドキュメントに戻ると、以下のようにメニューバーに「アジェンダ」→「テンプレート追加」というメニューが追加されているのが分かると思います。

一番最初に「テンプレート追加」を押すと許可を求められますが、許可してあげてください。 そして再度「テンプレート追加」を押すと今週のアジェンダが追加されます。

さて、毎回「テンプレート追加」を手動で押すのは面倒なので、自動化します。

Apps Scriptの左のメニューから「トリガー」を選択します。

そして「トリガーを追加」を選択し、実行する関数に「addTemplate」を選択します。

あとは実行したいスケジュール条件を入力します。定例MTGが終わった後実行するのがよいでしょう。

これで面倒な作業から解放されます。最高です。

Datadogのグラフにデプロイタイミングを表示する方法

Datadogのグラフをみていると、いつアプリケーションがデプロイされたのか気になることがあります。 「レスポンスタイムが急に悪くなってるけどデプロイ影響?」「エラーレートが跳ねるタイミングがあるけどデプロイ影響?」など。 そこでDatadogのグラフにデプロイタイミングを表示する方法を紹介します。

1, Event Overlays機能を使う

docs.datadoghq.com

以下の画面のように、表示したいDatadog Eventのクエリを入力します。

するとEvent発生日時がグラフ上に縦線で表示されます。

シンプルな方法ですが、デプロイするタイミングでDatadogにEventを送信する必要があります。 デプロイフローに追加が必要なのでできればDatadog内で完結したいです。

2, Show Overlays機能を使う

docs.datadoghq.com

※これを使うにはAPMを導入し、さらにVersion情報を送る必要があります。

ダッシュボード画面の右上のShow Overlaysをクリックします。 そしてChangesを選択し、Serviceからデプロイタイミングを知りたいサービスを選択します。

すると以下のようにデプロイタイミングが表示されます。

手軽でよいですが、

  • ダッシュボードによってはShow Overlaysが表示されない
  • Show this widget in full screen(ボタン) をおしてグラフを拡大表示するとデプロイタイミングの縦棒が表示されない

という課題があります。

3, Workflow Automationを使ってデプロイEventを自動で作成する

※これを使うにはAPMを導入し、さらにVersion情報を送る必要があります。

さて、本題です。

https://docs.datadoghq.com/ja/tracing/services/deployment_tracking/ docs.datadoghq.com

を読むと 「サービスの新しいデプロイが検出されるたびに、Deployment Tracking は time_between_deployments メトリクスの値を計算し、新しいデプロイとその前の最新バージョンのデプロイの間の秒数として計算されます。」とあります。そのためtime_between_deployments メトリクスを監視すればデプロイタイミングが分かります。

問題はEventをどう生成するかですが、DatadogのWorkflow Automationという機能を使います。

Workflow Automationはマイナーな機能かもしれませんが、非常に面白い機能です。 Workflow AutomationはIFTTTやZapierと似ていて、「トリガー」と「アクション」からなります。

トリガーには例えば以下が選べます

詳しくは ワークフローをトリガーする を参照ください。

アクションは、DatadogのEvent生成などDatadogへのアクションはもちろん、AWSなどのクラウドプロバイダー、SlackやGitHubなどのSaaS ツールへのアクションができます。 アクションの一覧は アクションカタログ を参照ください。

今回やりたいデプロイタイミングでDatadog Eventを生成するためには、

1, 以下の設定でworkflowを作成しておく

トリガーに「Monitor, Incident, or Security signal」を選択、アクションに「Datadog Create event」を選択

2, Monitorで time_between_deployments メトリクスを監視し0より大きい値になった場合、workflowをトリガーする

これでデプロイタイミングでDatadog Eventが生成されます。

あとは 1, Event Overlays機能を使うで紹介したやりかたでデプロイタイミングを表示すればOKです。

このやり方のデメリットとしては、「Monitorで監視する都合上、デプロイタイミングを監視したいだけなのにWarn/Alert扱いになる」のでちょっとだけ気持ち悪い点です。

Workflow Automationはなかなか夢が広がる機能だなと感じていて、 https://app.datadoghq.com/workflow/blueprints (要Datadogログイン) に使い方例があるので見てみると面白いと思います。

まとめ

Datadogのグラフにデプロイタイミングを表示する方法を紹介しました。 なんとかDatadogだけで完結してデプロイタイミングを表示できないか考えていたので、 time_between_deployments メトリクスとWorkflow Automationを組み合わせることでできて楽しかったです。

速く、もっと速く!Docker Build Cloudでイメージビルド時間を短縮する

2024/1/23に Docker Build Cloudが発表されました

www.docker.com

早速Docker Build Cloudを試してみました

Docker Build Cloudとは

サイト: https://www.docker.com/ja-jp/products/build-cloud/
ドキュメント: https://docs.docker.com/build/cloud/

イメージビルドをDocker社のCloud環境で行える機能です。 これによりどのようなメリットがあるかというと

  • イメージビルドキャッシュの共有
    • ローカルでイメージビルドするとき、もし他のユーザがビルド済みであればそのキャッシュを使うことができビルド時間が短縮できる
    • CI環境では毎回サーバーが違うため--mount=type=cacheが効かないがDocker Build Cloudであれば効く(!!)
    • ビルドキャッシュが存在するため--cache-fromのようにregistry cacheを使わなくてもよい。通常registry cacheを使うとかなりビルドが速くなるがregistry cache自体をpullする時間, pullしたイメージをextractする時間に地味に時間がかかるがそれがなくなる。
  • マルチアーキテクチャビルドが可能
  • CIツールとのシームレスな統合
    • ローカルのDockerやDocker Compose、GitHub ActionsやCircle CIなどのCIサービスと簡単に統合ができる

デメリットは、

  • Docker Build Cloudでビルドしたイメージをpullする時間がかかる
    • ただ変更があったimage layerだけがpullされるのでpullされるimage layerサイズが小さい場合はすぐ終わる
    • 2024/02/03現在 US Eastリージョンしかないため、Asiaからpullすると非常に時間がかかる。今後EuropeやAsiaリージョンのサポート予定
  • ビルドコンテキストをDocker Build Cloudに転送する時間がかかるケースがある
    • .dockerignoreを適切に設定していればビルドコンテキストサイズはそれほど大きくならないはずですが、何かしらの理由で大きなサイズの場合転送時間がネックになる可能性はあります。
  • planに含まれているビルド時間を超えてビルドしたい場合はビルド時間購入料金がかかる

料金に関して

無料PlanのDocker Personalだと 無料ビルド時間は 50分/月 です。かなり少ないですね。 Docker Teamに入っていれば 400分/月 のビルド時間が付与されますが、これは組織アカウント単位であり、ユーザ数あたりではないので注意。 このように無料付与枠がかなり少ないので本格的にDocker Build Cloudを使用する場合は Docker Build Cloud Team Planに入る必要があります。 年間払いだと $5/ユーザー/月、 月払いだと $6/ユーザー/月。 付与されるビルド時間は 200分/ユーザー/月 です。 これでも足りない場合はビルド時間を追加購入ことができます。

10,000分購入しても$500なのでかなり安い印象。

ちなみに、Docker Personal Planの無料枠の50minを使い切るとビルド時に

ERROR: failed to solve: FailedPrecondition: build cannot proceed build minutes limit of 50 reached

というエラーがでました。

使い方

https://build.docker.com/ にアクセスし、自分のprofileを選択します。

するとこういう画面がでるのでCreate new cloud builderからcloud builderを作成します。(この画面ではすでにmy-builderというcloud builderを作成済み)

作成したcloud builderをクリックすると、以下のような画面になります。

あとはSetup instructionsに表示される内容に沿って進めば簡単にDocker Build Cloudが使用できます。

実際速くなるのか?

イメージサイズが680MBになるDockerfileを使って試してみました。

ローカルでの使用

ローカルでのイメージビルドにDocker Build Cloudを使うメリットの一つはビルドキャッシュを共有出来る点です。
チームで開発をしている場合、フルビルドする場合イメージビルドに時間がかかります。 ビルドキャッシュを共有できれば他の人がすでにビルドした結果をpullすればよくなります。かなりイメージビルドが速くなりそうですよね。 しかし試してみると、Docker Build Cloudでビルドされたイメージをローカルにpullするのに長い時間がかかりました。 680MBのイメージをまるまるpullするのに6分くらい。更新されたimage layerだけをpullする場合でも330MBのサイズで190sくらい。更新されたimage layerのサイズが小さければ(1MB以下)なら数秒で終わりました。
これはDocker Build Cloudが2024/02/03現在、US Eastリージョンしかないため転送速度に時間がかかっているものと思われます。今後EuropeやAsiaリージョンのサポート予定だそうです。 Asiaリージョンのサポートがされてローカルでのpullが速くなればローカルでのDocker Build Cloudの使用も現実的になってくるかと思います。

CI上での使用

今回はCircleCIで試しました。
CircleCIはサーバーがUSリージョンにあるため、Docker Build Cloudでビルドしたイメージのpullにそれほど時間がかからないと見込んだからです。(GitHub Actionsは未調査)

CI上でのイメージビルドにDocker Build Cloudを使うメリットの一つはローカルでの使用と同様にビルドキャッシュを共有出来る点ですが、ポイントがローカルとは若干異なります。

  • Docker Build Cloudサーバーにビルドキャッシュ存在するため--cache-from, --cache-toのregistry cacheを使用しなくてよい。これによりregistry cacheイメージをpull&pushする時間, pullしたimageをextractする時間を削減できる
  • --mount=type=cacheが効く
    • たとえregistry cacheを使っていたとしてもアプリケーションで使うパッケージを更新した場合、ビルド時間がかかっていました。--mount=type=cacheを使うと追加/変更されたパッケージのみインストールすればよくなるためビルドが速くなりますが、CIでは毎回サーバーが異なるため--mount=type=cacheが使えないという課題がありました。Docker Build Cloudではビルドキャッシュが使えるため--mount=type=cacheが効きます。これによりアプリケーションで使うパッケージ更新時のイメージビルドが速くなります。

またもう一つのメリットはCIのサーバースペックを下げられる点です。イメージビルドを高速に行うにはサーバースペックが要求されるため、例えばCircleCIではresource classで大きめのclassを指定していた人も多いかと思います。Docker Build Cloudを使うとDocker Build CloudのサーバーはDocker Build Cloud Team Planの場合16 vCPU、32GB RAMのサーバーが割り当てられます。これによりCI側のサーバースペックを下げることができコスト削減ができる可能性があります。

さてローカルではDocker Build Cloudでビルドしたイメージのpullに時間がかかっていましたが、CircleCI上では680MBのイメージをまるまるpullするのに約20s、更新されたimage layerだけをpullする場合でも330MBのサイズで約10sでした。非常に速いですね。18倍も速いです。ただこれはDocker Build CloudのサーバーがAWS上にあり転送処理がAWSネットワーク内ですんでいるためかもしれません。
また--mount=type=cacheの指定も効いており、パッケージの更新処理も非常に速いです。registry cacheも必要ないためシンプルになります。

キャッシュサイズ

注意する点があるとすればビルドキャッシュサイズになります。
Docker Build Cloudではビルドキャッシュが保存されるわけですが、Docker Build Cloud Team Planの場合最大で200GiBになります。もし数多くのイメージをビルドする場合キャッシュ上限に達してしまう可能性があります。 なおキャッシュ上限に達すると、古いキャッシュは自動的に削除されます。
See: How do I manage the build cache with Docker Build Cloud?

FAQ

https://docs.docker.com/build/cloud/faq

まとめ

自分もそうですが、CI上でのイメージビルド高速化に苦労している人は少なくないと思います。ビルドキャッシュさえ存在すれば細かいことを考えずにすむのになと…よく思っていました。 Docker Build Cloudを使えば手軽かつ安価にイメージビルドの高速化ができそうです。 Productionで使われているイメージビルド処理が速くなるかは実際に試してみないと分からない部分もあるので仕事で検証をしていきたいと思います。

OpenSearchの手動スナップショットリポジトリ登録スクリプトをRubyで書く

OpenSearchで手動スナップショットを作成するためには、事前にスナップショットリポジトリの登録をしなければなりません。

docs.aws.amazon.com

公式ドキュメントのサンプルにはpythonのコードが掲載されています。
Using the sample Python client

この登録スクリプトRubyで書いてみました。

region = 'ap-northeast-1'
service = 'es'

# AWSの認証情報を取得
credentials = Aws::CredentialProviderChain.new.resolve
aws_signer = Aws::Sigv4::Signer.new(service: service, region: region, credentials_provider: credentials)

host = 'OpenSearchドメインエンドポイント'
path = '_snapshot/スナップショットリポジトリ名'
url = URI(host + path)

bucket_name = 'スナップショットS3バケット名'
role_arn = 'スナップショット IAM Role ARN'

payload = {
  type: 's3',
  settings: {
    bucket: bucket_name,
    region: region,
    role_arn: role_arn
  }
}.to_json

# AWSの署名付きリクエストを作成
signed_request = aws_signer.sign_request(
  http_method: 'PUT',
  url: url.to_s,
  headers: { 'Content-Type' => 'application/json' },
  body: payload
)
headers = signed_request.headers
headers['Content-Type'] = 'application/json'
response = Faraday.put(url, payload, signed_request.headers)

puts response.status
puts response.body

AWSの認証情報を取得の部分は各環境に応じて変更してください。
参考: AWSのSigV4署名を付与してIAM認証のAPI GatewayにHTTPリクエストを送るRubyとGoのサンプルコード #Ruby - Qiita

OpenSearchでVPC内にあるドメイン同士でRemote Reindexをする

はじめに

Amazon OpenSearch Serviceで、同一VPC内にあるドメイン同士でRemote Reindexをする方法を紹介します。

まず、公式ドキュメント docs.amazonaws.cn

前提条件

注意すべきは前提条件の部分です。

ドメインでデータ ノードに T2 または T3 インスタンス タイプを使用している場合、リモート再インデックスは使用できません。

検証用でT3インスタンスを使っている場合はインスタンスタイプを変更しましょう。

リモートドメインは、ローカルドメインからアクセス可能である必要があります。VPC 内に存在するリモートドメインでは、ローカルドメインVPC へのアクセスが必要です。このプロセスはネットワーク構成によって異なりますが、VPN またはマネージドネットワークへの接続、もしくは、ネイティブの VPC エンドポイント接続の使用が必要となる場合がほとんどです。詳細については、「VPC 内で Amazon OpenSearch Service ドメインを起動する」を参照してください

これは分かりにくいですが非常に重要です。次で説明をします。

組み込みのVPCエンドポイント接続機能

Migrating Amazon OpenSearch Service indexes using remote reindex - Amazon OpenSearch Service に説明がありますが、同一VPC内にあるドメイン同士であっても、組み込みのVPCエンドポイント接続機能を使ってローカルドメイン(データのコピー先)からリモートドメイン(データのコピー元)へのアクセスができるようにする必要があります。(てっきり同一VPC内にあれば設定いらんやろと思って読み飛ばしていたら必要でハマりました…)

組み込みのVPCエンドポイント接続機能とは?と思いますが、 このセクションReindex data with the Amazon Web Services Management Consoleにやり方が書いてますので、Remote Reindex APIの実行手前までそれ通り進めます。コンソールをぽちぽちやれば終わるはずです。

Remote Reindex API

さて、VPCエンドポイント接続設定が終わったらいよいよRemote Reindex APIの実行です。
ドキュメントには以下のように書かれていると思います。

POST _reindex
{
   "source":{
      "remote":{
         "host":"endpoint",
         "username":"username",
         "password":"password"
      },
      "index":"remote-domain-index-name"
   },
   "dest":{
      "index":"local-domain-index-name"
   }
}

きめ細かなアクセスコントロールを有効にしていて、かつユーザー管理にIAMを使用していない場合でなければusername, paswordはパラメーターとして渡さなくて大丈夫なはずです。
そうすると以下のようになりますが、

POST _reindex
{
   "source":{
      "remote":{
         "host":"endpoint"
      },
      "index":"remote-domain-index-name"
   },
   "dest":{
      "index":"local-domain-index-name"
   }
}

実行すると

  "error" : {
    "type" : "null_pointer_exception",
    "reason" : null
  }

といったエラーが返ってきます。

ドキュメントには書いてないですが、"external": trueオプション必要です。 medium.com の記事を見てやっとエラーが解消できました…。

最終的に以下の形になります。

POST _reindex
{
   "source":{
      "remote":{
         "host":"endpoint",
         "external": true
      },
      "index":"remote-domain-index-name"
   },
   "dest":{
      "index":"local-domain-index-name"
   }
}

なお"host":"endpoint"の部分の endpointOpenSearchドメインエンドポイントにport番号:443をつける必要があります。 つまりこんな感じになります。
"host": "https://hogehoge.ap-northeast-1.es.amazonaws.com:443"

まとめ

Amazon OpenSearch Serviceで、同一VPC内にあるドメイン同士でRemote Reindexをする方法を紹介しました。 remote reindexは snapshot&restoreと比べると snapshot用のS3バケットの作成, snapshotリポジトリの登録、それ用のIAM Role作成などをしなくていいので楽ですね。

ECRにリモートキャッシュ(--cache-to)のmode=maxでイメージプッシュする

2023/11/16 に BuildKit クライアント用の Amazon ECR でのリモートキャッシュサポートの発表 | Amazon Web Services ブログ という記事が発表されて、イメージビルド時のcache-toのオプションmode=maxが使えるようになった。
待望のアップデート。このissueを見たらどれだけ待ち望まれていたかが分かる。

以前まではECRはリモートキャッシュマニフェストに対応していなかったため、リモートキャッシュ先にECRを指定する場合はtype=inlineを指定する必要があった。(参考: Github Actionsのdocker/build-push-actionのcache-toにECRを指定する)

type=inlineだとmode=minしか指定出来ない。mode=minだと結果イメージのレイヤーしかキャッシュされず、マルチステージビルドを使用している場合中間イメージがキャッシュされず、イメージビルドが速くならないという問題があった。
max=modeはすべてのレイヤーをキャッシュするので、中間イメージが更新されてもキャッシュが効いてイメージビルドが速くなる。

リモートキャッシュに関しては Cache storage backends | Docker Docs を参照。

設定例

GitHub Actions

- name: Login to Amazon ECR
  id: login-ecr
  uses: aws-actions/amazon-ecr-login@v1

- uses: docker/build-push-action@v3
  with:
    push: true
    tags: ${{ steps.login-ecr.outputs.registry }}/${{ env.REPOSITORY_NAME }}:${{ github.sha }}
    provenance: false
    cache-from: type=registry,ref=${{ steps.login-ecr.outputs.registry }}/${{ env.REPOSITORY_NAME }}:buildcache
    cache-to: type=registry,mode=max,image-manifest=true,oci-mediatypes=true,ref=${{ steps.login-ecr.outputs.registry }}/${{ env.REPOSITORY_NAME }}:buildcache

CircleCI

- run:
    name: create builder instance
   # ビルダーインスタンスを作成しないとエラーになる
    command: docker buildx create --use  
- aws-ecr/build_and_push_image:
    account_id: ${AWS_ACCOUNT_ID}
    auth:
      - aws-cli/setup:
          role_arn: ${AWS_ROLE_ARN}
          region: ${AWS_DEFAULT_REGION}
    push_image: true
    region: ${AWS_DEFAULT_REGION}
    repo: ${REPOSITORY_NAME}
    tag: ${CIRCLE_SHA1}
    extra_build_args: >-
      --cache-from type=registry,ref=${REGISTRY_URL}/${REPOSITORY_NAME}:buildcache
      --cache-to type=registry,mode=max,image-manifest=true,oci-mediatypes=true,ref=${REGISTRY_URL}/${REPOSITORY_NAME}:buildcache
      --provenance=false

provenance=false にしている理由は docker/build-push-action v3.3.0で導入されたprovenanceオプションにまつわる問題 - chroju.dev を参照

EKS on FargateでのDatadog Cluster Agentの動かし方

概要

Fargate上でEKSのPodを動かしている場合に、Datadog Cluster Agentのマニフェストはどう定義すればいいか分かりづらかったのでメモとして残しておきます。

公式ドキュメント: https://docs.datadoghq.com/ja/integrations/eks_fargate/#cluster-agent-%E3%81%BE%E3%81%9F%E3%81%AF-cluster-checks-runner-%E3%81%AE%E5%AE%9F%E8%A1%8C

設定例

Datadog Cluster Agentをhelmでインストールします。 valuesファイルは以下のようにする。

# see: https://github.com/DataDog/helm-charts/tree/main/charts/datadog#values  
datadog:  
  apiKeyExistingSecret: datadog
agents:  
  enabled: false  
clusterAgent:  
  enabled: true  
  replicas: 2  
  shareProcessNamespace: true  
  tokenExistingSecret: datadog-cluster-agent
  env:  
  - name: DD_EKS_FARGATE  
    value: "true"  
  - name: DD_KUBERNETES_KUBELET_NODENAME  
    valueFrom:  
      fieldRef:  
        apiVersion: v1  
        fieldPath: spec.nodeName
  - name: DD_CLUSTER_NAME
    valueFrom:
      configMapKeyRef:
        key: DD_CLUSTER_NAME
        name: datadog
  resources:  
    requests:  
      cpu: 200m  
      memory: 256M  
    limits:  
      cpu: 200m  
      memory: 256M

datadog ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: datadog
data:
  DD_CLUSTER_NAME: my-cluster-name

datadog Secret

apiVersion: v1
kind: Secret
metadata:
  name: datadog
data:
  api-key: my-api-key

datadog-cluster-agent Secret

apiVersion: v1
kind: Secret
metadata:
  name: datadog-cluster-agent
data:
  token: my-datadog-cluster-agent-token # 32文字以上にすること。じゃないとエラーになる

Fargate上でPodを動かす場合、Datadog AgentコンテナはSidecarとして動かすことになります。 そのDatadog AgentコンテナにDatadog Cluster Agentコンテナと通信するための環境変数を渡してあげます。 必要な環境変数DD_CLUSTER_AGENT_ENABLEDDD_CLUSTER_AGENT_URLDD_CLUSTER_AGENT_AUTH_TOKENDD_ORCHESTRATOR_EXPLORER_ENABLEDです。

Sidecarの定義

spec:
  containers:
  - image: public.ecr.aws/datadog/agent:7.49.1
    name: datadog-agent
    env:
    - name: DD_API_KEY
      valueFrom:
        secretKeyRef:
          key: api-key
          name: datadog
    - name: DD_SITE
      value: datadoghq.com
    - name: DD_EKS_FARGATE
      value: "true"
    - name: DD_PROCESS_AGENT_ENABLED
      value: "true"
    - name: DD_KUBERNETES_KUBELET_NODENAME
      valueFrom:
        fieldRef:
          fieldPath: spec.nodeName
    - name: DD_CLUSTER_NAME
      valueFrom:
        configMapKeyRef:
          key: DD_CLUSTER_NAME
          name: datadog
    - name: DD_CLUSTER_AGENT_ENABLED
      value: "true"
    - name: DD_CLUSTER_AGENT_URL
      value: https://<CLUSTER_AGENT_SERVICE_NAME>.<CLUSTER_AGENT_SERVICE_NAMESPACE>.svc.cluster.local:5005
    - name: DD_CLUSTER_AGENT_AUTH_TOKEN
      valueFrom:
        secretKeyRef:
          key: token
          name: datadog-cluster-agent
    - name: DD_ORCHESTRATOR_EXPLORER_ENABLED # Kubernetes リソースビューを取得するために必要です
      value: "true"

うまくいかない場合

1, ログを確認

Datadog Cluster Agentコンテナのログ、Sidecarとして動かしているDatadog Agentコンテナのログを確認します。 INFOレベルログでうまくいかない原因が出力されていることもあります…。(DD_CLUSTER_AGENT_AUTH_TOKENの長さは32文字以上じゃないといけないとか)

2, agent statusで確認

Sidecarとして動かしているDatadog Agentコンテナにはいり、agent statusを実行し、 Datadog Cluster Agent欄を確認する。 Successfully Connected to the Datadog Cluster Agent.と出ていれば正常に設定がされています。

3, Sidecarとして動かしているDatadog AgentコンテナのPodのdnsPolicyDefaultになっていないか確認

DD_CLUSTER_AGENT_URLにDatadog Cluster Agent ServiceへURLを設定していますが、dnsPolicyDefaultでは名前解決できずエラーになります。 CoreDNSなどはdnsPolicyDefaultなのでそういったPodはDD_CLUSTER_AGENT_ENABLEDをfalseにするとよいでしょう。(他に良い解決方法があれば教えてください)