Traefik

クラウドネイティブ環境に特化したリバースプロキシ。DockerやKubernetesとの統合により、動的な設定管理を実現。自動サービス発見とロードバランシング機能。

reverse-proxydockerkubernetesmicroservicescloud-nativeload-balancergo

Traefik Proxy

Traefikはクラウドネイティブ環境に特化したリバースプロキシ・ロードバランサーです。DockerやKubernetesとの緊密な統合により、コンテナやサービスの動的な発見と設定管理を自動化し、マイクロサービスアーキテクチャに最適化された設計を提供します。

主な特徴

動的サービス発見(Service Discovery)

  • 自動設定: コンテナやサービスの起動・停止を自動検出
  • 多プロバイダー対応: Docker、Kubernetes、Consul、Etcdなど
  • リアルタイム更新: 設定変更時のゼロダウンタイム
  • ラベルベース設定: Dockerラベルによる直感的な設定

Let's Encrypt統合

  • 自動SSL証明書: ACME対応による自動取得・更新
  • DNS Challenge: DNS-01チャレンジによる証明書取得
  • ワイルドカード証明書: サブドメイン用の包括的な証明書
  • 複数CA対応: 複数の認証局からの証明書取得

高性能・可観測性

  • Go言語実装: 高いパフォーマンスと低リソース消費
  • メトリクス統合: Prometheus、DataDog、Jaegerサポート
  • ヘルスチェック: バックエンドの健全性監視
  • サーキットブレーカー: 障害時の自動回復機能

インストール方法

Docker

# 最新のTraefikイメージを取得
docker pull traefik:v3.4

# シンプルな実行
docker run -d \
  --name traefik \
  -p 80:80 \
  -p 443:443 \
  -p 8080:8080 \
  -v /var/run/docker.sock:/var/run/docker.sock:ro \
  traefik:v3.4 \
  --api.insecure=true \
  --providers.docker=true \
  --providers.docker.exposedbydefault=false \
  --entrypoints.web.address=:80 \
  --entrypoints.websecure.address=:443

Docker Compose

version: '3.8'

services:
  traefik:
    image: traefik:v3.4
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"  # ダッシュボード
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik.yml:/etc/traefik/traefik.yml:ro
      - ./dynamic.yml:/etc/traefik/dynamic.yml:ro
      - traefik-certs:/certs
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.dashboard.rule=Host(`traefik.localhost`)"
      - "traefik.http.routers.dashboard.tls=true"
      - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
    networks:
      - traefik-network

volumes:
  traefik-certs:

networks:
  traefik-network:
    external: true

Kubernetes (Helm)

# Traefikリポジトリを追加
helm repo add traefik https://traefik.github.io/charts
helm repo update

# 基本インストール
helm install traefik traefik/traefik

# カスタム設定でインストール
helm install traefik traefik/traefik \
  --set ports.web.redirectTo=websecure \
  --set ingressRoute.dashboard.enabled=true \
  --set providers.kubernetesIngress.enabled=true

バイナリインストール

# Linux x86_64
curl -L https://github.com/traefik/traefik/releases/download/v3.4.0/traefik_v3.4.0_linux_amd64.tar.gz \
  | tar -xzf -
sudo mv traefik /usr/local/bin/
sudo chmod +x /usr/local/bin/traefik

# 設定ファイルとサービスファイルを作成
sudo mkdir -p /etc/traefik
sudo systemctl enable traefik

基本設定

静的設定(traefik.yml)

global:
  checkNewVersion: false
  sendAnonymousUsage: false

api:
  dashboard: true
  debug: true

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entrypoint:
          to: websecure
          scheme: https
  websecure:
    address: ":443"
    http3:
      enabled: true

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
    network: traefik-network
  file:
    filename: /etc/traefik/dynamic.yml
    watch: true

certificatesResolvers:
  letsencrypt:
    acme:
      email: [email protected]
      storage: /certs/acme.json
      httpChallenge:
        entryPoint: web
      # DNS Challenge
      dnsChallenge:
        provider: cloudflare
        delayBeforeCheck: 60

log:
  level: INFO
  filePath: "/var/log/traefik/traefik.log"

accessLog:
  filePath: "/var/log/traefik/access.log"
  format: json

動的設定(dynamic.yml)

http:
  middlewares:
    secure-headers:
      headers:
        accessControlAllowMethods:
          - GET
          - OPTIONS
          - PUT
        accessControlMaxAge: 100
        hostsProxyHeaders:
          - "X-Forwarded-Host"
        sslRedirect: true
        stsSeconds: 63072000
        stsIncludeSubdomains: true
        stsPreload: true
        frameDeny: true
        contentTypeNosniff: true
        browserXssFilter: true
        customRequestHeaders:
          X-Forwarded-Proto: https

    compress:
      compress: {}

    auth:
      basicAuth:
        users:
          - "admin:$2y$12$..." # htpasswd -nB admin

