Skip to content
Published on

Traefik 完全ガイド — IngressRoute、ミドルウェア、動的設定

Authors

はじめに

Kubernetes クラスタを運用していると、外部トラフィックを内部サービスへルーティングする入口(ingress)が必ず必要になります。標準の Ingress リソースだけではパス書き換え、認証、レート制限といった要件を表現しづらく、コントローラごとにアノテーション構文が異なるため移植性が低下します。

Traefik は、こうした制約を動的設定(dynamic configuration)とミドルウェア(middleware)という概念で解決したクラウドネイティブなエッジルーターです。Go で書かれた単一バイナリであり、Kubernetes CRD、標準 Ingress、Docker、Consul など複数のプロバイダ(provider)を同時に監視しながら、ルーティングルールをリアルタイムに再構成します。設定ファイルを再読み込みしたりプロセスを再起動したりする必要はありません。

本記事では Traefik のコア概念を順を追って押さえたうえで、IngressRoute CRD とミドルウェアチェイニング、Let's Encrypt による自動 TLS、ダッシュボード、そして 2026 年現在の標準となった Gateway API との関係まで、実践的な例とともに見ていきます。最後に Helm デプロイとよく遭遇する落とし穴も整理します。

本記事は次の読者を対象としています。

  • Kubernetes で ingress-nginx の代わりに Traefik の導入を検討している方
  • 標準 Ingress のアノテーション地獄から抜け出したい方
  • 自動 TLS とミドルウェアチェイニングを宣言的に管理したい方
  • Ingress から Gateway API への移行経路を検討している方

Traefik アーキテクチャを一望する

Traefik のルーティングモデルは 4 つのコアオブジェクトで構成されます。リクエストが入ってきてからバックエンドの Pod に到達するまでの流れを理解すると、残りの設定がはるかに簡単になります。

                  インターネット / 外部クライアント
                            |
                            v
   +-------------------------------------------------+
   |                  EntryPoint                     |
   |     (:80 web / :443 websecure ポートで受信)      |
   +-------------------------------------------------+
                            |
                            v
   +-------------------------------------------------+
   |                    Router                       |
   |  ルールマッチ: Host(`app.example.com`) && Path   |
   |  一致したら Middleware チェインへ渡す             |
   +-------------------------------------------------+
                            |
                            v
   +-------------------------------------------------+
   |          Middleware チェイン (順番どおり)         |
   |   auth -> redirect -> ratelimit -> stripprefix  |
   +-------------------------------------------------+
                            |
                            v
   +-------------------------------------------------+
   |                   Service                       |
   |  ロードバランシング先 (k8s Service / Pod)        |
   +-------------------------------------------------+
                            |
                            v
                    バックエンド Pod

EntryPoint

EntryPoint は Traefik がトラフィックを受信するネットワークの入口です。通常は静的設定(static configuration)で定義し、ポートとプロトコルを指定します。慣例的に 80 番ポートを web、443 番ポートを websecure と呼びます。

# traefik.yml (静的設定)
entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
          permanent: true
  websecure:
    address: ":443"
    http:
      tls: {}
  metrics:
    address: ":9100"

上の例では web に入ってきたすべての HTTP リクエストが websecure(HTTPS)へ恒久的にリダイレクトされます。EntryPoint 単位でグローバルなリダイレクトをかけるのは非常によくあるパターンです。

Router

Router は入ってきたリクエストをどのルールでマッチさせるかを定義します。Host、Path、Header、Method など多様なマッチャ(matcher)を論理演算子で組み合わせられます。

# 動的設定の例
http:
  routers:
    my-app:
      rule: "Host(`app.example.com`) && PathPrefix(`/api`)"
      entryPoints:
        - websecure
      middlewares:
        - strip-api-prefix
      service: my-app-service
      tls:
        certResolver: letsencrypt

ルール(rule)はバッククォートで囲んだ値で表現します。優先度(priority)は既定ではルール長を基準に自動計算されますが、priority フィールドで直接指定することもできます。

