traefik 起步

105 min read

中文文档

https://www.qikqiak.com/traefik-book/middlewares/basicauth/

创建网络

将Traefik和其它服务连接到同一网络

docker network create traefik_net

查看连接网络的服务

docker network inspect traefik_net

traefik docker-compose 文件

version: '3'

services:
  traefik:
    image: "traefik:v2.5"
    container_name: "traefik"
    ports:
      - "80:80"
      - "443:443"
      # (Optional) Expose Dashboard
      - "8080:8080"  # Don't do this in production!
    volumes:
      - /etc/traefik:/etc/traefik
      - ./data/traefik-ssl-certs:/ssl-certs
      - /var/run/docker.sock:/var/run/docker.sock:ro
      
networks:
  default:
    external:
      name: traefik_net

配置说明:

  • /etc/traefik treafik的配置文件
  • traefik-ssl-certs 认证证书存放
  • 8080端口 为Dashboard 面板的访问地址
  • /var/run/docker.sock:/var/run/docker.sock:ro 挂载 docker.sock,实现与docker的交互 ,监听docker事件
  • ./data/traefik-ssl-certs:/ssl-certs 本地存放证书
  • 使用已存在的网络一些场景下,我们并不需要创建新的网络,而只需加入已存在的网络,此时可使用external选项。示例:
networks:
  default:
    external:
      name: traefik_net

traefik.yml 静态配置文件

静态配置应用全局,配置说明

api:
  dashboard: true # 是否启用 Traefik Api接口
  insecure: true # 是否启用 Traefik 控制面板展示

log: # Traefik 日志,涉及本身发生的一切(启动、配置、事件、关闭等)
  filePath: "/path/to/log-file.log" # 日志文件路径
  format: json # 日志存储格式
  level: DEBUG # 日志存储级别

accessLog: # 访问日志配置
  filePath: "/path/to/access.log" # 日志文件路径
  format: json # 日志存储格式
  bufferingSize: 100 # 在写入日志文件之前保存在内存中的日志行数
  filters: # 日志过滤
    statusCodes: # 指定访问状态码
      - "200"
      - "300-302"
    retryAttempts: true
    minDuration: "10ms" # 指定超时时间保留日志
  fields: # 限制保留指定字段
    defaultMode: keep
    names:
      ClientUsername: drop
    headers:
      defaultMode: keep
      names:
          User-Agent: redact
          Authorization: drop
          Content-Type: keep

metrics: # 服务指标配置,默认请求地址:
  prometheus: # 启用 Prometheus
    buckets: # 延迟指标的存储桶
      - 0.1
      - 0.3
      - 1.2
      - 5.0

entryPoints: # 入口点配置
  http:
    address: :80 # 监听 80 端口
    http:
      redirections: # 转发中间件
        entryPoint:
          to: https # 转发到新的入口点,这里转发到 HTTPS

  https:
    address: :443 # 监听 443 端口
    http:
      middlewares: # 中间件
        - secureHeaders@file
        - nofloc@file
      tls: # TLS证书方式
        certResolver: buypass # 选择 buypass 证书服务配置

pilot:
  dashboard: false # 官方数据监控面板

ping: {} # ping相关配置

providers: # 服务发现配置
  docker:
    endpoint: "unix:///var/run/docker.sock" # 服务者提供配置(必须)
    exposedByDefault: false # 是否开启所有容器标签监听,如果设置为false,traefik.enable=true则从生成的路由配置中忽略没有标签的容器。
  file:
    filename: /configurations/dynamic.yml # 动态配置文件路径

certificatesResolvers: # TLS 证书配置
  buypass: # 自定义证书服务配置
    acme:
      email: your email # 申请邮箱
      storage: acme.json # 证书内容存放文件路径
      caServer: https://api.buypass.com/acme/directory # CA服务器地址
      keyType: EC256 # 生成证书私钥
      httpChallenge:
        entryPoint: http # 指定哪个入口点刷新证书

静态配配置一个实例

global:
  checkNewVersion: true
  sendAnonymousUsage: false  # true by default

# (Optional) Log information
# ---
# log:
#  level: ERROR  # DEBUG, INFO, WARNING, ERROR, CRITICAL
#   format: common  # common, json, logfmt
#   filePath: /var/log/traefik/traefik.log

# (Optional) Accesslog
# ---
# accesslog:
  # format: common  # common, json, logfmt
  # filePath: /var/log/traefik/access.log

# (Optional) Enable API and Dashboard
# ---
# api:
#  dashboard: true  # true by default
#  insecure: true  # Don't do this in production!

# Entry Points configuration
# ---
entryPoints:
  web:
    address: :80
    # (Optional) Redirect to HTTPS
    # ---
    # http:
    #   redirections:
    #     entryPoint:
    #       to: websecure
    #       scheme: https

  websecure:
    address: :443

