介绍说明
先记录,其他后面补!
具体部署文档
./traefik/docker-compose.yaml
version: '3.7'
services:
traefik:
image: traefik:v2.3.4
restart: always
environment:
# https://developer.aliyun.com/endpoints#service_alidns
# https://github.com/aliyun/alibaba-cloud-sdk-go/blob/master/README-CN.md
- ALICLOUD_REGION_ID=cn-hangzhou
- ALICLOUD_ACCESS_KEY=XXXXXXXX
- ALICLOUD_SECRET_KEY=XXXXXXXX
command:
- "--log.level=INFO"
- "--api.insecure=true"
- "--api.dashboard=true"
- "--providers.docker.swarmMode=false"
- "--providers.docker.useBindPortIP=true"
- "--providers.docker.network=net-traefik"
- "--providers.docker.exposedbydefault=false"
- "--providers.file.directory=/etc/traefik/"
- "--providers.file.watch=true"
- "--entrypoints.http.address=:80"
- "--entrypoints.https.address=:443"
# 配置 ACME 相关
# https://doc.traefik.io/traefik/https/acme/
- "--certificatesresolvers.acme-resolver.acme.email=username@domain.org"
- "--certificatesresolvers.acme-resolver.acme.storage=/etc/traefik/acme.json"
# - "--certificatesresolvers.acme-resolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
- "--certificatesresolvers.acme-resolver.acme.preferredchain=ISRG Root X1"
- "--certificatesresolvers.acme-resolver.acme.keytype=RSA4096"
- "--certificatesresolvers.acme-resolver.acme.dnschallenge.provider=alidns"
- "--certificatesresolvers.acme-resolver.acme.dnschallenge.delaybeforecheck=0"
- "--certificatesresolvers.acme-resolver.acme.dnschallenge.resolvers=223.5.5.5:53,114.114.114.114:53,8.8.8.8:53"
- "--certificatesresolvers.acme-resolver.acme.dnschallenge.disablepropagationcheck=true"
logging:
driver: json-file
options:
max-size: "200k"
max-file: "10"
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik_http.rule=Host(`traefik.domain.org`)"
- "traefik.http.routers.traefik_http.entrypoints=http"
- "traefik.http.routers.traefik_http.middlewares=gzip,auth"
- "traefik.http.routers.traefik_https.rule=Host(`traefik.domain.org`)"
- "traefik.http.routers.traefik_https.entrypoints=https"
- "traefik.http.routers.traefik_https.middlewares=gzip,auth"
- "traefik.http.routers.traefik_https.tls=true"
# 定义共享证书
- "traefik.http.routers.traefik_https.tls.certresolver=acme-resolver"
- "traefik.http.routers.traefik_https.tls.domains[0].main=domain.org"
- "traefik.http.routers.traefik_https.tls.domains[0].sans=domain.org,*.domain.org"
# 使用 Swarm 模式要显式定义 service 否则不会被路由
- "traefik.http.services.traefik.loadbalancer.server.port=8080"
# 定义共享中间件
- "traefik.http.middlewares.gzip.compress=true"
- "traefik.http.middlewares.ssl.headers.sslRedirect=true"
- "traefik.http.middlewares.auth.basicauth.users=XXXXXXXX"
networks:
- traefik
ports:
- '80:80'
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "/path/:/etc/traefik/:rw"
networks:
traefik:
name: net-traefik
./service/docker-compose.yaml
version: '3.7'
services:
service1:
image: 6xyun/whoami
restart: always
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik_http.entrypoints=http"
- "traefik.http.routers.traefik_http.rule=Host(`service.domain.org`)"
- "traefik.http.routers.traefik_http.middlewares=gzip"
- "traefik.http.routers.traefik_https.entrypoints=https"
- "traefik.http.routers.traefik_https.rule=Host(`service.domain.org`)"
- "traefik.http.routers.traefik_https.middlewares=gzip"
# - "traefik.http.routers.cltfile_https.tls.certresolver=acme-resolver"
- "traefik.http.routers.traefik_https.tls=true"
- "traefik.http.services.service.loadbalancer.server.port=80"
- "traefik.http.services.service.loadbalancer.healthCheck.path=/"
- "traefik.http.services.service.loadbalancer.healthCheck.port=80"
- "traefik.http.services.service.loadbalancer.healthCheck.interval=10s"
- "traefik.http.services.service.loadbalancer.healthCheck.timeout=3s"
networks:
- traefik
service2:
image: 6xyun/whoami
restart: always
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik_http.entrypoints=http"
- "traefik.http.routers.traefik_http.rule=Host(`service.domain.org`)"
- "traefik.http.routers.traefik_http.middlewares=gzip"
- "traefik.http.routers.traefik_https.entrypoints=https"
- "traefik.http.routers.traefik_https.rule=Host(`service.domain.org`)"
- "traefik.http.routers.traefik_https.middlewares=gzip"
# - "traefik.http.routers.cltfile_https.tls.certresolver=acme-resolver"
- "traefik.http.routers.traefik_https.tls=true"
- "traefik.http.services.service.loadbalancer.server.port=80"
- "traefik.http.services.service.loadbalancer.healthCheck.path=/"
- "traefik.http.services.service.loadbalancer.healthCheck.port=80"
- "traefik.http.services.service.loadbalancer.healthCheck.interval=10s"
- "traefik.http.services.service.loadbalancer.healthCheck.timeout=3s"
networks:
- traefik
networks:
traefik:
name: net-traefik
external: true
关于 HTTPS 配置
证书池
- 先说一下
Traefik
证书大概的规则吧,Traefik
只有一个证书池。 - 虽然每个服务都定义了
tls
配置, 但最终获得/生成的证书都被Traefik
加载并全局使用,例如上面的例子,Traefik
的配置里面配置了Let's Encrypt
的泛域名证书支持,其他的服务里面就不必在写certresolver
属性, 只需要配置tls=true
开启TLS
就可以了,Traefik
检测到服务需要TLS
支持会在全局的证书池里面去寻找并匹配,匹配上了就能直接使用,没有匹配到就会使用默认证书(开启Let's Encrypt
后如果没匹配上会自动进行签发)。
使用 Let's Encrypt
证书
- 完全可以参照官方文档进行配置,但是有一点小细节还是需要记录一下。
Let's Encrypt
是免费的,并且理论上支持无限续期。Let's Encrypt
只允许通过dnschallenge
方式认证的域名申请泛域名证书。2021年10月
之后颁发的证书由于Root CA
切换可能在一些低版本系统中不被信任(例如:Windows XP、Android 7以下)。
使用本地证书
- 这个问题由于我没有仔细阅读文档导致我踩坑踩了两天。
- 如同我上面贴出来的服务,注意里面的
providers.file.directory
属性,这就是关键了。 - 原始文档里面说明了:除了
k8s
环境以外,其他环境使用本地证书只能通过file provider
的方式加载。
- 而在
Docker/Swarm
中开启Traefik
的file provider
就需要配置providers.file.directory
,让Traefik
能够从这个配置对应的目录中去读取配置。
https://doc.traefik.io/traefik/providers/file/#provider-configuration
- 完成上面的操作之后, 只需要在对应的目录中创建好配置文件,就能让
Traefik
加载上本地证书了。附一份配置示例:
# filename:cert.yaml
tls:
certificates:
- certFile: /path/to/domain.cert
keyFile: /path/to/domain.key
- certFile: /path/to/other-domain.cert
keyFile: /path/to/other-domain.key
本地证书链配置方式
- 这个文档里面好像确实没有。本人也是依照别的组件配置试验出来的。
- 用常用的
.pem
格式证书举例子:
-----BEGIN CERTIFICATE-----
MIIXXXXXXXXXXXXXXX....(A:服务证书)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIXXXXXXXXXXXXXXX....(B:签发A证书的CA证书)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIXXXXXXXXXXXXXXX....(C:签发B证书的CA证书)
-----END CERTIFICATE-----
...
-----BEGIN CERTIFICATE-----
MIIXXXXXXXXXXXXXXX....(ROOT CA)
-----END CERTIFICATE-----
如上内容所示,这就是一个证书链格式了,其中需要注意的是证书顺序,按照级别从低到高的顺序进行排序(第一个是服务证书,最后一个一般是 ROOT CA
或 ROOT CA
的下一级证书)。
警告:证书文件当中不要包含私钥。