Middleware

Middleware は Router と Service の間でリクエストまたはレスポンスを加工する段階です。認証、ヘッダ追加、パス書き換え、レート制限、圧縮など数十種類の組み込みミドルウェアが提供され、複数をチェインとして連結できます。チェインの順番が動作に直接影響するため、順序の設計が重要です。

Service

Service は実際のバックエンドを指し、ロードバランシング戦略(weighted round robin)、ヘルスチェック、スティッキーセッションといったオプションを定義します。Kubernetes では通常クラスタの Service リソースにマッピングされます。

Provider

Provider は Traefik が設定を読み込むソースです。要点は Traefik が複数のプロバイダを同時に監視するという点です。Kubernetes 環境では主に次の 2 つを使います。

プロバイダ説明使用リソース
kubernetesCRDTraefik 専用 CRD ベースIngressRoute、Middleware など
kubernetesIngress標準 Ingress リソースを処理Ingress、IngressClass
kubernetesGatewayGateway API 標準を処理Gateway、HTTPRoute
# 静的設定でプロバイダを有効化
providers:
  kubernetesCRD:
    allowCrossNamespace: false
  kubernetesIngress:
    ingressClass: traefik
  kubernetesGateway: {}

Ingress と IngressRoute CRD の違い

ここは Traefik 入門者が最も混乱しやすいポイントです。どちらの方式もトラフィックをルーティングしますが、表現力と移植性に大きな差があります。

標準 Ingress の限界

標準 Ingress は Kubernetes 公式リソースなので移植性が高い一方、仕様そのものは host と path ベースのルーティング程度しか標準化されていません。それ以外のすべての高度な機能(書き換え、認証、レート制限など)はコントローラ固有のアノテーションに依存します。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app
  annotations:
    traefik.ingress.kubernetes.io/router.middlewares: default-auth@kubernetescrd
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
spec:
  ingressClassName: traefik
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-app-service
                port:
                  number: 80

ご覧のとおり、ミドルウェアを付けるにはアノテーション文字列に依存する必要があり、この構文は他のコントローラへそのまま移すことはできません。2026 年現在、標準 Ingress API は凍結(frozen)状態です。つまりこれ以上新しい機能は追加されず、コミュニティの発展方向は Gateway API へ移っています。

IngressRoute CRD

IngressRoute は Traefik が定義した CRD で、ルーティングルールとミドルウェア、TLS 設定をアノテーションなしで明示的な YAML フィールドとして表現します。

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: my-app
  namespace: default
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`app.example.com`) && PathPrefix(`/api`)
      kind: Rule
      priority: 10
      middlewares:
        - name: api-auth
        - name: strip-api-prefix
      services:
        - name: my-app-service
          port: 80
  tls:
    certResolver: letsencrypt

次の表で両方式を比較します。

項目標準 IngressIngressRoute CRD
移植性高い (k8s 標準)低い (Traefik 専用)
ミドルウェア表現アノテーション文字列ネイティブフィールド
マッチングルールhost / path 中心Host、Header、Method など豊富
TCP / UDP ルーティング不可IngressRouteTCP / UDP 対応
優先度制御限定的priority フィールドで明示
今後の標準凍結済みTraefik 依存

結論として、移植性が最優先なら標準 Ingress または Gateway API を、Traefik のすべての機能を活用したいなら IngressRoute を選びます。ただし新規プロジェクトであれば、後述する Gateway API を優先的に検討するのが 2026 年基準では合理的です。

ミドルウェアチェイニングの実践

ミドルウェアは Traefik の最も強力な機能です。各ミドルウェアを独立した CRD として定義し、IngressRoute から順番に参照してチェインを構成します。よく使う 4 つを見ていきます。

1. ベーシック認証 (BasicAuth)

まず資格情報を格納した Secret を作り、ミドルウェアから参照します。

apiVersion: v1
kind: Secret
metadata:
  name: dashboard-auth-secret
  namespace: default