tls:
  options:
    default:
      sslStrategies:
        - "tls.SniStrict"
      minVersion: "VersionTLS12"
      cipherSuites:
        - "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
        - "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305"
        - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"

Docker統合

アプリケーション配備

version: '3.8'

services:
  webapp:
    image: nginx:alpine
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.webapp.rule=Host(`app.example.com`)"
      - "traefik.http.routers.webapp.entrypoints=websecure"
      - "traefik.http.routers.webapp.tls=true"
      - "traefik.http.routers.webapp.tls.certresolver=letsencrypt"
      - "traefik.http.services.webapp.loadbalancer.server.port=80"
      # セキュリティミドルウェア
      - "traefik.http.routers.webapp.middlewares=secure-headers@file,compress@file"
    networks:
      - traefik-network

  api:
    image: node:alpine
    command: ["node", "server.js"]
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`api.example.com`)"
      - "traefik.http.routers.api.entrypoints=websecure"
      - "traefik.http.routers.api.tls.certresolver=letsencrypt"
      - "traefik.http.services.api.loadbalancer.server.port=3000"
      # レート制限
      - "traefik.http.middlewares.api-ratelimit.ratelimit.burst=100"
      - "traefik.http.routers.api.middlewares=api-ratelimit"
    networks:
      - traefik-network

networks:
  traefik-network:
    external: true

ロードバランシング

version: '3.8'

services:
  web1:
    image: nginx:alpine
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.web.rule=Host(`load-balanced.example.com`)"
      - "traefik.http.services.web.loadbalancer.server.port=80"
    networks:
      - traefik-network

  web2:
    image: nginx:alpine
    labels:
      - "traefik.enable=true"
      - "traefik.http.services.web.loadbalancer.server.port=80"
    networks:
      - traefik-network

  web3:
    image: nginx:alpine
    labels:
      - "traefik.enable=true"
      - "traefik.http.services.web.loadbalancer.server.port=80"
      # ヘルスチェック設定
      - "traefik.http.services.web.loadbalancer.healthcheck.path=/health"
      - "traefik.http.services.web.loadbalancer.healthcheck.interval=30s"
    networks:
      - traefik-network

Kubernetes統合

IngressRoute設定

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: webapp-ingressroute
  namespace: default
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`app.example.com`)
      kind: Rule
      services:
        - name: webapp-service
          port: 80
      middlewares:
        - name: auth
  tls:
    certResolver: letsencrypt

---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: auth
  namespace: default
spec:
  basicAuth:
    secret: auth-secret

Helm Values(本格運用向け)

# values.yaml
deployment:
  kind: DaemonSet  # 全ノードに配置

service:
  type: LoadBalancer
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: nlb

ports:
  web:
    redirections:
      entryPoint:
        to: websecure
        scheme: https
        permanent: true
  websecure:
    http3:
      enabled: true

providers:
  kubernetesIngress:
    enabled: true
    ingressClass: traefik
  kubernetesCRD:
    enabled: true
    ingressClass: traefik
  kubernetesGateway:
    enabled: true

certificatesResolvers:
  letsencrypt:
    acme:
      email: [email protected]
      storage: /data/acme.json
      dnsChallenge:
        provider: route53
        
persistence:
  enabled: true
  size: 128Mi

metrics:
  prometheus:
    service:
      enabled: true
    serviceMonitor:
      enabled: true

ingressRoute:
  dashboard:
    enabled: true
    matchRule: Host(`traefik.example.com`)
    entryPoints: ["websecure"]
    middlewares:
      - name: auth

extraObjects:
  - apiVersion: v1
    kind: Secret
    metadata:
      name: auth-secret
    type: kubernetes.io/basic-auth
    stringData:
      username: admin
      password: secure-password

高度な機能

マイクロサービス向けAPI Gateway

# トラフィック分割
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: wrr-service
spec:
  weighted:
    services:
      - name: app-v1
        port: 80
        weight: 90
      - name: app-v2
        port: 80
        weight: 10

---
# カナリアデプロイメント
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: canary-deployment
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`api.example.com`) && Headers(`X-Canary`, `true`)
      kind: Rule
      services:
        - name: app-v2-service
          port: 80
    - match: Host(`api.example.com`)
      kind: Rule
      services:
        - name: app-v1-service
          port: 80

認証・認可

