はじめに
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 つを使います。
| プロバイダ | 説明 | 使用リソース |
| --- | --- | --- |
| kubernetesCRD | Traefik 専用 CRD ベース | IngressRoute、Middleware など |
| kubernetesIngress | 標準 Ingress リソースを処理 | Ingress、IngressClass |
| kubernetesGateway | Gateway 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
次の表で両方式を比較します。
| 項目 | 標準 Ingress | IngressRoute 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-01 | 80 番ポートで検証トークンを応答 | 不可 |
| TLS-ALPN-01 | 443 番ポートで TLS ハンドシェイク | 不可 |
| DNS-01 | DNS 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 つの方式の位置づけを整理したものです。
| 方式 | 標準かどうか | 表現力 | 推奨する状況 |
| --- | --- | --- | --- |
| 標準 Ingress | k8s 標準(凍結) | 低い | 単純なルーティング、レガシー |
| IngressRoute | Traefik 専用 | 高い | Traefik の高度な機能が必要 |
| Gateway API | k8s 標準(発展中) | 高い | 新規プロジェクト推奨 |
当面は 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)を正確に理解すれば、どの方式を選んでも揺らぐことなく運用できます。
参考資料
- [Traefik 公式ドキュメント](https://doc.traefik.io/traefik/)
- [Traefik Kubernetes IngressRoute ガイド](https://doc.traefik.io/traefik/routing/providers/kubernetes-crd/)
- [Traefik Helm Charts](https://github.com/traefik/traefik-helm-chart)
- [Kubernetes Ingress の概念](https://kubernetes.io/docs/concepts/services-networking/ingress/)
- [Gateway API 公式ドキュメント](https://gateway-api.sigs.k8s.io/)
- [Let's Encrypt ドキュメント](https://letsencrypt.org/docs/)
- [cert-manager ドキュメント](https://cert-manager.io/docs/)
- [Helm 公式ドキュメント](https://helm.sh/docs/)
- [ingress-nginx ドキュメント](https://kubernetes.github.io/ingress-nginx/)
현재 단락 (1/441)
Kubernetes クラスタを運用していると、外部トラフィックを内部サービスへルーティングする入口(ingress)が必ず必要になります。標準の Ingress リソースだけではパス書き換え、認証、...