type: Opaque
stringData:
  users: |
    admin:$apr1$abcd1234$encryptedpasswordhash
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: api-auth
  namespace: default
spec:
  basicAuth:
    secret: dashboard-auth-secret
    removeHeader: true

users の値は htpasswd で生成したハッシュ形式である必要があります。removeHeader を true にすると、認証後に Authorization ヘッダをバックエンドへ転送しません。

2. リダイレクト (RedirectScheme / RedirectRegex)

HTTP を HTTPS へ強制したり、特定のパスパターンを別の場所へ送ったりできます。

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: https-redirect
  namespace: default
spec:
  redirectScheme:
    scheme: https
    permanent: true
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: legacy-redirect
  namespace: default
spec:
  redirectRegex:
    regex: "^https://old.example.com/(.*)"
    replacement: "https://new.example.com/${1}"
    permanent: true

3. レート制限 (Rate Limit)

毎秒または毎分のリクエスト数を制限してバックエンドを保護します。average は許容する平均速度、burst は瞬間的な許容量です。

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: api-ratelimit
  namespace: default
spec:
  rateLimit:
    average: 100
    burst: 50
    period: 1s
    sourceCriterion:
      ipStrategy:
        depth: 1

sourceCriterion でクライアントを識別する基準を定めます。プロキシの背後にいる場合は ipStrategy.depth で X-Forwarded-For ヘッダから実際のクライアント IP を抽出するよう設定します。

4. StripPrefix

バックエンドがルートパス(/)を期待しているのに、外部からは特定の prefix でアクセスする場合、パスの先頭部分を取り除きます。

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: strip-api-prefix
  namespace: default
spec:
  stripPrefix:
    prefixes:
      - /api
    forceSlash: false

このミドルウェアが適用されると、外部からの /api/users リクエストはバックエンドへ /users として渡されます。

ミドルウェアチェインの構成と順序

複数のミドルウェアを IngressRoute で配列として並べると、その順番どおりに適用されます。順序を誤ると意図と異なる動作になるため注意が必要です。

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: secure-api
  namespace: default
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`api.example.com`)
      kind: Rule
      middlewares:
        - name: https-redirect
        - name: api-auth
        - name: api-ratelimit
        - name: strip-api-prefix
      services:
        - name: api-service
          port: 8080
  tls:
    certResolver: letsencrypt

上記のチェインは次の順番で動作します。

リクエスト
  -> https-redirect   (HTTP なら HTTPS へリダイレクト)
  -> api-auth         (認証の通過判定)
  -> api-ratelimit    (リクエスト速度の制限)
  -> strip-api-prefix (パス prefix の除去)
  -> api-service      (バックエンドへ転送)

原則として、コストが安く拒否される可能性が高いミドルウェア(リダイレクト、認証、レート制限)を前方に置き、不要な処理を早期に遮断するのがよいです。パス加工のような変換は後方に置きます。

自動 TLS — Let's Encrypt ACME

Traefik の魅力的な機能の一つが、Let's Encrypt による証明書の自動発行と更新です。ACME プロトコルを内蔵しているため、別途 cert-manager がなくても動作します。

ACME チャレンジ方式

ACME はドメイン所有権を証明する 3 つのチャレンジをサポートします。

チャレンジ動作方式ワイルドカード証明書
HTTP-0180 番ポートで検証トークンを応答不可
TLS-ALPN-01443 番ポートで TLS ハンドシェイク不可
DNS-01DNS TXT レコードで検証可能
# 静的設定 — HTTP-01 チャレンジ
certificatesResolvers:
  letsencrypt:
    acme:
      email: ops@example.com
      storage: /data/acme.json
      httpChallenge:
        entryPoint: web

ワイルドカード証明書が必要なら DNS-01 チャレンジを使う必要があります。DNS プロバイダ(例: Cloudflare、Route53)の API トークンを環境変数として注入します。

certificatesResolvers:
  letsencrypt-dns:
    acme:
      email: ops@example.com
      storage: /data/acme.json
      dnsChallenge:
        provider: cloudflare
        resolvers:
          - "1.1.1.1:53"

