DockerCompose が複数あってもサービス名で名前解決させたい
前回の記事、"【2019年11月版】Quarkus で Hibernate-Panache の REST API 作ってネイティブ化し Jaeger でトレース"でコンテナを多数使用しました。
まずは ネイティブコンパイルしたバイナリが入った単体のコンテナ。cAdvisor + Prometheus + Grafana の監視系コンテナ群。そして PostgreSQLとJaegerのdocker-compose、の3グループで起動・停止するようにしておりました。
監視系のコンテナ群は "dockprom" というリポジトリのdcoekr-composeをそのまま使用しておりまして、Quarkus用のサーバー群と混ぜたくないな、ということと、Quarkusデモアプリのコンテナもdockpromには入れられないのでPostgreSQL+Jaeger側のdocker-composeに入れましょう、ということで2つのdocker-composeに落ち着きましたが・・・
dockprom は独立性を保ちたいので、dockpromのネットワーク設定は弄りたくないけど、dockpromのネットワークいじらないでPrometheusから別docker-composeに入ってるQuarkusを名前解決するってどうやって? という問題が立ち上がりました。
さらに、docker-composeのNetworkで "External" ってのは設定できますが、先にそのネットワークがないと起動時にエラーとなってしまいます。
つまり、
- Prometheus と Quarkus は別の docker-compose
- Prometheus から Quarkus をサービス名で参照したい
- Prometheus のネットワーク "monitor-net" に参加できるのは "monitor-net" が作成された後
- Quarkus が Prometheus と同じネットワークに参加するためには Prometheus コンテナが先に作成されている必要がある。
- 先に作成されているコンテナが、後から立ち上がるコンテナを名前解決するには・・・?
という問題が発生いたしました。
結論から言うと、"普通に、問題なくできる" でした。
ネットワークに参加すれば後からでも名前解決できるようになってました。。。
以下、前回の記事で作成したプロジェクトをベースに、具体的な設定方法をご説明いたします。
1. Prometheusの設定
まず、Prometheus で Quarkus のエンドポイントを参照する設定です。
ここが一番、悩ましい箇所だったのですが、結果的に普通に書いてOKだったのです。
...
- job_name: 'quarkus'
scrape_interval: 5s
static_configs:
- targets: ['quarkus:8082']
...
targets で quarkus:8082
と書いてOKでした。後で立ち上げる docker-compose で "quarkus"が存在すればちゃんと解決できるようになります。
このコンテナが作成された時点では名前解決できないはずなのに・・・よくやってるなぁ。。
2. dockprom の起動
以下の手順で dockprom/docker-compose.yml を起動します。
$ cd dockprom
$ docker-compose up
そしてここでネットワーク dockprom_monitor-net
が作成されます。
3. Quarkus 側の docker-compose
quarkus 用のコンテナは Dockerfile を作成して終わっておりましたが、ちゃんと docker-compose に入れました。
version : "3"
services:
quarkus:
build:
context: .
ports:
- 8082:8082
networks:
- default
- monitor-net
depends_on:
- jaeger
- db
...
networks:
monitor-net:
external:
name: dockprom_monitor-net
まず、サービス名は先のPrometheusの設定ファイルに書いた名前に合わせて quarkus
とします。これ重要ですね。
build、portsオプションは問題ないかと思います。
続いて networks ですが、下で定義する dockprom_monitor-net にリンクするネットーワーク に参加します。
そして、これだけでは db
や jaeger
が名前解決できなくなってしまう ので default
にも参加します。これがまた重要です。
depends_on
は後にも述べますがオマケみたいなもんです。。。
そして、外部ネットワークを参照する "external" ネットワークの定義です。
"external"の"name" はdocker-composeで定義する名前では足らず、docker network ls
で表示されるネットワーク名です。つまり、"フォルダ名_ネットワーク名"となります。
4. Quarkus の起動
docker-compose で depends_on
と定義しましたが、これはコンテナの作成順を指示するだけで、中のサービスが使えるようになるまでは待ってくれません。
試したところ、quarkus の起動が圧倒的に早く、PostgreSQL のポート待ち受けを待ってくれず、エラーになって起動しませんでした・・・
よって、ちょっと残念ですが、以下のように PostgreSQL だけ先に起動します。
$ docker-compose up -d db
...
# 一息入れて
$ docker-compose up -d
...
と、2段階で起動すればOKです。
5. 動作確認
localhost:8082
の quarkus にアクセスした後で localhost:9090
にアクセスすると、ちゃんとquarkus のメトリクスが取得されていることがわかります。
凡例の箇所にも quarkus:8082
とあるのでちゃんと quarkus:8082 のエンドポイントからデータを取得できているようです。
以上です!