# OAuth2認証
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: oauth2-auth
spec:
  forwardAuth:
    address: http://oauth2-proxy.auth.svc.cluster.local:4180
    authResponseHeaders:
      - X-Auth-User
      - X-Auth-Email

---
# JWT認証
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: jwt-auth
spec:
  plugin:
    jwt:
      secret: your-jwt-secret
      algorithm: HS256

セキュリティ強化

# レート制限とIPホワイトリスト
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: security-middleware
spec:
  chain:
    middlewares:
      - name: ip-whitelist
      - name: rate-limit
      - name: secure-headers

---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: ip-whitelist
spec:
  ipWhiteList:
    sourceRange:
      - 192.168.1.0/24
      - 10.0.0.0/8

---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: rate-limit
spec:
  rateLimit:
    burst: 100
    period: 1m

監視とログ

Prometheus統合

# prometheus設定
metrics:
  prometheus:
    addEntryPointsLabels: true
    addServicesLabels: true
    buckets:
      - 0.1
      - 0.3
      - 1.2
      - 5.0

構造化ログ

log:
  level: INFO
  format: json
  filePath: "/var/log/traefik/traefik.log"

accessLog:
  format: json
  filePath: "/var/log/traefik/access.log"
  fields:
    defaultMode: keep
    names:
      ClientUsername: drop
    headers:
      defaultMode: keep
      names:
        User-Agent: keep
        Authorization: drop
        Content-Type: keep

分散トレーシング

tracing:
  jaeger:
    samplingParam: 1.0
    localAgentHostPort: jaeger-agent:6831
  # または
  datadog:
    localAgentHostPort: datadog-agent:8126
    globalTag: datacenter:us-east

パフォーマンス最適化

接続プール調整

serversTransport:
  maxIdleConnsPerHost: 200
  forwardingTimeouts:
    dialTimeout: 30s
    responseHeaderTimeout: 60s
    idleConnTimeout: 90s

HTTP/3とQUIC

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

キャッシュ設定

http:
  middlewares:
    cache:
      plugin:
        cache:
          maxExpiry: 300s
          cleanup: 600s
          excludedHeaders:
            - Authorization
            - Cookie

本番環境での運用

高可用性設定

# HA構成でのクラスター設定
cluster:
  store: consul
  prefix: traefik

providers:
  consul:
    rootKey: traefik
    endpoints:
      - consul1:8500
      - consul2:8500
      - consul3:8500

セキュリティベストプラクティス

# セキュアな設定
api:
  dashboard: true
  debug: false
  insecure: false

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

トラブルシューティング

一般的な問題

  1. 証明書取得エラー
# ログ確認
docker logs traefik 2>&1 | grep -i acme

# DNS設定確認
dig _acme-challenge.example.com TXT
  1. サービス発見の問題
# Traefikダッシュボードでサービス状態確認
curl http://localhost:8080/api/http/services

# Docker プロバイダーの確認
curl http://localhost:8080/api/providers/docker
  1. パフォーマンス問題
# メトリクス確認
curl http://localhost:8080/metrics

# 接続状態確認
ss -tuln | grep :443

デバッグモード

log:
  level: DEBUG
  format: json

accessLog:
  format: json
  fields:
    defaultMode: keep

エコシステム統合

CI/CD統合

# GitLab CI/CDパイプライン例
deploy:
  script:
    - |
      kubectl apply -f - <<EOF
      apiVersion: traefik.io/v1alpha1
      kind: IngressRoute
      metadata:
        name: ${CI_PROJECT_NAME}-${CI_COMMIT_REF_SLUG}
      spec:
        entryPoints:
          - websecure
        routes:
          - match: Host(\`${CI_PROJECT_NAME}-${CI_COMMIT_REF_SLUG}.example.com\`)
            kind: Rule
            services:
              - name: ${CI_PROJECT_NAME}-${CI_COMMIT_REF_SLUG}
                port: 80
        tls:
          certResolver: letsencrypt
      EOF

モニタリングスタック

# Grafanaダッシュボード用設定
metrics:
  prometheus:
    service:
      enabled: true
    serviceMonitor:
      enabled: true
      namespace: monitoring
      interval: 30s
      scrapeTimeout: 10s

まとめ

Traefikは現代的なクラウドネイティブ環境において、以下の価値を提供します:

  • 自動化: サービス発見と設定の自動化により運用負荷を削減
  • 可観測性: 包括的なメトリクス、ログ、トレーシング機能
  • 拡張性: プラグインシステムによる機能拡張
  • 信頼性: 高可用性とゼロダウンタイム更新

特にマイクロサービスアーキテクチャ、コンテナオーケストレーション、DevOps環境において、その真価を発揮する優秀なリバースプロキシソリューションです。