はじめに
こんにちは。WebikeでエンジニアをしているHidekiです。
以前コンテナ化されたLaravelアプリケーションをTraefik環境下にデプロイするという案件があったので、Traefikの使い方についてお話しようと思います。
Traefikとは
traefikとは動的な設定が可能な、エッジルーター(ロードバランサー&リバースプロキシ)です。
オープンソースでGo言語で開発されています。
Traefik Labsというフランスの企業で開発されています。
ACMEクライアントなので、Let’s Encryptの無料SSL証明書を容易に取得することが可能です。
画像引用元: https://traefik.io/
構築してみる
今回構築する構成は下図の通りです。
画像引用: https://github.com/hdk-t/traefik-example
- コンテナ管理にDocker Composeを使用する
- リクエストパスに応じて各コンテナにリバースプロキシさせる
- 3台のNginxコンテナはラウンドロビンでロードバランシングさせる
環境
- Docker 20.10.17
- Docker Compose 1.29.2
ディレクトリ構造
traefik-example
┣ gateway
┃ ┣ traefik
┃ ┃┣ access.log
┃ ┃┗ traefik.yml
┃ ┗ docker-compose.yml
┗ web
┗ docker-compose.yml
Traefikの設定について
traefikの設定方法は大きく2種類あります
- 静的設定(Static Configuration)
- 設定ファイルはyaml記法または、toml記法で記述します
- 静的設定の変更にはコンテナの再起動が必要です
- 動的設定(Dynamic Configuration)
- 動的設定をする方法はいくつか存在します(Docker,設定ファイル,k8s etc..)
- 設定ファイルで設定する場合は静的設定と同様にyaml記法または、toml記法で記述します
- 動的設定の変更はコンテナの再起動を必要としません
今回は静的設定にyamlファイル、動的設定の方法にDockerを使用します。
Dockerを使用した動的設定の方法は、コンテナのラベルにTraefikの属性を付与することで設定できます。
Traefikは常に同じdocker networkのコンテナを監視しており、それらの変更や追加を検知することで動的設定を実現させています。
Traefikの静的設定
./gateway/traefik/traefik.yml
providers:
docker:
exposedByDefault: false
network: proxy
watch: true
entrypoints:
http:
address: ":80"
forwardedHeaders:
insecure: true
trustedIPs:
- "127.0.0.1/32"
- "172.0.0.1/8"
- "192.168.0.0/16"
api:
dashboard: true
insecure: false
log:
level: INFO
experimental:
http3: true
global:
sendAnonymousUsage: false
accessLog:
filePath: "/var/logs/access.log"
bufferingsize: 100
filters:
statuscodes:
- "100-599"
retryattempts: true
minduration: "100ms"
fields:
names:
StartUTC: drop
設定内容を要点だけ簡単に説明すると
providers: docker
- 動的設定方法にdocker
- 他の設定は公式ドキュメントを参照
dashboard: true
- Traefikのダッシュボードを有効化
- ベーシック認証を設定できるが、今回は検証なので設定しません
entrypoints: http
- 今回はhttpポートのみ開放
- httpsにする場合は同様に設定が必要
- httpにアクセスが来たらhttpsにリダイレクトさせる設定を入れることもできる
Traefikコンテナのdocker-compose.yml(動的設定)
./gateway/docker-compose.yml
version: '3'
networks:
traefik_example_network:
external: true
services:
traefik:
image: traefik:v2.6.1
restart: always
environment:
- TZ=Japan
ports:
- target: 80
published: 80
protocol: tcp
mode: host
security_opt:
- no-new-privileges:true
networks:
- traefik_example_network
volumes:
- ./logs:/var/logs
- ./traefik:/etc/traefik
- /var/run/docker.sock:/var/run/docker.sock:ro,cached
labels:
### traefik configration
- traefik.enable=true
- traefik.http.routers.dashboard.rule=(Host(`traefik.localhost`))
- traefik.http.routers.dashboard.service=api@internal
traefik.http.routers.dashboard.rule=(Host(`traefik.localhost`))
traefik.localhost のドメインでアクセスしてきたら、Traefikのダッシュボードにプロキシさせます。
Webサーバーのdocker-compose.yml(動的設定)
./web/docker-compose.yml
version: '3'
networks:
traefik_example_network:
external: true
services:
nginx:
image: nginx
restart: always
networks:
- traefik_example_network
labels:
### traefik configration
- traefik.enable=true
- traefik.http.routers.nginx.rule=PathPrefix(`/nginx`)
- traefik.http.services.nginx.loadbalancer.server.port=80
- traefik.http.middlewares.nginx-omitprefix.stripprefix.prefixes=/nginx
- traefik.http.routers.nginx.middlewares=nginx-omitprefix
apache:
image: httpd
restart: always
networks:
- traefik_example_network
labels:
### traefik configration
- traefik.enable=true
- traefik.http.routers.apache.rule=PathPrefix(`/apache`)
- traefik.http.services.apache.loadbalancer.server.port=80
- traefik.http.middlewares.apache-omitprefix.stripprefix.prefixes=/apache
- traefik.http.routers.apache.middlewares=apache-omitprefix
traefik.http.routers.nginx.rule=PathPrefix(`/nginx`)
traefik.http.routers.apache.rule=PathPrefix(`/apache`)
NginxとApacheも同様にプロキシさせる条件を設定します。
コンテナの起動とスケールアップ
設定ファイルの記述が完了したら、docker networkを作成して、コンテナを立ち上げます。
ネットワークを作成
docker network create traefik_example_network
Traefikコンテナを起動
docker-compose -f ./gateway/docker-compose.yml up -d
ApatchとNginxを起動
docker-compose -f ./web/docker-compose.yml up -d
この時点で下記にアクセスできるハズです。
※ hostsでループバックアドレスにlocalhostが設定されてる前提です
127.0.0.1 localhost
traefikのダッシュボード
http://traefik.localhost
Nginx
http://localhost/nginx
Apache
http://localhost/apache
上記が確認できたら、Nginxを3台にスケールアップしてみましょう。
docker-compose -f ./web/docker-compose.yml scale nginx=3
これで、構成図の状態になりました。
docker ps
access.logを見るとNginxへのアクセスはラウンドロビンでロードバランシングされている事が確認できます。
./traefik/acccess.log
さいごに
このようにTraefikを使用することで簡単にリクエストを捌くことができました。
サブドメインで振り分けられるのがとても便利ですね。
使いどころとしては、1つのホストに複数のサービスコンテナを稼働させる際に便利です。
また、動的設定を使用すれば設定変更時に再起動が不要のため、他のサービスのダウンタイム無しで設定変更を行うことが可能です。
弊社では一部業務Webアプリケーションのリバースプロキシとして使用しています。
ニッチな技術なのでググっても参考文献が見つかりにくいところがデメリットです。