Comparison of Traefik 1.7 and Traefik 2.0 with Docker

很早以前我就写过几篇Traefik搭配Docker部署各种服务的文章。包括相对最近关于如何搭建Ghost平台的文章使用的也是Traefik+docker这个组合。在我看来,实在没有什么比这哥俩组合更简单部署程序的方法了。很早之前我就知道Traefik要迎来2.0的大更新版本,当时粗略看了一下感觉有点复杂当时就没有细看。后来因为我用了latest tag和Towerwatch,系统自动更新到Traefik 2版本之后还导致了我网站崩了半天我都没发现……(Traefik 1.7到2.0之后使用语法很不一样)

我最近也不知道哪根筋抽了,突然想着必须学会Traefik 2的配置,在挣扎了几个晚上包括去Reddit吐槽之后才终于看到了点眉目,于是先记下来,以后慢慢学习再添补内容。

推荐阅读

  1. Traefik official documentation
  2. Traefik 2.0 + Docker — a Simple Step by Step Guide
  3. Traefik 2.0 + Docker — an Advanced Guide
  4. Traefik 2.0 & Docker 101
  5. Traefik 2 & TLS 101

Traefik的配置方法有很多种,我这里只选用我知道的方法给大家讲解。我在这里默认大家已经安装好了Docker以及Docker Compose,不知道如何安装的朋友可以参考官方文档如下。

说一千道一万都不如直接举例说明来的痛快^1

部署实例

这里我会分别用Traefik 1.7和Traefik 2来做同样的事情。

  1. Enable Traefik Dashboard
  2. 给Dashboard一个域名来访问
  3. 给Dashboard加basic auth
  4. 部署一个whoami的服务
  5. 自动通过ACME获取SSL证书(ECC 384 Key)并自导从http转接到https
Traefik 1.7 + Docker自动获取SSL证书实例
1
2
3
4
touch docker-compose.yml
touch traefik.toml
touch acme.json
chmod 600 acme.json
  • docker-compose.yml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    version: '3.3'

    services:
    reverse-proxy:
    image: traefik:1.7-alpine
    command: --api --docker
    ports:
    - "80:80"
    - "443:443"
    volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - ./traefik.toml:/traefik.toml
    - ./acme.json:/acme.json
    labels:
    - "traefik.port=8080"
    - "traefik.backend=reverse-proxy"
    - "traefik.frontend.rule=Host:traefik.mydomain.com"
    - "traefik.enable=true"
    - "traefik.frontend.auth.basic=user:password"

    whoami:
    image: emilevauge/whoami
    labels:
    - "traefik.frontend.rule=Host:whoami.mydomain.com"
  • traefik.toml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    defaultEntryPoints = ["http", "https"]

    [entryPoints]
    [entryPoints.http]
    address = ":80"
    [entryPoints.http.redirect]
    entryPoint = "https"
    [entryPoints.https]
    address = ":443"
    [entryPoints.https.tls]

    #Let's encrypt setup
    [acme]
    email = "[email protected]"
    storage = "acme.json"
    onHostRule = true
    keyType = "EC384"
    entryPoint = "https"
    [acme.httpChallenge]
    entryPoint = "http"
Traefik 2 + docker自动获取SSL证书

创建所需文件以及文件夹

1
2
3
4
5
6
7
touch docker-compose.yml
mkdir data
mkdir data/configurations
touch data/traefik.yml
touch data/acme.json
touch data/configurations/dynamic.yml
chmod 600 data/acme.json
  • docker-compose.yml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    version: '3'

    services:
    traefik:
    image: traefik:latest
    container_name: traefik
    restart: unless-stopped
    security_opt:
    - no-new-privileges:true
    ports:
    - 80:80
    - 443:443
    volumes:
    - /etc/localtime:/etc/localtime:ro
    - /var/run/docker.sock:/var/run/docker.sock:ro
    - ./data/traefik.yml:/traefik.yml:ro
    - ./data/acme.json:/acme.json
    # Add folder with dynamic configuration yml
    - ./data/configurations:/configurations
    labels:
    - "traefik.enable=true"
    - "traefik.http.routers.traefik.entrypoints=http"
    - "traefik.http.routers.traefik.rule=Host(`traefik.mydomain.com`)"
    # Entry Point for https
    - "traefik.http.routers.traefik.middlewares=https-redirect@file"
    - "traefik.http.routers.traefik-secure.entrypoints=https"
    - "traefik.http.routers.traefik-secure.rule=Host(`traefik.mydomain.com`)"
    - "traefik.http.routers.traefik-secure.middlewares=user-auth@file"
    - "traefik.http.routers.traefik-secure.tls=true"
    - "traefik.http.routers.traefik-secure.tls.certresolver=http"
    - "traefik.http.routers.traefik-secure.service=api@internal"

    whoami:
    image: emilevauge/whoami
    labels:
    - "traefik.enable=true"
    # Entry point for http
    - "traefik.http.routers.whoami.entrypoints=http"
    - "traefik.http.routers.whoami.rule=Host(`whoami.mydomain.com`)"
    # Entry Point for https
    - "traefik.http.routers.whoami.middlewares=https-redirect@file"
    - "traefik.http.routers.whoami-secure.entrypoints=https"
    - "traefik.http.routers.whoami-secure.rule=Host(`whoami.mydomain.com`)"
    # Enable TLS
    - "traefik.http.routers.whoami-secure.tls=true"
    - "traefik.http.routers.whoami-secure.tls.certresolver=http"
  • traefik.yml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    api:
    dashboard: true

    entryPoints:
    http:
    address: ":80"
    https:
    address: ":443"

    providers:
    docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
    file:
    filename: /configurations/dynamic.yml

    certificatesResolvers:
    http:
    acme:
    email: [email protected]
    storage: acme.json
    keyType: EC384
    httpChallenge:
    entryPoint: http
  • dynamic.yml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # Dynamic configuration
    http:
    middlewares:
    https-redirect:
    redirectScheme:
    scheme: https

    user-auth:
    basicAuth:
    users:
    - "user:password"
版本对比:
  1. 我在Traefik 2多使用了一个dynamic.yml文件。这个文件里面定义了两个middleware,更多的其他动态配置也可以在这个文件里面添加。有很多教程都把middleware以label的形式添加在docker-compose.yml文件里面。我个人觉得还是放在文件里面方便在别的service里面引用更好。
  2. 我需要为每个service指定router的EntryPoint,http和https需要创建两个router来指定不同的entrypoints
  3. 也需要指定使用TLS……
  4. 还需要指定用什么TLS resolver……
  5. 动态配置的文件可以随时修改随时生效,这是进步。
结论

Traefik 2这么麻烦,我干嘛不用Traefik 1.7呢?

这就是我作为一个只使用简单功能的用户,在学习过如何从Traefik 1.7转到Traefik 2之后的的想法……