【Traefik2.x】反向代理、HTTPS证书

3,887 阅读5分钟

前言

服务器不会向外部暴露很多端口来做服务暴露,一般只会开放有限的几个端口来做服务暴露,为了达到这个效果,咱们就用到了反向代理。

反向代理有多种途径,常用的是Nginx,由于我们的Java应用是基于docker容器发布的,而traefik自动集成了docker以及相关的组件,所以基于traefik搭建反向代理会对我更适用,最近研究了一下,最坑的地方是在适用TLS的自动续签https证书的时候。

技能要求:

  1. 会docker、docker-compose

1. traefik相关介绍(更详细的请移步官网)

1.1 官网

英文文档

中文文档

1.2 创建目录、配置文件

文件说明:

  1. docker-compose-traefik-demo.yml traefik的docker-compose文件

  2. traefik.yml traefik的静态配置文件(修改需要重启traefik服务才能生效)

  3. http.yml、tcp.yml、tls.yml traefik的动态配置文件(修改后无需重启服务就能生效)

文件目录如下图:

2. 安装traefik

traefik本身有个dashboard的管控台,为它自身配置反向代理就是为了能用域名的形式进行管控台的访问,我们用这个控制台的相关配置来说明traefik的安装。

这里做了几个事情:

  1. 配置http、https反向代理

  2. 为http配置自动跳转https

  3. TLS配置通过ACME自动生成https证书、自动续签证书

2.1 静态配置文件traefik.yml

traefik.yml

api:
  # 开启 WEB UI
  dashboard: true
  # 安全模式
  insecure: true


# 发现docker或者file文件中定义的服务
providers:
  # 监听file
  file:
    # 定义动态配置文件所在的文件目录(容器内部路径)
    directory: /data/traefik/config
    # 监听动态配置文件的变更
    watch: true


  # 监听docker
  docker:
    # 如果置为false,那么docker容器需要在labels中声明traefik.enable=true,否则容器会被忽略
    exposedByDefault: false


# 定义流量入口(也就是对外暴露的监听的端口,该处定义的端口需要在docker-compose.yml中做端口暴露映射)
entryPoints:
  # 定义一个名称为http的入口,监听80端口,由80端口进入的流量都由它来代理
  http:
    address: ":80"
    # http请求自动跳转https
    http:
      redirections:
        entryPoint:
          to: https

  # 定义https入口,监听443端口,由80端口进入的流量都由它来代理
  https:
    address: ":443"

  # mysql的tcp代理入口
  mysql:
    address: ":3306"

  # redis的tcp代理入口
  redis:
    address: ":6379"


# 开启ACME 自动生成HTTPS证书
certificatesResolvers:
  myCertResolver:
    acme:
      # 邮箱地址
      email: "xxx@qq.com"
      # 签发的https证书存放位置
      storage: "/letsencrypt/acme.json"
      # 自动签发证书的一种验证方式(还有tlsChallent、dnsChallenge,我们用的是常用的这种httpChallenge方式)
      httpChallenge:
        entryPoint: http

配置文件说明:

  1. 这里暴露了四个端口:80、443、3306、6379

80: 对外暴露,用于代理http请求;

443: 对外暴露,用户代理https请求;

3306: 对外暴露,用于代理基于tcp的mysql服务请求;

6379: 对外暴露,用户代理基于tcp的Redis服务请求。

  1. http会自动跳转https

  2. 定义了了ACME,要使用ACME的话,是需要额外配置的,会在动态配置文件中引用这里配置的名字叫myCertResolver的这个resolve。

  3. ACME中的email你替换成你自己的邮箱即可(我是填写了个真实的邮箱)

2.2 动态配置文件

这里的配置文件可以做拆分,我这里目前没有做太细致的拆分,简单拆分成 http请求动态配置文件http.yml,tcp请求动态配置文件tcp.yml,以及tls动态配置文件tls.yml,而且,目前我没有用到tls里的配置(这一块的东西,我目前还没太明白)

2.2.1 http.yml

http.yml

http:

  # 路由配置
  routers:

    ## ############################################################################
    ##                    traefik配置
    ## ############################################################################

    # 定义traefik的WEB UI 路由
    router-traefik:
      # 指定监听web这个流量入口,不指定的话则会监听所有入口
      entryPoints:
        - "http"
        - "https"
      rule: "Host(`traefik.xxx.com`)"
      service: "api@internal"
      ## 使用中间件定义的用户认证
      middlewares:
        - user-auth
      # 开启ACME,并引用在traefik.yml中定义的myCertResolver这个resolve
      tls:
#        options: foo
        certResolver: "myCertResolver"


  # 中间件配置
  middlewares:
    # 为dashboard配置登录票据
    # UserName : admin
    # Password : qwer1234
    user-auth:
      basicAuth:
        users:
          - "admin:$apr1$tm53ra6x$FntXd6jcvxYM/YH0P2hcc1"

说明:

rule: "Host(traefik.xxx.com)" 该项配置配置了traefik对外的访问域名为traefik.xxx.com,如果只是局域网内访问,并且不需要https证书的话,该域名可以不备案,如果是要支持https证书,并且自动通过ACME续签的话,该traefik.xxx.com是需要到相关机构做备案的,否则,无法做ACME自动续签,打开traefik的debug日志,报错信息为: tls handle error,因为ACME自动生成证书时,应该是会到公网的dns服务器上去验证是不是有这个域名,如果该域名不存在的话,就会报错。

tcp.yml

先空着,下文中配置tcp反向代理会列举

tls.yml

先空着,后续配置

2.3 docker-compose的配置文件

docker-compose-traefik-demo.yml

version: '3'

services:
  traefik-service:
    image: traefik:v2.0
    container_name: traefik
    restart: always
    security_opt:
      - no-new-privileges:true
    # 容器端口和宿主机物理机端口的映射,对外暴露,提供服务
    ports:
      - "80:80"
      - "443:443"
      - "3306:3306"
      - "6379:6379"
    volumes:
      # 这样 Traefik 可以监听 Docker 事件
      - /var/run/docker.sock:/var/run/docker.sock
      # 静态配置文件目录映射
      - ./config/static:/etc/traefik
      # 动态配置文件目录映射
      - ./config/dynamic:/data/traefik/config
      # ACME生成证书存放位置(该文件在traefik服务启动之前需要赋予600的权限:chmod 600 acme.json)
      - ./letsencrypt/acme.json:/letsencrypt/acme.json

    # 使用名字为proxy的网络
    networks:
      - proxy

# 定义网络
networks:
  proxy:
    external: true

2.4 启动traefik服务

  1. 创建名字为proxy的网络
docker network create proxy
  1. 启动traefik服务
docker-compose -f docker-compose-traefik-demo.yml up -d
  1. 查看traefik的日志
docker logs -f traefik
  1. hosts文件做域名映射配置

如果你的域名是备案了的,并且你的traefik安装在该域名解析的主机上,那么无需做该操作。

192.168.64.201  traefik.xxx.com
  1. 浏览器访问:
http://traefik.xxx.com

结果如下图:

6. 配置tcp反向代理

7. 配置tcp的TLS

这里目前还没弄好,后续补充