【2019年度11月版】複数のdocker-composeをまたいでコンテナの名前解決をする

# DockerCompose が複数あってもサービス名で名前解決させたい

前回の記事、"[【2019年11月版】Quarkus で Hibernate-Panache の REST API 作ってネイティブ化し Jaeger でトレース](https://qiita.com/koinori/items/244f0ecb8fd7ecd4f34f)"でコンテナを多数使用しました。

まずは ネイティブコンパイルしたバイナリが入った単体のコンテナ。cAdvisor + Prometheus + Grafana の監視系コンテナ群。そして PostgreSQLとJaegerのdocker-compose、の３グループで起動・停止するようにしておりました。
監視系のコンテナ群は "dockprom" というリポジトリのdcoekr-composeをそのまま使用しておりまして、Quarkus用のサーバー群と混ぜたくないな、ということと、Quarkusデモアプリのコンテナもdockpromには入れられないのでPostgreSQL+Jaeger側のdocker-composeに入れましょう、ということで２つのdocker-composeに落ち着きましたが・・・

**dockprom は独立性を保ちたいので、dockpromのネットワーク設定は弄りたくないけど、dockpromのネットワークいじらないでPrometheusから別docker-composeに入ってるQuarkusを名前解決するってどうやって？** という問題が立ち上がりました。

さらに、docker-composeのNetworkで "External" ってのは設定できますが、先にそのネットワークがないと起動時にエラーとなってしまいます。

つまり、

1. Prometheus と Quarkus は別の docker-compose
2. Prometheus から Quarkus をサービス名で参照したい
3. Prometheus のネットワーク "monitor-net" に参加できるのは "monitor-net" が作成された後
4. Quarkus が Prometheus と同じネットワークに参加するためには Prometheus コンテナが先に作成されている必要がある。
5. 先に作成されているコンテナが、後から立ち上がるコンテナを名前解決するには・・・？

という問題が発生いたしました。

結論から言うと、"**普通に、問題なくできる**" でした。

ネットワークに参加すれば後からでも名前解決できるようになってました。。。

以下、前回の記事で作成したプロジェクトをベースに、具体的な設定方法をご説明いたします。

## 1. Prometheusの設定

まず、Prometheus で Quarkus のエンドポイントを参照する設定です。
ここが一番、悩ましい箇所だったのですが、結果的に普通に書いてOKだったのです。

```yml:dockprom/prometheus/promethus.yml
...
  - job_name: 'quarkus'
    scrape_interval: 5s
    static_configs:
      - targets: ['quarkus:8082']
...
```

targets で `quarkus:8082` と書いてOKでした。後で立ち上げる docker-compose で "quarkus"が存在すればちゃんと解決できるようになります。

このコンテナが作成された時点では名前解決できないはずなのに・・・よくやってるなぁ。。

## 2. dockprom の起動

以下の手順で dockprom/docker-compose.yml を起動します。

```shell
$ cd dockprom
$ docker-compose up
```
そしてここでネットワーク  `dockprom_monitor-net` が作成されます。

## 3. Quarkus 側の docker-compose 

quarkus 用のコンテナは Dockerfile を作成して終わっておりましたが、ちゃんと docker-compose に入れました。

```yml
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 だけ先に起動します。

```shell
$ docker-compose up -d db
...
# 一息入れて
$ docker-compose up -d
...
```
と、２段階で起動すればOKです。

## 5. 動作確認

`localhost:8082` の quarkus にアクセスした後で `localhost:9090` にアクセスすると、ちゃんとquarkus のメトリクスが取得されていることがわかります。

![Prometheus Time Series Collection and Processing Server.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335150/6561aa56-852b-6408-01c1-3ba4df7088ec.png)

凡例の箇所にも `quarkus:8082` とあるのでちゃんと quarkus:8082 のエンドポイントからデータを取得できているようです。

以上です！