acme.json ファイルは発行された証明書と秘密鍵を保存するため、権限を 600 に制限し、永続ボリューム(PVC)に保存する必要があります。Pod が複数にスケールすると、同じファイルを同時に書き込んで競合する可能性があるため、マルチレプリカ環境では cert-manager を別途使うか、証明書発行を単一インスタンスに制限するほうが安全です。

ダッシュボード

Traefik は現在、Router、Service、Middleware の状態を視覚的に表示する Web ダッシュボードを提供しています。運用中のルーティング構成を素早く確認するのに便利です。

# 静的設定でダッシュボードと API を有効化
api:
  dashboard: true
  insecure: false

insecure を true にすると認証なしで公開されるため、本番環境では絶対に使ってはいけません。代わりに IngressRoute でダッシュボードを公開し、BasicAuth ミドルウェアをかけて保護します。

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-dashboard
  namespace: traefik
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`traefik.example.com`)
      kind: Rule
      middlewares:
        - name: dashboard-auth
      services:
        - name: api@internal
          kind: TraefikService
  tls:
    certResolver: letsencrypt

Service に api@internal という内部 TraefikService を指定している点に注目してください。これは Traefik 内部の API ハンドラを指す特殊な参照です。

Gateway API 対応

2026 年基準で最も重要な流れは Gateway API です。前述のとおり標準 Ingress は凍結され、Kubernetes ネットワーキングの次世代標準は Gateway API に定まりました。Gateway API は役割分離(インフラ運用者は Gateway、アプリ開発者は HTTPRoute)と豊かなルーティング表現力を標準 CRD として提供します。

Traefik は Gateway API 実装として適合認証を受けており、kubernetesGateway プロバイダを通じて標準リソースを処理します。つまり IngressRoute の表現力をベンダー依存なしに標準として得られます。

apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: traefik
spec:
  controllerName: traefik.io/gateway-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: traefik-gateway
  namespace: traefik
spec:
  gatewayClassName: traefik
  listeners:
    - name: web
      protocol: HTTP
      port: 80
    - name: websecure
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: example-tls
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: my-app-route
  namespace: default
spec:
  parentRefs:
    - name: traefik-gateway
      namespace: traefik
  hostnames:
    - "app.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /api
      backendRefs:
        - name: my-app-service
          port: 80

次の表は 3 つの方式の位置づけを整理したものです。

方式標準かどうか表現力推奨する状況
標準 Ingressk8s 標準(凍結)低い単純なルーティング、レガシー
IngressRouteTraefik 専用高いTraefik の高度な機能が必要
Gateway APIk8s 標準(発展中)高い新規プロジェクト推奨

当面は Gateway API のミドルウェア表現が IngressRoute ほど豊かでない場合があり、両方式を併用する過渡的な運用もよく見られます。長期的には Gateway API へ収束する方向を推奨します。

デプロイ実践 — Helm values

本番環境では公式 Helm チャートで Traefik をデプロイするのが一般的です。次は実践でよく使う values の例です。

# リポジトリ追加とインストール
helm repo add traefik https://traefik.github.io/charts
helm repo update
helm install traefik traefik/traefik \
  --namespace traefik --create-namespace \
  --values values.yaml
# values.yaml
deployment:
  replicas: 2

ingressClass:
  enabled: true
  isDefaultClass: true

providers:
  kubernetesCRD:
    enabled: true
    allowCrossNamespace: false
  kubernetesIngress:
    enabled: true
  kubernetesGateway:
    enabled: true

ports:
  web:
    redirectTo:
      port: websecure
  websecure:
    tls:
      enabled: true

certificatesResolvers:
  letsencrypt:
    acme:
      email: ops@example.com
      storage: /data/acme.json
      httpChallenge:
        entryPoint: web

persistence:
  enabled: true
  size: 128Mi
  path: /data

dashboard:
  enabled: true

resources:
  requests:
    cpu: 100m
    memory: 128Mi
  limits:
    cpu: 500m
    memory: 256Mi

