概念

让我们回顾一下在 概览 举的例子:

假设你已经在你的基础设施上部署了一堆微服务。你可能使用了一个服务发现系统(例如 etcd 或 consul)或者一个资源管理框架(swarm,Mesos/Marathon)来管理所有这些服务。 如果你想让你的用户去从互联网访问你的某些微服务, 你就必需使用虚拟hosts或前缀路径来配置一个反向代理:

  • 域名 api.domain.com 将指向你的私有网络中的微服务 api
  • 路径 domain.com/web 将指向你的私有网络中的微服务 web
  • 域名 backoffice.domain.com 将指向你的私有网络中的微服务 backoffice ,在你的多台实例之间负载均衡

架构

我们将Træfɪk放大,一起看看它内部的结构:

结构

入口点

入口点是是Træfɪk的网络入口。 它们可以通过以下方式来定义:

这里有一个入口点定义的例子:

[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    entryPoint = "https"
  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]
      [[entryPoints.https.tls.certificates]]
      certFile = "tests/traefik.crt"
      keyFile = "tests/traefik.key"

这里还有一个证书身份验证的例子:

[entryPoints]
  [entryPoints.https]
  address = ":443"
  [entryPoints.https.tls]
  clientCAFiles = ["tests/clientca1.crt", "tests/clientca2.crt"]
    [[entryPoints.https.tls.certificates]]
    certFile = "tests/traefik.crt"
    keyFile = "tests/traefik.key"

前端

前端是入口流量从入口点转发到后端的一组规则。 前端可以通过以下规则定义:

你可以为一条规则添加多个值,通过用 , 分隔开。 你可以使用多条规则,通过用 ; 分隔开。

你可以选择启用 passHostHeader 来转发客户端请求Header中的 Host 字段到后端

这里有一个前端定义的例子:

[frontends]
  [frontends.frontend1]
  backend = "backend2"
    [frontends.frontend1.routes.test_1]
    rule = "Host:test.localhost,test2.localhost"
  [frontends.frontend2]
  backend = "backend1"
  passHostHeader = true
  priority = 10
  entrypoints = ["https"] # overrides defaultEntryPoints
    [frontends.frontend2.routes.test_1]
    rule = "HostRegexp:localhost,{subdomain:[a-z]+}.localhost"
  [frontends.frontend3]
  backend = "backend2"
    [frontends.frontend3.routes.test_1]
    rule = "Host:test3.localhost;Path:/test"

合并多条规则

正如上面例子中所展示的,你可以合并多条规则。 在TOML文件中,你可以使用多条路由:

  [frontends.frontend3]
  backend = "backend2"
    [frontends.frontend3.routes.test_1]
    rule = "Host:test3.localhost"
    [frontends.frontend3.routes.test_2]
    rule = "Path:/test"

这里,当规则Host:test3.localhost Path:/test同时匹配时 frontend3 将把流量转发到 backend2。 或者你也可以使用 ; 符号来分隔,结果是相同的:

  [frontends.frontend3]
  backend = "backend2"
    [frontends.frontend3.routes.test_1]
    rule = "Host:test3.localhost;Path:/test"

最后,你可以使用 , 符号分隔规则,为一个前端创建一个规则来绑定多个域名或路径:

 [frontends.frontend2]
    [frontends.frontend2.routes.test_1]
    rule = "Host:test1.localhost,test2.localhost"
  [frontends.frontend3]
  backend = "backend2"
    [frontends.frontend3.routes.test_1]
    rule = "Path:/test1,/test2"

优先级

默认情况下,路由会以规则长度(为了防止部分重叠情况)被排序(倒序): PathPrefix:/12345 将会比 PathPrefix:/1234 优先被匹配到,最后才会匹配到 PathPrefix:/1

你可以在前端自定义优先级:

  [frontends]
    [frontends.frontend1]
    backend = "backend1"
    priority = 10
    passHostHeader = true
      [frontends.frontend1.routes.test_1]
      rule = "PathPrefix:/to"
    [frontends.frontend2]
    priority = 5
    backend = "backend2"
    passHostHeader = true
      [frontends.frontend2.routes.test_1]
      rule = "PathPrefix:/toto"

这里,frontend1 将会比 frontend2 优先被匹配(因为10 > 5).

后端

后端用来负责将来自一个或多个前端的流量负载均衡到一组http服务器上。 这里支持多种负载均衡方法:

