クイック エンジニアリングブログ

株式会社クイック Web事業企画開発本部のエンジニアリングチームが運営する技術ブログです。

【Docker Traefik】「URL Pathマッチングによる複数Webコンテナへの振り分け」実装

こんにちは。クイックSREチームのみっちーです。

突然ですが、みなさんは「Traefik」はご存知でしょうか。
TraefikはGo言語で書かれた軽量Edge Routerで、簡単にLoad Balancerとして利用できるのが大変魅力的ですね。
今回は、そのTraefikを利用して「URL Pathマッチングによる複数Webコンテナへの振り分け」をやってみました。docs.traefik.io

Traefikは公式ドキュメントも充実していて比較的扱いやすい印象がありますが、Pathマッチングによる振り分けの実装方法にちょっと癖があります。
記事も少なく初実装時にかなりハマってしまったので、同様にお困りの方の助けになれば幸いです。

今回の記事は、こんな人向けです。

  • Docker、Docker Compose は触ったことがある。
  • Traefikは知らない。もしくは、知ってるけど「URL Pathマッチングによる振り分け」がうまく行かない。

1. 下準備

今回は、TraefikコンテナWeb(apache)コンテナを利用します。
コンテナを利用するために、まずは「Docker」と「Docker-Compose」を準備しましょう。
※ 「Docker」 と 「Docker Compose」 は触ったことがある人を前提とするので、install方法はここでは割愛します。

準備ができたら次に進みます。

2. traefik.toml を書く

  • /etc/traefik/traefik.toml

Traefikコンテナを起動する前に、設定ファイルを準備しましょう。
こんな感じで、ほぼそのまま公式にあったものを流用して書いてみます。
logの出力有無などの細かいところは、必要に応じて適宜変更してください。

debug = true
logLevel = "DEBUG"

defaultEntryPoints = ["http"]

[entryPoints]
  [entryPoints.http]
  address = ":80"

[web]
address = ":8080"

3. docker-compose.ymlを書く

今回の主題となる「URL Pathマッチングによる振り分け」の部分です。
構成は、テストなので「 Traefik & Web(Apache2.4系)×2台」の最小構成です。
※ 少々見ずらいですが、#で設定のポイントを書いてます。

version: '2'

services:
  proxy:
    image: traefik:latest
    command: --api --docker --docker.domain=traefik.local --logLevel=DEBUG
    container_name: test_proxy
    networks:
      - testnw
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
# 上記で作成したtraefik.toml を、コンテナ側の「/etc/traefik/traefik.toml 」にマウントします。
      - /home/vagrant/test/traefik.toml:/etc/traefik/traefik.toml  

  web01:
    image: httpd:2.4
    container_name: test_web01
    networks:
      - testnw
    expose:
      - "80"
    labels:
      - "traefik.port=80"
# アクセス用のドメイン名を記載。localhostで良ければ書かなくてもOKです。
# 振り分け条件を書かない場合は、「/」にマッチングします。
# 以下は、http://test919.domain.dayo/*  でのURLマッチング例(ただし、~/web02/*は、後続のweb02で設定している条件にマッチするので除外)
      - "traefik.frontend.rule=Host: test919.domain.dayo" 
# Pathマッチングの優先度。数字の高いものが優先的にマッチングします。
      - "traefik.frontend.priority=10"

  web02:
    image: httpd:2.4
    container_name: test_web02
    networks:
      - testnw
    expose:
      - "80"
    labels:
      - "traefik.port=80"
# アクセス用ドメイン名の指定に続いて、「PathPrefix: /{prefix:マッチング文字列}{any_任意の文字列:(/.*)?$$}」 でマッチング構文が書けます。 
# 以下は、http://test919.domain.dayo/web02/* でのURLマッチング例。
      - "traefik.frontend.rule=Host: test919.domain.dayo; PathPrefix: /{prefix:web02}{any_web02:(/.*)?$$}" 
# Pathマッチングの優先度はweb01より高くします。低くすると、「/」 でマッチングするweb01へすべて流れてしまいます。
      - "traefik.frontend.priority=20"

networks:
  testnw:
    driver: bridge
    driver_opts:
      com.docker.network.enable_ipv6: "false"

4. コンテナを起動してアクセスしてみる

起動してアクセスしてみましょう。

# docker-compose -f /home/vagrant/test/docker-compose.yml up -d
[vagrant@localhost test]$ curl -H 'Host:test919.domain.dayo' http://localhost/index.html
web01

[vagrant@localhost test]$ curl -H 'Host:test919.domain.dayo' http://localhost/web02/index.html
web02

※ 今回はテストのため事前に、web01のindex.htmlに「web01」と、web02では~/web02/index.html に「web02」と記載して保存してあります。

こんな感じでうまく振り分けられましたね。

いかがでしたか?少々癖のあるTraefikのURL Pathマッチングですが、うまく使えれば手軽にAWSのApplication Load Balancerのようなことができるのがいいですね。

もし気になる設定があれば、上記以外でもコメントいただければ幸いです。
可能な範囲で検証してみようと思います。


\\『真のユーザーファーストでマーケットを創造する』仲間を募集中です!! //

919.jp