HashiCorp Nomad で OpenTelemetry デモアプリを動かす
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.
みなさん…ついに技術バケットリストの項目に取り組めたので、とても興奮しています。 先週、OpenTelemetry デモアプリの Helm チャート を HashiCorp Nomad のジョブスペックに変換する作業を始めました。 今日は、お気に入りの Hashi オールインワンツールである HashiQube を使って、OpenTelemetry デモアプリを Nomad で動かす方法についてお話しします。
さあ、始めましょう!

デプロイ
前提知識
先に進む前に、以下の基本的な理解があることを前提としています。
- Nomad。 まだの方は、私の Nomad 入門記事をご覧ください。 Daniela Baron によるこちらのブログ記事もおすすめです。
- オブザーバビリティ(o11y)と OpenTelemetry(OTel)。 まだの方は、オブザーバビリティ入門をご覧ください。
前提条件
このチュートリアルの例を実行するには、以下が必要です。
チュートリアル用リポジトリ
今日のチュートリアルで使用するリポジトリは以下のとおりです。
- 私が変更を加えた HashiQube リポジトリ(servian/hashiqube のフォーク)。 興味がある方は、hashiqube に対して行った変更をご覧ください。
- 私の Nomad Conversions リポジトリ
HashiQube のセットアップ
始める前に、HashiQube はデフォルトで Nomad、Vault、Consul を Docker 上で実行することを改めてお伝えします。 さらに、Nomad に 21 個のジョブスペックをデプロイします。 これにはかなりの CPU と RAM が必要になるため、Docker Desktop に十分なリソースが割り当てられていることを確認してください。 参考までに、私は 8 コア、32 GB RAM の M1 MacBook Pro を使っています。 Docker Desktop のリソース設定は以下のとおりです。
- CPU: 3
- メモリ: 9.5GB
- スワップ: 3GB
視覚的に確認したい方のために、Docker Preferences のリソース設定のスクリーンショットを掲載します。

詳しくは、Docker のドキュメントでリソース設定の変更方法を確認してください。 Mac、Windows、Linux の各ドキュメントがあります。
1- /etc/hosts の更新
サービスの公開には Traefik ロードバランサーを使用しており、localhost のサブドメインとしてアクセスします。
Traefik で公開されたサービス(および Traefik ダッシュボード自体)にアクセスできるようにするために、ホストマシンの /etc/hosts に以下のエントリを追加する必要があります。
127.0.0.1 traefik.localhost
127.0.0.1 otel-demo.localhost
2- HashiQube でローカル Hashi 環境をプロビジョニングする
詳細なクイックスタート手順に従って HashiQube を起動します。
NOTE: 問題が発生した場合は、Gotchas セクションを確認してください。
すべてが起動して実行されると(これには数分かかります)、起動シーケンスの最後に以下のような表示が出て、準備完了となります。