断路器也可以应用到后端,用于防止故障服务器上的高负载。 初始化状态是Standby。断路器只观察统计信息但并不修改请求。 当断路条件匹配时,断路器进入Tripped状态,它会返回与定义的http状态码或转发到其他前端。 一旦Tripped状态计时器超时,断路器会进入Recovering状态并重置所有统计数据。 当短路条件不匹配并且Recovery状态计时器超时时,断路器进入Standby状态。

它可以通过配置:

举个例子:

为了主动防治后端被高负载压垮,可以为每个后端设置最大连接数限制。

最大连接数限制可以通过为maxconn.amount配置一个整型值,同时 maxconn.extractorfunc 是用来配置通过什么样的维度来统计最大连接数。"例如下面例子中通过请求中host来统计连接数"

例如:

[backends]
  [backends.backend1]
    [backends.backend1.maxconn]
       amount = 10
       extractorfunc = "request.host"

所有的负载平衡器都支持粘滞会话(sticky sessions)。当粘滞会话被开启时,会有一个名称叫做_TRAEFIK_BACKEND的cookie在请求被初始化时被设置在请求初始化时。在随后的请求中,客户端会被直接转发到这个cookie中存储的后端(当然它要是健康可用的),如果这个后端不可用,将会指定一个新的后端。

例如:

[backends]
  [backends.backend1]
    [backends.backend1.loadbalancer]
      sticky = true

服务器健康检查也是可配置的,当Traefik定期执行HTTP GET请求到后端时,后端返回的HTTP状态码不是200 OK,那么这个后端将被从负载均衡轮询列表中移除。健康检查可以以一个在后端URL后附加路径的路径地址与一个时间间隔 (以 time.ParseDuration 所识别的格式给出) specifying how 配置多久健康检查应该执行一次 (默认30秒). 每个后端必需在5秒内回应健康检查。

当一个后端重新返回HTTP状态码200 OK时,将被重新添加回负载均衡轮询列表。

例如:

[backends]
  [backends.backend1]
    [backends.backend1.healthcheck]
      path = "/health"
      interval = "10s"

服务器

服务器可以简单的被定义为URL。你也可以设置一个自定义的 weight 给每个服务器(这个weight将会被用于负载均衡)。

这里有一个关于后端和服务器的定义的例子:

[backends]
  [backends.backend1]
    [backends.backend1.circuitbreaker]
      expression = "NetworkErrorRatio() > 0.5"
    [backends.backend1.servers.server1]
    url = "http://172.17.0.2:80"
    weight = 10
    [backends.backend1.servers.server2]
    url = "http://172.17.0.3:80"
    weight = 1
  [backends.backend2]
    [backends.backend2.LoadBalancer]
      method = "drr"
    [backends.backend2.servers.server1]
    url = "http://172.17.0.4:80"
    weight = 1
    [backends.backend2.servers.server2]
    url = "http://172.17.0.5:80"
    weight = 2

配置文件

Træfɪk的配置文件分为两部分:

静态 Træfɪk 配置

静态配置文件是一种全局配置文件,用来配置后端和入口点的连接。

可以通过许多方式配置Træfɪk,以下是各种配置方式的生效优先级。 上面的项目优先级大于下面的项目:

这代表着参数会覆盖配置文件,Key-value存储会覆盖参数。

配置文件

在默认情况下, Træfɪk 会在以下几个地方寻找 traefik.toml 文件:

你可以通过设置configFile参数来覆盖这种默认情况:

$ traefik --configFile=foo/bar/myconfigfile.toml

请转到 全局配置 部分获取详细文档。

参数

每个参数(命令)在帮助部分都有定义:

$ traefik --help

需要注意的是,所有默认值也会一同被展示出来。

Key-value 存储

Træfɪk 支持多种 Key-value 存储方式:

请转到 用户手册 Key-value 存储配置 部分获取详细文档。

动态 Træfɪk 配置

动态配置请关注:

Træfɪk 可以将多个配置后端的规则热更新。

我们只需要开启watch 选项来让 Træfɪk 监听配置文件变化并自动生成配置。 指向服务的路由在监测到任何变化时直接被创建或更新。

请转到后端配置 部分获取详细文档。

命令

使用方法: traefik [command] [--flag=flag_argument]

列出了所有Træfɪk可用的命令与命令描述:

每个命令都可能包含相关的标志。 所有相关的标志都会显示在:

$ traefik [command] --help

需要注意的是,每个命令描述是在帮助的开始部分:

$ traefik --help