# Certificates configuration
# ---
# TODO: Custmoize your Cert Resolvers and Domain settings
# 
certificatesResolvers:
# LET'S ENCRYPT:
# ---
# 
  staging:
    acme:
      email: [email protected]  # TODO: Change this to your email
      storage: /ssl-certs/acme.json
      caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
      httpChallenge:
        entryPoint: web
  production:
    acme:
      email: [email protected]  # TODO: Change this to your email
      storage: /ssl-certs/acme.json
      caServer: "https://acme-v02.api.letsencrypt.org/directory"
      httpChallenge:
        entryPoint: web

# Provider Configuration
# ---
# TODO: Customize your Provider Settings if needed
# 
providers:
# DOCKER:
# ---
#
  docker:
    exposedByDefault: false  # Default is true

配置说明

  • api 是否开启traefik的api功能和面板
  • log是否开启日志功能
  • exposedByDefault 关闭容器自动连接,只有标签为 "traefik.enable=true"的容器才能主动加入到路由

静态配置

http: # 为 HTTP 请求配置
  middlewares: # 中间件配置
    default-compress:
      compress: true # 开启压缩
    nofloc:
      headers: # 头部信息配置
        customResponseHeaders: # 要应用于响应的头部key-value
          Permissions-Policy: "interest-cohort=()"
    secureHeaders:
      headers:
        sslRedirect: true # 只允许 HTTPS 请求
        forceSTSHeader: true # 即使连接是 HTTP,也设置forceSTSHeader为true添加 STS 标头
        stsIncludeSubdomains: true # 将includeSubDomains指令附加到Strict-Transport-Security标头
        stsPreload: true # 将preload标志附加到Strict-Transport-Security标头。
        stsSeconds: 31536000
    user-auth:
      basicAuth: # 基础认证配置
        usersFile: "/path/to/passwd" # 认证方式
  routers: # 路由规则配置
    dashboard:
      rule: "Host(`traefik.example.com`)" # 匹配 traefik.example.com 地址请求
      entrypoints:
        - "https" # 入口点为 HTTPS
      service:
        "dashboard@internal" # 导向到指定服务
      middlewares:
        - "user-auth@file" # 中间件
        - "default-compress" # 中间件
    api:
      rule: "Host(`traefik.example.com`) && PathPrefix(`/api`)" # 匹配 traefik.example.com/api 地址请求
      entrypoints:
        - "https" # 入口点为 HTTPS
      service:
        "api@internal" # 导向到指定服务
      middlewares:
        - "user-auth@file"
        - "default-compress"
    ping:
      rule: "Host(`traefik.example.com`) && PathPrefix(`/ping`)" # 匹配 traefik.example.com/ping 地址请求
      entrypoints:
        - "https"
      service:
        "ping@internal" # 导向到指定服务
      middlewares:
        - "user-auth@file"

tls: # TLS 相关配置
  options:
    default:
      cipherSuites:
        - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
        - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
      minVersion: VersionTLS12

docker容器 nginx 配置实例

version: "3.7"

services:
  nginx:
    image: nginx:latest
    container_name: nginx
    hostname: nginx
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nginx.entrypoints=web"
      - "traefik.http.routers.nginx.rule=Host(`nginx.bytenote.net`)"

networks:
  default:
    external:
      name: traefik_net

配置Baseauth

动态配置文件,定义名为test-auth的middlewares

http:
  middlewares:
    test-auth:
      basicAuth:
        users:
          - "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/" 
          - "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"

容器配置,在容器的label中指定middlewares为本地的动态配置文件test-auth

version: '3'

services:

  whoami:
    image: containous/whoami
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.test-auth-web.entrypoints=web"
      - "traefik.http.routers.test-auth-web.rule=Host(`who.bytenote.net`)"
      - "traefik.http.routers.test-auth-web.middlewares=test-auth@file"

networks:
  default:
    external:
      name: traefik_net

核心概念

Providers 用来自动发现平台上的服务,可以是编排工具、容器引擎或者 key-value 存储等,比如 Docker、Kubernetes、File

Entrypoints 监听传入的流量(端口等…),是网络入口点,它们定义了接收请求的端口(HTTP 或者 TCP)。

Routers 分析请求(host, path, headers, SSL, …),负责将传入请求连接到可以处理这些请求的服务上去。

Services 将请求转发给你的应用(load balancing, …),负责配置如何获取最终将处理传入请求的实际服务。

Middlewares 中间件,用来修改请求或者根据请求来做出一些判断(authentication, rate limiting, headers, ...),中间件被附件到路由上,是一种在请求发送到你的服务之前(或者在服务的响应发送到客户端之前)调整请求的一种方法。