🕺

複数の Docker Compose 構成を用いた Traefik の構築

2022/07/21に公開

結論から言うと

GitHub のリポジトリから成果物を拝める。READMEについてはあまり気にしてはいけない。

以下、詳細。


動機

Dockerは便利なのでローカルだったりOCIだったりでたくさん使っている。K8Sは私がアヒルなせい[1]でよくわからず、Docker Compose 止まりではある。どうであれ、環境の分離や冪等性のある構築といった点から、考えられるワークフローの大部分において使わない手がまったくない。

問題がある。docker-compose.yml が長過ぎる。密度が高すぎる。もちろん疎結合や密結合という話をしたいのではない。この時勢を見ればわかるように、密集密閉密接という三密[2]は非常によろしくない。大体今日これを書いている時点で東京の感染者数は3万を越えている。完全に第七波が到来している。感染症対策のため、docker-compose.yml は複数のファイルに分割しなければならない。まあ他の理由もなくはない[3]

言うまでもなく、分割をするとコロナへの対策がより効果的になるものと推測される。副次的効果として、docker-compose.ymlの保守性の増加・見通しの良さの改善といった点が挙げられる。

要件

  1. 複数の docker-compose.yml を用いて構成を別個のファイルに分割する。
    • 具体的には Traefik の構成と(モック用の)nginx の構成は別ファイルに分割する。
    • 今回は Traefik, nginx(A), nginx(B) となった。
  2. Traefik が :443(と :80)を受け付けることにする。HTTPSも Traefik だけで終端させる。
    • 証明書の取得は Cloudflare による DNS チャレンジを用いる。動機に直接結びついているものではないので、これについては多く言及しない[4]
    • Traefik には ACME を扱える機構が存在する。Let's Encrypt は ACME を喋るので、Traefik と Let's Encrypt をお互いに喋らせれば外部の機構を導入する必要はない。イメージを続くツイートの画像に示す。

https://twitter.com/hisasu77/status/1182927285646544898

  1. 各 Docker Compose 環境単位が部分的にダウンしても影響が全体に及ばないようにする。

    • nginx(B)が死んでもnginx(A)に繋げないとか、そういうのはないようにする。
  2. (結果論だが)三回目のワクチン接種後に検証することになったので、身体に気をつける。

    • ファイザーなので一回目・二回目のモデルナよりは副作用が弱いはずである……
    • 二回目のモデルナはやばかった。39度もの高熱が二日にわたり続いた。

分割と検証

GitHub のリポジトリを見てほしいんだけど(逐一書くのめんどくさい)、重要と思われる部分を抜粋して書く。

1. Traefik

https://github.com/akaregi/traefik-compose-test/blob/master/traefik/docker-compose.yml#L14-L26

このあたりで言う事はあまりないだろう。--providers.docker.exposedbydefault=false で無差別にコンテナを吸わないようにする[5]

https://github.com/akaregi/traefik-compose-test/blob/master/traefik/docker-compose.yml#L28-L33

証明書の取得を記述する。Traefik は面倒くさいことをしなくても宣言的記述でHTTPSまで持ち込めてしまえるため非常に見通しのよい設定にできる。その上 certbot などを別途動かさなくてよいために可搬性も高まる。

この設定は DNS に Cloudflare を用いていて、かつ DNS チャレンジを通じて証明書を取得する場合である。また ${CA_EMAIL}docker-compose.yml と同じフォルダに置かれる .env から取得される環境変数である。

2. NGINX[6]

https://github.com/akaregi/traefik-compose-test/blob/master/nginx-a/docker-compose.yml#L10-L16

必要ならドメインの解決(Host(...))を書き換える。ちなみにドメインは localhost でも完璧に動作した。HTTPSさえ気にしなければ、ホストから test-a.localhost みたいにアクセスできる。

結果

要件は大筋で達成できたので良いのではないか。ワクチンの副作用も強くでなかったので、頭痛薬代わりに用いた生理の薬[7]を飲んだらどうにかなった。万々歳。皆様もコロナにお気をつけて。


備考

docker-compose から docker compose への読み替え

もし Docker Compose の構築に docker-compose コマンドを用いている場合、それはほとんど副作用なしに docker compose にそのまま読み替えられる。そして docker compose のほうが多少マシであり、ハイフンのある方はこの先保守されないとかそういう話がある。

RHEL系OS固有の問題? IPマスカレードの設定

OCI(ORACLE Cloud Infrastructure)の名でお察しの通り、ホストOSは Oracle Linux である。おそらく、RHEL系のOSでは IP マスカレードに関する設定がになっている[8]。何が悪いかというと、コンテナ間通信が正常に動作せず、おそらく Ubuntu が前提となっている他の資料の大半が動作しないために CYKA BLYAT[9] を連発することになる。

この問題の解決には IP マスカレードの設定を firewall-cmd 経由で当てればよい。以下に参考リンクを示す。

https://genchan.net/it/virtualization/docker/12786/

リンクによれば、設定は次のようになる。最後に Docker サービスを再起動する。

$ firewall-cmd --add-masquerade --permanent
$ firewall-cmd --reload
脚注
  1. ネイティブなアヒルの鳴き声を出せるせいで、調子にのってクェクェ言ってたらアヒルにされました。 ↩︎

  2. 最近言わないね? ↩︎

  3. 知識不足のためわからない、複数の Docker Compose 環境間でコンテナは通信してくれるのかとかそういった疑問を解消したい、みたいな。 ↩︎

  4. 最終的にインターネットに乗せたが、検証だけならローカルでも大半を達成できる ↩︎

  5. これで Traefik はラベルtraefik.enable=trueのついたコンテナのみを扱うようになる。 ↩︎

  6. 私の友人は nginx のことを「んぎんくす」と読んでいた。興味深い………… ↩︎

  7. 副作用を止めようとして薬の副作用が起きたらどうするんだ?という懸念はあったが成分を見る限り頭痛薬とそう変わらなかった。 ↩︎

  8. 「『ぽ』になる」という表現は私の身内特有の表現である。意味は「『ぽ』になる」と同一である。 ↩︎

  9. 原義では сука блять であり、ь の発音を意識するのがコツらしい。言語学的には、/t/ が軟音になる。 ↩︎

Discussion