logs:
  general:
    level: INFO
  access:
    enabled: true

インストール後、次のコマンドで状態を確認します。

kubectl get pods -n traefik
kubectl get svc -n traefik
kubectl logs -n traefik deploy/traefik --tail=100

運用とチューニング

アクセスログとメトリクス

本番環境ではアクセスログを JSON 形式で残し、Prometheus メトリクスを有効化して可観測性を確保します。

metrics:
  prometheus:
    entryPoint: metrics
    addEntryPointsLabels: true
    addServicesLabels: true

accessLog:
  format: json
  filters:
    statusCodes:
      - "400-499"
      - "500-599"

statusCodes フィルタを使うと 4xx、5xx 応答のみをロギングし、ログ量を減らせます。

ヘルスチェックとプローブ

Traefik 自体の readiness、liveness プローブは ping EntryPoint を通じて構成します。

ping:
  entryPoint: web

タイムアウトのチューニング

長時間の接続や大容量アップロードを扱う場合は、EntryPoint のトランスポートタイムアウトを調整します。

entryPoints:
  websecure:
    address: ":443"
    transport:
      respondingTimeouts:
        readTimeout: 60s
        writeTimeout: 60s
        idleTimeout: 180s

落とし穴とトラブルシューティング

運用中によく遭遇する問題を整理しました。

1. 404 または Router がマッチしない

最もよくある原因は EntryPoint 指定の漏れです。IngressRoute に entryPoints を明示しないと、すべての EntryPoint に公開されたり、意図したポートに入ってこなかったりすることがあります。まずダッシュボードで該当 Router が登録されているか、ルールが正しいかを確認してください。

# Router の状態を API で照会
kubectl port-forward -n traefik deploy/traefik 8080:8080
curl http://localhost:8080/api/http/routers

2. ミドルウェアが見つからない

別の名前空間のミドルウェアを参照するには名前空間を明示する必要があります。IngressRoute のアノテーション方式では name-namespace@kubernetescrd の形を使います。また allowCrossNamespace が false だとクロス名前空間参照がブロックされます。

3. 証明書が発行されない

HTTP-01 チャレンジは 80 番ポートが外部から到達可能である必要があります。ファイアウォールやロードバランサの設定を確認してください。acme.json ファイルの権限が 600 でないと Traefik が拒否します。また、マルチレプリカで同じ acme.json を共有すると発行が乱れることがあります。

4. StripPrefix 後にバックエンドが壊れる

バックエンドアプリケーションが絶対パスで静的リソースを参照していると、prefix を除去したあとにリンクが壊れることがあります。この場合はアプリケーションに base path を設定するか、replacePathRegex ミドルウェアでより精密にパスを扱う必要があります。

5. 実際のクライアント IP が見えない

クラウドロードバランサの背後にいると、レート制限やログに LB の IP しか記録されないことがあります。forwardedHeaders.trustedIPs を設定し、レート制限ミドルウェアの ipStrategy.depth を環境に合わせて調整する必要があります。

entryPoints:
  websecure:
    address: ":443"
    forwardedHeaders:
      trustedIPs:
        - "10.0.0.0/8"
        - "172.16.0.0/12"

おわりに

Traefik は動的設定、ミドルウェア、自動 TLS を一つにまとめ、Kubernetes ingress を宣言的に運用できるようにする強力なツールです。IngressRoute CRD は標準 Ingress のアノテーション地獄から抜け出させてくれますが、ベンダー依存というコストが伴います。

2026 年現在、標準 Ingress は凍結され、Gateway API が次世代標準として定着しました。Traefik は Gateway API を正式にサポートしているため、新規プロジェクトであれば Gateway API を優先的に検討しつつ、Traefik のミドルウェアエコシステムが必要な部分では IngressRoute を併用する戦略が現実的です。コア概念(EntryPoint、Router、Middleware、Service、Provider)を正確に理解すれば、どの方式を選んでも揺らぐことなく運用できます。

参考資料