前述
为什么先从 Traefik 说起?
因为 Traefik 是整个 NAS 外网入口的核心,从下图我们简单说一下从外至内访问的路径,用户访问 Gitea,实际是通过 Traefik 进行反代访问的 Gitea,Photoprism 和 Jellyfin 也是一样的。这仅仅是一个举例,其它很多 WEB 应用也是经过 Traefik 反代,当然您也可以使用 Nginx、APISIX、HAProxy 等。
Traefik 简介
在现代的微服务架构中,对于请求的路由、负载均衡以及 SSL 证书的自动化管理变得至关重要。Traefik 正是一个为此而生的云原生反向代理和负载均衡器。本文将为您简要介绍 Traefik,它的部署方式以及它的优缺点。
什么是 Traefik?
Traefik 是一个开源的、用 Go 编写的现代 HTTP 反向代理和负载均衡器,专为微服务而设计。它可以与大多数流行的容器和编排工具(如 Docker、Kubernetes 和 Swarm)无缝集成。Traefik 可以自动发现新的服务或容器,并为它们自动配置路由。
部署方式:
-
作为 Docker 容器运行: Traefik 可以直接作为 Docker 容器来运行,利用 Docker API 进行服务发现。
-
在 Kubernetes 集群中运行: Traefik 可以作为 Kubernetes 的 Ingress Controller 来运行,从而自动发现并路由到集群中的服务。
-
使用其他编排工具:除了 Docker 和 Kubernetes,Traefik 还支持许多其他编排解决方案,如 Swarm、Rancher 等。
优点:
-
动态配置:与其他反向代理不同,Traefik 可以动态地发现并配置新的服务。无需手动修改配置文件并重新启动代理。
-
自动 SSL:Traefik 可以与 Let’s Encrypt 集成,为您的服务自动提供和续订 SSL 证书。
-
简单的配置:与其他解决方案相比,Traefik 的配置更为简洁明了。
-
丰富的中间件:Traefik 提供了多种内置的中间件,如: 重试、基于路径的路由、基本认证等。
-
高性能和轻量级:由于其 Go 的基础结构,Traefik 是轻量级且高性能的。
缺点:
-
学习曲线:对于那些习惯于传统的反向代理(如 Nginx 或 Apache)的人来说,Traefik 的某些概念可能需要一些时间来熟悉。
-
高级配置的复杂性:尽管基本配置相对简单,但高级用例可能会变得更为复杂。
总之 Traefik 是一个强大而灵活的反向代理和负载均衡器,特别适用于微服务架构。它的自动服务发现、动态配置和自动 SSL 管理使其成为现代应用部署的理想选择。如果您正在寻找一个现代、高性能的反向代理解决方案,那么 Traefik 绝对值得一试。
Traefik 部署
因为在家用 NAS 中部署,所以采用 Docker 方式部署,如果是在 Kubernetes 中部署则采用 Ingress Controller 方式。这里采用 Docker-compose 进行管理,下面是对应的 docker-compose.yaml 文件。
先说一下家用 NAS 部署 Traefik ,对外提供服务的提前条件:
- 一个自己的域名
- 能够分配动态公网 IP 的带宽(可以找 ISP 提供商要求分配公网 IP)
- Cloudflare 平台账号,由 Cloudflare 接管您的域名解析,基于 Cloudflare + Let’s Encrypt 实际证书自动续期功能。(Aliyun、DNSPod 都可以,根据自己实际需求)
# 中间件及 SSL/TLS 证书相关配置
[root@demo traefik]# cat > config/dynamic.yaml << /EOF
tls:
options:
default:
minVersion: VersionTLS12
cipherSuites:
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 # TLS 1.2
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 # TLS 1.2
- TLS_AES_256_GCM_SHA384 # TLS 1.3
- TLS_CHACHA20_POLY1305_SHA256 # TLS 1.3
curvePreferences:
- CurveP521
- CurveP384
sniStrict: true
http:
middlewares:
SecHeaders:
headers:
forceSTSHeader: true
stsIncludeSubdomains: true
#stsSeconds: 31536000
stsSeconds: 15768000
sslRedirect: true
sslForceHost: true
EOF
[root@demo traefik]# cat > docker-compose.yaml << /EOF
version: "3"
services:
traefik:
privileged: true
image: traefik:v2.10.1
restart: always
environment:
CF_API_KEY: xxx # CloudFlare API EKY
CF_API_EMAIL: xxx # CloudFlare 注册邮箱地址
stdin_open: true
volumes:
- /SSD/Demo/traefik/letsencrypt:/letsencrypt # 挂载证书存放目录
- /var/run/docker.sock:/var/run/docker.sock
- /SSD/Demo/traefik/config:/etc/traefik/config # 挂载traefik配置目录
tty: true
networks:
- traefik_net
ports:
- 8880:8880/tcp
- 1443:1443/tcp
- 8085:8085/tcp
command:
- --providers.docker=true
- --providers.file=true
- --providers.docker.exposedByDefault=false
- --api.debug=true
- --api=true
- --api.dashboard=true
- --api.insecure=true
- --accesslog=true
- --entrypoints.traefik.address=:8085
# - --entrypoints.dashboard.address=:8080
#- --entrypoints.api.address=:8080
- --entryPoints.web.address=:8880
- --entryPoints.websecure.address=:1443 # HTTPS端口,家用带宽不提供443、80端口解析服务
- --entrypoints.web.http.redirections.entryPoint.to=websecure
- --entrypoints.web.http.redirections.entryPoint.scheme=https
- --certificatesresolvers.myresolver.acme.dnschallenge.provider=cloudflare # 域名解析提供商
- --certificatesresolvers.myresolver.acme.dnschallenge.delaybeforecheck=30
- --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json
- --certificatesresolvers.myresolver.acme.email= [email protected] # 设置一个let's encrypt 证书申请邮箱
- --providers.file.directory=/etc/traefik/config
- --providers.file.watch=true
labels:
- "traefik.enable=true"
- "traefik.docker.network=traefik_net"
- "traefik.http.routers.dashboard.tls=true"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.entryPoints=websecure"
- "traefik.http.routers.dashboard.tls.certresolver=myresolver"
- "traefik.http.routers.dashboard.rule=Host(`traefik.rockylinux.cn`) " # Traefik 使用的域名
- "traefik.http.middlewares.dashboard-auth.basicauth.users=username:password" # 通过命令 htpasswd -nb username:password 加密
- "traefik.http.routers.dashboard.middlewares=dashboard-auth@docker,SecHeaders@file"
- "traefik.http.routers.dashboard.tls.domains[0].main=rockylinux.cn"
- "traefik.http.routers.dashboard.tls.domains[0].sans=*.rockylinux.cn"
networks:
traefik_net:
external: true
EOF
# 启动 Traefik 服务
[root@demo traefik]# docker-compose up -d
# 确保启动服务正常
[root@demo traefik]# docker-compose ps
Docker 启动正常以后,正常通过域名 DNS 解析或者绑定 hosts 解析,就可以打开对应 Traefik Dashboard 了。如果需要从公网可以打开,首先手动在 Cloudflare 上创建一条 A 记录解析至动态公网 IP(可以上路由器查看,或者 curl ifconfig.me 命令获取,后续会单独分享 ddns-go 动态 DNS 解析管理工具),然后路由器上开启 1443 端口 DNAT 至 Traefik 服务器的 1443 端口,最后打开 Traefik Dashboard。
参考文献
[1] Traefik 官方文档
[2] GitHub – traefik/traefik
写在最后
至此,我们对 Traefik 的基本概念和在 Docker 中的部署进行了简要的介绍。Traefik 无疑是现代云原生应用的强大伙伴,能够满足微服务架构中的各种路由和负载均衡需求。当然,实际应用中,Traefik 的配置和用法会远比我们此次介绍的要丰富得多。
感谢您的阅读!在下一篇文章中,我们将转向另一个令人兴奋的家庭影音篇,我们将探讨其特点、安装过程和如何与其它工具整合等,敬请期待!
下篇预告: DIY NAS系列 13 — 影音管理之 Jellyfin 安装与配置
启动后插件出现错误,请问是什么原因
ERRORS
middleware “SecHeaders@file” does not exist
文章中少写了中间件部份配置,已补充至文档当中。
Unable to obtain ACME certificate for domains “com,*.com” error=”unable to generate a certificate for the domains [com *.com]: error: one or more domains had a problem:n[*.*com] [.**com] acme: error presenting token: cloudflare: failed to find zone loseyourip.com.: zone could not be foundn[com] [com] acme: error presenting token: cloudflare: failed to find zone loseyourip.com.: zone could not be foundn” rule=”Host(
traefik.****com
) ” routerName=dashboard@docker providerName=myresolver.acme ACME CA=”https://acme-v02.api.letsencrypt.org/directory”请问怎么解决
此报错分为两部:
1、Cloudflare 中未发现 xxx.com 域名,说明域名未接入Cloudflare管理。
2、令牌出错,说明在 CF_API_KEY 不对,需要从 https://dash.cloudflare.com/profile/api-tokens 获取。