Traefik 雲原生邊緣路由器

使用 Traefik 作為反向代理和負載平衡器,支援自動 HTTPS、服務發現、Kubernetes Ingress

專案簡介

Traefik 是一個現代化的 HTTP 反向代理和負載平衡器,專為微服務和容器環境設計。支援自動服務發現、動態配置、自動 HTTPS。

GitHub Stars: 61K+

主要功能

  • 自動服務發現 - Docker、Kubernetes、Consul
  • 自動 HTTPS - Let’s Encrypt 整合
  • 動態配置 - 無需重啟更新
  • 負載平衡 - 多種演算法
  • 中介軟體 - 認證、限流、重寫

安裝

Docker

1
2
3
4
5
docker run -d -p 80:80 -p 8080:8080 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  traefik:v3.0 \
  --api.insecure=true \
  --providers.docker

Docker Compose

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
version: '3.8'
services:
  traefik:
    image: traefik:v3.0
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./letsencrypt:/letsencrypt

Kubernetes

1
2
helm repo add traefik https://traefik.github.io/charts
helm install traefik traefik/traefik

基本配置

靜態配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# traefik.yml
api:
  dashboard: true

entryPoints:
  web:
    address: ":80"
  websecure:
    address: ":443"

providers:
  docker:
    exposedByDefault: false
  file:
    directory: /etc/traefik/dynamic

動態配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# dynamic/config.yml
http:
  routers:
    my-router:
      rule: "Host(`example.com`)"
      service: my-service
      entryPoints:
        - websecure
      tls:
        certResolver: letsencrypt

  services:
    my-service:
      loadBalancer:
        servers:
          - url: "http://backend:8080"

Docker 整合

服務標籤

1
2
3
4
5
6
7
8
9
services:
  webapp:
    image: myapp:latest
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.webapp.rule=Host(`app.example.com`)"
      - "traefik.http.routers.webapp.entrypoints=websecure"
      - "traefik.http.routers.webapp.tls.certresolver=letsencrypt"
      - "traefik.http.services.webapp.loadbalancer.server.port=8080"

多路由

1
2
3
4
5
6
7
8
labels:
  # API 路由
  - "traefik.http.routers.api.rule=Host(`api.example.com`)"
  - "traefik.http.routers.api.service=api-service"

  # Web 路由
  - "traefik.http.routers.web.rule=Host(`www.example.com`)"
  - "traefik.http.routers.web.service=web-service"

自動 HTTPS

Let’s Encrypt

1
2
3
4
5
6
7
8
# traefik.yml
certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@example.com
      storage: /letsencrypt/acme.json
      httpChallenge:
        entryPoint: web

DNS Challenge

1
2
3
4
5
6
7
8
9
certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@example.com
      storage: /letsencrypt/acme.json
      dnsChallenge:
        provider: cloudflare
        resolvers:
          - "1.1.1.1:53"

萬用字元憑證

1
2
3
4
labels:
  - "traefik.http.routers.app.tls.certresolver=letsencrypt"
  - "traefik.http.routers.app.tls.domains[0].main=example.com"
  - "traefik.http.routers.app.tls.domains[0].sans=*.example.com"

中介軟體

基本認證

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
http:
  middlewares:
    auth:
      basicAuth:
        users:
          - "admin:$apr1$..."

  routers:
    secure:
      rule: "Host(`admin.example.com`)"
      middlewares:
        - auth

限流

1
2
3
4
5
6
http:
  middlewares:
    rate-limit:
      rateLimit:
        average: 100
        burst: 50

重寫

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
http:
  middlewares:
    strip-prefix:
      stripPrefix:
        prefixes:
          - "/api"

    add-prefix:
      addPrefix:
        prefix: "/v1"

重導向

1
2
3
4
5
6
http:
  middlewares:
    https-redirect:
      redirectScheme:
        scheme: https
        permanent: true

Kubernetes Ingress

IngressRoute

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: webapp
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`app.example.com`)
      kind: Rule
      services:
        - name: webapp
          port: 80
  tls:
    certResolver: letsencrypt

中介軟體

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: auth
spec:
  basicAuth:
    secret: auth-secret
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: admin
spec:
  routes:
    - match: Host(`admin.example.com`)
      middlewares:
        - name: auth
      services:
        - name: admin-app
          port: 80

負載平衡

演算法

1
2
3
4
5
6
7
8
9
http:
  services:
    weighted:
      weighted:
        services:
          - name: app-v1
            weight: 3
          - name: app-v2
            weight: 1

健康檢查

1
2
3
4
5
6
7
8
http:
  services:
    my-service:
      loadBalancer:
        healthCheck:
          path: /health
          interval: 10s
          timeout: 3s

監控

Prometheus 指標

1
2
3
4
5
6
7
8
9
metrics:
  prometheus:
    addEntryPointsLabels: true
    addServicesLabels: true
    entryPoint: metrics

entryPoints:
  metrics:
    address: ":8082"

存取日誌

1
2
3
4
5
6
7
accessLog:
  filePath: "/var/log/traefik/access.log"
  format: json
  filters:
    statusCodes:
      - "200-299"
      - "400-499"

相關連結

延伸閱讀

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy