docker-composeでリバースプロキシとしてtraefikを使う

はじめに

traefikを紹介したいと思います。 マイクロサービスアーキテクチャを採用すると、複数のサービスを一つのエンドポイントでURLのパスによって、マイクロサービスA,Bに振り分けるケースがあります。クラウドサービスを利用しているとGCPのCloud Load BalancingやAWS ELBなどを利用して、ルーティングルールを設定します。一方、ローカル開発だとリバースプロキシで代用することができると思います。リバースプロキシがないと、それぞれのマイクロサービスのポートを開いたりすることになり、ポートが衝突したりして不都合が悩みでした。 ローカル開発は個人的にはdocker-composeをよく利用するのですが、traefikというリバースプロキシを使ってパスに基づいたルーティングをしてみます。

traefikとは

Traefik is a leading modern reverse proxy and load balancer that makes deploying microservices easy. Traefik integrates with your existing infrastructure components and configures itself automatically and dynamically.

出典: What is Traefik? - Wikipedia

訳すると、Traefikは、主要なモダンリバースプロキシでありロードバランサーで、マイクロサービスのデプロイを簡単にします。Traefikは、既存のインフラストラクチャコンポーネントと統合し、自動的かつ動的に構成します。

個人的に気に入っているのは、docker-composeのlabelを追加するだけで、ルーティングのコントロールができるところです。これによって、docker-compose.ymlだけみれば、どのようなルーティングをしているか明白で、手軽に利用できます。 こういうところは、nginxより後発のtraefikの方がモダンであると思います。

docker-composeの設定を行う

公式からdocker-composeの例を参考にして以下のようなdocker-compose.ymlを作成します。 service-a,service-bというマイクロサービスがある想定でtraefikでPathPrefix Ruleを使って、それぞれルーティングしたいと思います。実際のマイクロサービスはAPIを提供すると思いますが、説明をシンプルにするためnginxで代用します。 traefikのコンテナ部分は公式からそのまま変更なしです。

version: "3.3"

services:

  traefik:
    image: "traefik:v2.5"
    container_name: "traefik"
    command:
      #- "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  service-a:
    image: nginx
    volumes:
      - ./service-a:/usr/share/nginx/html/service-a
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.service-a.rule=PathPrefix(`/service-a`)" #/service-aは、service-aにルーティングする
      - "traefik.http.routers.service-a.entrypoints=web"

  service-b:
    image: nginx
    volumes:
      - ./service-b:/usr/share/nginx/html/service-b
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.service-b.rule=PathPrefix(`/service-b`)" #/service-bは、service-bにルーティングする
      - "traefik.http.routers.service-b.entrypoints=web"

docker-compose upする

docker-compose upしてルーティング出来ているか確認してみます。

docker-compose up -d
curl -L http://localhost/service-a
# service-a
curl -L http://localhost/service-b
# service-b

きちんと振り分けられていそうですね。

リファレンスをみると、他にもHost名や優先度など、いろんなルールを追加することが出来ます。

まとめ

モダンなリバースプロキシであるtraefikをdocker-composeでローカル開発で用いることを紹介しました。 これでマイクロサービスが増えてきても、ローカル開発でポートが衝突することは少なくできそうです。

全てのソースコードはこちら