以下の URL を使ってアプリにアクセスできるようになります。
- Vault: http://localhost:8200
- Nomad: http://localhost:4646
- Consul: http://localhost:8500
- Traefik: http://traefik.localhost
Nomad CLI と Vault CLI もダウンロードしてインストールしてください。
HashiQube に SSH 接続する必要がある場合は、ホストマシンで新しいターミナルウィンドウを開き、以下のコマンドを実行します。
vagrant ssh
3- OTel デモアプリのデプロイ
いよいよ OTel デモアプリをデプロイする準備が整いました!
まず、リポジトリをクローンして作業ディレクトリに移動します。
git clone https://github.com/avillela/nomad-conversions.git
cd nomad-conversions
次に、Nomad で Memory Oversubscription を有効にします。 これは一度だけ行う設定です。
nomad operator scheduler set-config -memory-oversubscription true
Memory Oversubscription を有効にすると、Nomad はジョブに割り当てられたメモリ以上のメモリを使用できるようになります。
たとえば、resources スタンザの以下の設定を考えてみましょう。
resources {
cpu = 55
memory = 1024
memory_max = 2048
}
ジョブに 55Mz の処理能力(cpu 設定)と 1024MB の RAM(memory 設定)を割り当てています。
この場合、Memory Oversubscription が有効で、ジョブが割り当てられた 1024MB 以上のメモリを必要とすると、Nomad はジョブに最大 2048MB の RAM を割り当てます(memory_max 設定)。
Memory Oversubscription が有効でない場合、Nomad は memory_max 設定を無視します。
次に、サービスをデプロイしましょう。
nomad job run -detach otel-demo-app/jobspec/traefik.nomad
nomad job run -detach otel-demo-app/jobspec/redis.nomad
nomad job run -detach otel-demo-app/jobspec/ffspostgres.nomad
nomad job run -detach otel-demo-app/jobspec/otel-collector.nomad
nomad job run -detach otel-demo-app/jobspec/adservice.nomad
nomad job run -detach otel-demo-app/jobspec/cartservice.nomad
nomad job run -detach otel-demo-app/jobspec/currencyservice.nomad
nomad job run -detach otel-demo-app/jobspec/emailservice.nomad
nomad job run -detach otel-demo-app/jobspec/featureflagservice.nomad
nomad job run -detach otel-demo-app/jobspec/paymentservice.nomad
nomad job run -detach otel-demo-app/jobspec/productcatalogservice.nomad
nomad job run -detach otel-demo-app/jobspec/quoteservice.nomad
nomad job run -detach otel-demo-app/jobspec/shippingservice.nomad
nomad job run -detach otel-demo-app/jobspec/checkoutservice.nomad
nomad job run -detach otel-demo-app/jobspec/recommendationservice.nomad
nomad job run -detach otel-demo-app/jobspec/frontend.nomad
nomad job run -detach otel-demo-app/jobspec/loadgenerator.nomad
nomad job run -detach otel-demo-app/jobspec/frontendproxy.nomad
nomad job run -detach otel-demo-app/jobspec/grafana.nomad
nomad job run -detach otel-demo-app/jobspec/jaeger.nomad
nomad job run -detach otel-demo-app/jobspec/prometheus.nomad
ジョブをデタッチモードで実行しているため、Nomad は現在のジョブのデプロイが正常に完了するのを待たずに次のジョブを開始します。 そのため、出力は以下のようになります。
Job registration successful
Evaluation ID: d3eaa396-954e-241f-148d-6720c35f34bf
Job registration successful
Evaluation ID: 6bba875d-f415-36b7-bfeb-2ca4b9982acb
Job registration successful
Evaluation ID: 16dc8ef8-5e26-68f4-89b6-3d96b348775b
Job registration successful
Evaluation ID: 34de0532-a3b5-8691-bf18-51c0cc030573
Job registration successful
Evaluation ID: 7310e6a2-9945-710b-1505-c01bd58ccd35
...
Evaluation ID の値はお使いのマシンでは異なりますのでご注意ください。
4- Nomad で確認する!
デプロイが進行中の間、http://localhost:4646 の Nomad UI にアクセスして進捗を確認できます。

すべてのサービスが起動するにはしばらく時間がかかります(最大 10 分程度)。 Nomad がイメージをダウンロードしてサービスを初期化する必要があるため、お待ちください! 一部のサービスは他のサービスに依存しているため、上のスクリーンキャプチャのように、サービスが待機状態になったり、しばらく起動と停止を繰り返したりすることがあります。 慌てないでください!すべてうまくいきます!!
すべてのジョブが起動して実行されると、以下のようにすべてが緑色になります。

http://localhost:8500 の Consul にアクセスして、サービスのヘルスチェック状態も確認できます。

デフォルトでは、不健全なサービスは赤い「x」マーク付きで上部に表示されます。 上のスクリーンショットにはいやな赤い「x」が見当たらないので、サービスは良好な状態です!
5- OTel デモアプリにアクセスする
OTel デモアプリは Envoy を使って複数のフロントエンドサービスを公開しています。
ウェブストア、Jaeger、Grafana、Load Generator、Feature Flag です。
これらはすべて frontendproxy サービスによって管理されています。
Traefik は frontendproxy サービスを otel-demo.localhost アドレスで公開しています。
これは frontendproxy.nomad の service スタンザ内の以下のコードスニペットで設定されています。
tags = [ "traefik.http.routers.frontendproxy.rule=Host(`otel-demo.localhost`)",
"traefik.http.routers.frontendproxy.entrypoints=web",
"traefik.http.routers.frontendproxy.tls=false",
"traefik.enable=true",
]
Host が otel-demo.localhost に設定されていることに注目してください。
サービスには以下の URL からアクセスできます。
ウェブストア: http://otel-demo.localhost/

