traefik教程

使用traefik创建反向代理过程见:https://blog.woyou.cool/post/1908

本文来自官网文档的部分翻译并加以解释:https://doc.traefik.io/traefik/

由于本人不善描述,故请结合下述举例进行了解

简述

traefik是一个边际路由,它在服务中扮演着网关的角色。它拦截所有请求并进行一系列处理后再传递到具体的处理服务器。

其特点是可以进行自动的服务发现。例如,我希望在项目中添加一个新的服务,如果使用nginx的话就需要手动修改nginx配置文件,并创建路由规则。而traefik则会自动监听服务状态,新加的服务也会根据规则自动创建路由。这就使得它在初始配置时略微麻烦,但是后续使用的过程比较简单。

重要概念

traefik有几个较为重要的概念:

  • provider:之所以能自动进行服务发现,是因为要有人告诉它。告诉它的这个人就是provider,这个provider可以是docker socket、zookeeper、k8s、redis甚至file。traefik时刻监听它们里面的内容,并对其变化做出反应。
  • Router:路由规则,例如我希望对 “n1.domain.com” 的请求全部路由到n1服务器,而“n2.domain.com”的请求全部路由到n2服务器,这就是两条根据域名区分的路由规则
    具体可以设定的参数参见:https://doc.traefik.io/traefik/routing/providers/docker/
  • Service:处理具体请求的服务,例如上述的n1、n2服务器,但一个服务器上也可能有多个service,此时需要通过端口进行区分
  • Middleware:每个请求被traefik拦截后,都会经过一系列middleware才能到达service,用户可以指定需要哪些middleware,例如对url进行修改、对header进行修改等
    具体有哪些middleware见:https://doc.traefik.io/traefik/middlewares/http/overview/ 和

配置文件

traefik有两种非常重要的配置文件:静态配置和动态配置

静态配置就是一个 traefik.yml 的配置文件,这里面配置的是traefik的一些启动参数,例如其监听的端口、是否开始dashboard等

动态配置就是用来配置各种路由规则的。traefik一旦启动后就不需要再进行配置了,所有新加入的服务都应该在该服务启动时就指定路由规则,然后等待traefik自动发现。

例如:我启动了一个traefik,此时需要新加入一个web服务S,则我应该在启动S时给定一个启动参数“rule=my-router-rule”用于路由的配置(真实的配置不是这样,但也是kv的形式),这个参数就是一个动态配置。由于不同的provider中服务的启动方式不同,故动态配置都是不尽相同的。例如若使用docker作为provider,则启动新的docker容器时,就需要加上 --label rule=my-router-rule 的参数。因为docker做provider时是使用容器的label作为动态配置的。

(三个月后的后记:不得不说,这种配置方式,当时一时爽,后来火葬场。当我再次进入这个服务器看的时候,我发现我完全忘记了当时是怎么配置的,我完全不知道访问规则是什么,就算我找到了域名解析规则,但我依旧无法想起它到底是怎么访问的,为什么可以这样,我已经怀疑人生到不会组织语言了)

举例

开启一个traefik并使用docker作为provider

#traefik静态配置文件 traefik.yml

# 使用docker作为provider
providers:
  docker: {}

# 使用安全模式并开启dashboard
api:
  dashboard: true
  insecure:  false

启动traefik

docker run -d -p 8080:8080 -p 80:80 -p 443:443 --name traefik -v /var/run/docker.sock:/var/run/docker.sock -v /home/hunt/Templates/traefik.yml:/etc/traefik/traefik.yml --network net1 -l "traefik.http.routers.dashboard.rule=Host(\`traefik.huntzou.com\`) && (PathPrefix(\`/api\`) || PathPrefix(\`/dashboard\`))" -l "traefik.http.routers.dashboard.service=api@internal" traefik

为了便于使用域名访问,我手动在host文件中添加了一些dns解析,其中192.168.190.128就是我的服务器ip

192.168.190.128     huntzou.com
192.168.190.128     n1.huntzou.com
192.168.190.128     n2.huntzou.com
192.168.190.128     n3.huntzou.com
192.168.190.128     traefik.huntzou.com

浏览器输入 http://traefik.huntzou.com/dashboard/ 即可看到traefik的dashboard。(注:结尾的 / 不能少)

启动两个nginx服务(启动完成后为了便于区分最好能修改下主页)

# 将 n1.huntzou.com 域名路由到n1 service
docker run -d --network net1 --name n1 -l "traefik.http.routers.r1.rule=Host(\`n1.huntzou.com\`)" -l "traefik.http.services.n1.loadbalancer.server.port=80" nginx

# 将 n2.huntzou.com 域名路由到n2 service
docker run -d --network net1 --name n2 -l "traefik.http.routers.r2.rule=Host(\`n2.huntzou.com\`)" -l "traefik.http.services.n2.loadbalancer.server.port=80" nginx

再次查看dashboard看到已经自动发现了这两个服务

浏览器分别访问 “n1.huntzou.com” 和 “n2.huntzou.com” 就能看到它们路由到了不同的service

当然,我这里是根据域名进行路由的,您也可以根据其他条件,例如header、url等进行路由

使用let’s encrypt

traefik支持使用let’s encrypt自动获取ssl证书(let’s encrypt证书一般90天有效,traefik会到还剩30天时自动获取更新)

修改配置文件:

## traefik.yml

# Docker configuration backend
providers:
  docker: {}

# API and dashboard configuration
api:
  dashboard: true
  insecure:  false

entryPoints:
  web:
    address: ":80"

    # 用于http重定向到https
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: ":443"

certificatesResolvers:
  myresolver:
    acme:
      email: zouheng613@hunt
      # 证书保存位置,可以将其挂载出去易于备份
      storage: acme.json
      httpChallenge:
        entryPoint: web

修改traefik启动参数(用于使得dashboard也使用https):

sudo docker run -d -p 8080:8080 -p 80:80 -p 443:443 --name traefik -v /var/run/docker.sock:/var/run/docker.sock -v /home/ubuntu/traefik.yml:/etc/traefik/traefik.yml --network net1 -l "traefik.http.routers.dashboard.rule=Host(\`traefik.athe.top\`) && (PathPrefix(\`/api\`) || PathPrefix(\`/dashboard\`))" -l "traefik.http.routers.dashboard.service=api@internal" -l "traefik.http.routers.dashboard.tls=true" -l "traefik.http.routers.dashboard.tls.certresolver=myresolver"  traefik

修改service启动参数:

sudo docker run -d --network net1 --name n1 -l "traefik.http.routers.r1.rule=Host(\`n1.athe.top\`)" -l "traefik.http.routers.r1.tls=true" -l "traefik.http.routers.r1.tls.certresolver=myresolver" nginx

再次访问n1服务(这里我用了真实的外网服务器和域名):

Leave a Comment