# Traefik介绍
Traefik 是一个 开源 的可以使得服务发布变得轻松有趣的 边缘路由器。它负责接收你系统的请求,然后使用合适的组件来对这些请求进行处理
除了众多的功能之外,Traefik 的与众不同之处还在于它会自动发现适合你服务的配置。当 Traefik 在检查你的服务时,会找到服务的相关信息并找到合适的服务来满足对应的请求
Traefik 兼容所有主流的集群技术,比如 Kubernetes,Docker,Docker Swarm,AWS,Mesos,Marathon等等

# Traefik概念
Traefik 是一个 边缘路由器 ,这意味着它是你整个应用平台的大门,拦截并路由每个传入的请求:它知道所有的逻辑和规则,这些规则确定哪些服务处理哪些请求(基于 path,host,headers 等等...)

传统的边缘路由器(或反向代理)需要一个配置文件,其中包含路由到你服务的所有可能路由,而 Traefik 则从服务本身获取它们,在部署你的服务的时候,你附加上一些信息来告诉 Traefik 可以处理的服务请求的特征

这意味着在部署服务时,Traefik 会立即检测到该服务并实时更新路由规则。当然同样的,当你从你的基础架构上删除这些服务时,这些路由同样会相应的消失
# Traefik安装
[k8s安装traefik v1](http://www.youqiqi.cn/archives/traefik%E9%83%A8%E7%BD%B2)
[k8s安装traefik v2](http://www.youqiqi.cn/archives/traefikv2x%E9%83%A8%E7%BD%B2)
docker安装traefik

创建一个 docker-compose.yml 文件,你将在其中定义一个使用官方的 Traefik 镜像的反向代理服务
```bash
cat docker-compose.yml
version: '3'
services:
reverse-proxy:
# 官方的 Traefik 2.0 Docker 镜像
image: traefik:v2.0
# 开启 web UI 并且告诉 Traefik 监听 Docker
command: --api.insecure=true --providers.docker
ports:
# HTTP 端口
- "80:80"
# Web UI 端口(通过 --api.insecure=true 启用)
- "8080:8080"
volumes:
# 这样 Traefik 可以监听 Docker 事件
- /var/run/docker.sock:/var/run/docker.sock
```
运行以下命令启动traefik
```bash
docker-compose up -d reverse-proxy
```
然后可以打开浏览器,访问 http://localhost:8080/api/rawdata 接口来查看 Traefik 的 API 原始数据
**Traefik 检查新服务并创建路由**
现在我们已经启动并运行了 Traefik 实例,接下来我们来部署一个新的服务,添加到上面的 docker-compose.yml 文件
```bash
# ...
whoami:
# 一个通过 API 暴露其 IP 地址的容器
image: containous/whoami
labels:
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
```
上面我们定义了 whoami:一个简单的 web 服务,它会输出部署的机器的相关信息(IP 地址、主机等等),然后我们可以使用以下命令启动 whoami 服务
```bash
docker-compose up -d whoami
```
启动完成后,然后返回浏览器,查看 http://localhost:8080/api/rawdata 接口的数据,正常就可以看到 Traefik 已自动检测到新容器并更新了相应的配置。
当 Traefik 检测到新服务时,它会创建相应的路由,然后我们可以访问相应的路由(我们这里使用 curl):
```bash
curl -H Host:whoami.docker.localhost http://127.0.0.1
#然后会输出如下一些信息
Hostname: 3cca68434466
IP: 127.0.0.1
IP: 172.21.0.3
#...
```
Traefik的Web UI界面可以通过http://localhost:8080即可:

# 路由和负载均衡
首先,当启动 Traefik 时,需要定义 entrypoints,然后根据连接到这些 entrypoints 的 路由 来分析传入的请求,来查看他们是否与一组 规则 相匹配,如果匹配,则路由可能会将请求通过一系列 中间件 转换过后再转发到你的 服务上去

Providers 来发现基础设施上存在的服务(它们的 IP、运行状况等...)
Entrypoints 监听传入的流量(端口等...)
Routers 分析请求(host, path, headers, SSL, ...)
Services 将请求转发到你的服务(load balancing, ...)
Middlewares 中间件,用来修改请求或者根据请求来做出一些判断 (authentication, rate limiting, headers, ...)
**示例**
下面是一个 file provider 的完整配置文件示例,该配置文件将 http://domain/whoami/ 的请求转发到一个可访问的服务 http://private/whoami-service/ 上。
在该过程中,Traefik 会使用中间件来对用户进行身份验证(使用 BasicAuth 中间件)
静态配置如下:
```bash
entryPoints:
web:
address: :8081
# 在8081端口上监听传入的请求
providers:
# 开启 file provider,可以在一个文件夹中来定义 路由/中间件/服务
file:
filename: dynamic_conf.yml
```
动态配置如下所示:
```bash
http:
routers:
to-whoami:
rule: "Host(`domain`) && PathPrefix(`/whoami/`)"
middlewares:
- test-user
service: whoami
middlewares:
test-user:
basicAuth:
users:
- test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/
services:
whoami:
loadBalancer:
servers:
- url: http://private/whoami-service
```
# 入口点(EntryPoints)

EntryPoints(入口点)是 Traefik 的网络入口点。它们定义了接收请求的端口(HTTP 或者 TCP)
**配置示例**
```bash
## 静态配置 仅80端口
entryPoints:
web:
address: ":80"
## 静态配置 80 & 443端口
entryPoints:
web:
address: ":80"
web-secure:
address: ":443"
```
定义了两个 entrypoints:一个叫 web,另一个加 web-secure
web 监听 80 端口, web-secure 监听 443 端口
# 路由器(Routers)

一个路由器负责将传入请求连接到可以处理这些请求的服务上去
在这个过程中,路由器可能会使用一些 中间件 来更新请求,或者将请求转发到服务之前进行一些操作
**配置示例**
```bash
## 动态配置
http:
routers:
my-router:
rule: "Path(`/foo`)"
service: service-foo
## 动态配置 将端口3306上所有的(非TLS)请求转发到 database 这个服务
tcp:
routers:
to-database:
entryPoints:
- "mysql"
# 捕获所有请求(仅适用于非tls路由器的规则)
rule: "HostSNI(`*`)"
service: database
## 静态配置
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
other:
address: ":9090"
```
# 服务(Services)

Services 负责配置如何获取最终将处理传入请求的实际服务
**配置示例**
为一个 HTTP 服务声明两个实例 -- 使用 File Provider
```bash
## 动态配置
http:
services:
my-service:
loadBalancer:
servers:
- url: "http://private-ip-server-1/"
- url: "http://private-ip-server-2/"
```
为一个 TCP 服务声明两个实例 -- 使用 File Provider
```bash
tcp:
services:
my-service:
loadBalancer:
servers:
- address: "xx.xx.xx.xx:xx"
- address: "xx.xx.xx.xx:xx"
```

Traefik概述整理