望遠鏡やアクセサリの素晴らしいラインナップを探索して、いくつか購入してみてください😉🔭
Jaeger UI: http://otel-demo.localhost/jaeger/ui/

上のスクリーンキャプチャでは、checkoutservice からのサンプルトレースを確認できます。
Grafana: http://otel-demo.localhost/grafana/


デモアプリには 2 つの Grafana ダッシュボードが同梱されており、OpenTelemetry で出力されたメトリクスを表示します。
Feature Flags UI: http://otel-demo.localhost/feature/

Load Generator UI: http://otel-demo.localhost/loadgen/

注意点
OTel デモアプリを Nomad で動かすにあたって多くの問題を解消してきたと思いますが、サービスのデプロイ時にいくつかの問題に遭遇しました。
サービスが Collector に接続できないことがある
すべてのサービスが正常に起動しているように見えても、一部のサービスが OTel Collector に接続できないことがあります。
原因はまだ特定できていないので、現時点では otel-collector.nomad を再起動するだけです。
ウェブアプリの UI がおかしい場合(商品や通貨が表示されないなど)は、frontend.nomad も再起動します。
サービスがテレメトリーを Collector に送信していないことを示す良い指標は、Jaeger に表示されるサービスの数を確認することです。
jaeger-query サービスを含めて 14 個のサービスが表示されるはずです。

ホストマシンのメモリ不足
そう…私のマシンはかなりの性能ですが、ホストマシンのメモリが不足することもあります。 Chrome と Safari で大量のタブを開いていることも一因でしょう。 さらに正直に言うと、HashiQube と Nomad 上の 21 個のジョブはかなりのメモリを消費します。 HashiQube と Docker のメモリ設定にいくつかの調整を加えてメモリの問題を最小限に抑えるようにしていますが、メモリモンスターにやられてしまった場合は、ブラウザや他のアプリを閉じて再度開き、メモリを解放することをおすすめします。 もしこの問題が発生したら、ぜひ教えてください!
進行中のプロジェクト
このプロジェクトは進行中の作業であることをご了承ください。 改善の提案がある場合や、Nomad ジョブスペックのさらなる共同作業をご希望の場合は、ご連絡ください!
まとめ
以上です! これで OpenTelemetry デモアプリ(OpenTelemetry を実行するマルチマイクロサービスアプリ)を HashiCorp Nomad にデプロイする方法の例がわかりました。 主なポイントは以下のとおりです。
- HashiQube を使って、Docker 上の Nomad を介してローカルの HashiCorp 環境を構築し、Traefik をロードバランサーとして OTel デモアプリを Nomad で実行しました。
- frontendproxy を通じて公開された以下のサービスにアクセスして、OTel デモアプリの動作を確認しました。 ウェブストア、Grafana、Jaeger、Feature Flags UI、そして Load Generator UI。
締めくくる前に、Nomad ジョブスペックの調整を手伝ってくれた HashiCorp の Luiz Aoqui と、HashiQube の継続的な開発を行っている Riaan Nolan に大きな感謝を伝えたいと思います。 (余談ですが、Luiz と Riaan の両名は On-Call Me Maybe Podcast のゲストでした!)
最後に、ピンクのバスケットから顔を出すネズミのフィービーの写真をお届けします。 かわいくないですか?🥰

Peace, love, and code. 🦄 🌈 💫
Nomad 上の OTel デモアプリについて質問がありますか? Mastodon または LinkedIn でお気軽にご連絡ください。
OpenTelemetry コミュニティは常にコントリビューションを求めています! ぜひご参加ください! Mastodon をお使いの方は、Mastodon の OpenTelemetry をフォローしてください。