前言
服务器不会向外部暴露很多端口来做服务暴露,一般只会开放有限的几个端口来做服务暴露,为了达到这个效果,咱们就用到了反向代理。
反向代理有多种途径,常用的是Nginx,由于我们的Java应用是基于docker容器发布的,而traefik自动集成了docker以及相关的组件,所以基于traefik搭建反向代理会对我更适用,最近研究了一下,最坑的地方是在适用TLS的自动续签https证书的时候。
技能要求:
- 会docker、docker-compose
1. traefik相关介绍(更详细的请移步官网)
1.1 官网
英文文档
中文文档
1.2 创建目录、配置文件
文件说明:
-
docker-compose-traefik-demo.yml traefik的docker-compose文件
-
traefik.yml traefik的静态配置文件(修改需要重启traefik服务才能生效)
-
http.yml、tcp.yml、tls.yml traefik的动态配置文件(修改后无需重启服务就能生效)
文件目录如下图:
2. 安装traefik
traefik本身有个dashboard的管控台,为它自身配置反向代理就是为了能用域名的形式进行管控台的访问,我们用这个控制台的相关配置来说明traefik的安装。
这里做了几个事情:
-
配置http、https反向代理
-
为http配置自动跳转https
-
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
配置文件说明:
- 这里暴露了四个端口:80、443、3306、6379
80: 对外暴露,用于代理http请求;
443: 对外暴露,用户代理https请求;
3306: 对外暴露,用于代理基于tcp的mysql服务请求;
6379: 对外暴露,用户代理基于tcp的Redis服务请求。
-
http会自动跳转https
-
定义了了ACME,要使用ACME的话,是需要额外配置的,会在动态配置文件中引用这里配置的名字叫myCertResolver的这个resolve。
-
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服务
- 创建名字为proxy的网络
docker network create proxy
- 启动traefik服务
docker-compose -f docker-compose-traefik-demo.yml up -d
- 查看traefik的日志
docker logs -f traefik
- hosts文件做域名映射配置
如果你的域名是备案了的,并且你的traefik安装在该域名解析的主机上,那么无需做该操作。
192.168.64.201 traefik.xxx.com
- 浏览器访问:
http://traefik.xxx.com
结果如下图:
6. 配置tcp反向代理
7. 配置tcp的TLS
这里目前还没弄好,后续补充