使用Traefik实现单域名下访问路径重复的多仪表盘
要将多个独立域名的仪表盘统一到 dashboard.demo.com 域名下,核心思路是利用Traefik的路径前缀匹配和中间件路径处理能力,为每个仪表盘分配专属路径前缀,同时解决内部路径调用的兼容性问题。以下是针对两种场景的具体实现方案:
一、基础配置框架
首先为每个仪表盘定义路径剥离中间件,用于移除访问时的前缀,将请求转发到对应服务的原始路径;再通过IngressRoute统一绑定域名与各仪表盘的路由规则。
1. 定义路径剥离中间件
创建三个中间件分别对应三个仪表盘,用于剥离访问前缀:
# dashboard1路径剥离中间件 apiVersion: traefik.containo.us/v1alpha1 kind: Middleware metadata: name: strip-dashboard1 spec: stripPrefix: prefixes: - "/dashboard1" forceSlash: false # dashboard2路径剥离中间件 apiVersion: traefik.containo.us/v1alpha1 kind: Middleware metadata: name: strip-dashboard2 spec: stripPrefix: prefixes: - "/dashboard2" forceSlash: false # dashboard3路径剥离中间件 apiVersion: traefik.containo.us/v1alpha1 kind: Middleware metadata: name: strip-dashboard3 spec: stripPrefix: prefixes: - "/dashboard3" forceSlash: false
2. 统一域名IngressRoute配置
通过IngressRoute将 dashboard.demo.com 域名与三个仪表盘的路由绑定:
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: unified-dashboard spec: entryPoints: - websecure # 使用HTTPS入口 routes: # 路由到dashboard1 - match: Host(`dashboard.demo.com`) && PathPrefix(`/dashboard1`) kind: Rule services: - name: dashboard1-service # 替换为你的dashboard1服务名 port: 80 # 替换为服务暴露的端口 middlewares: - name: strip-dashboard1 # 路由到dashboard2 - match: Host(`dashboard.demo.com`) && PathPrefix(`/dashboard2`) kind: Rule services: - name: dashboard2-service # 替换为你的dashboard2服务名 port: 80 middlewares: - name: strip-dashboard2 # 路由到dashboard3 - match: Host(`dashboard.demo.com`) && PathPrefix(`/dashboard3`) kind: Rule services: - name: dashboard3-service # 替换为你的dashboard3服务名 port: 80 middlewares: - name: strip-dashboard3 tls: certResolver: letsencrypt # 关联已配置的cert-manager证书解析器
二、针对性场景处理
场景1:dashboard1和dashboard2共享内部路径 /apis/v1/services
这种情况的核心问题是避免路径冲突,同时保证内部请求能正确路由到对应服务,优先推荐以下两种方案:
方案1:修改仪表盘Base URL(最优)
如果仪表盘支持配置Base URL,直接在部署时为dashboard1和dashboard2分别设置基础路径为 /dashboard1 和 /dashboard2。例如通过环境变量或配置文件修改:
- dashboard1配置:
BASE_URL=/dashboard1 - dashboard2配置:
BASE_URL=/dashboard2
修改后,页面内的所有绝对路径请求会自动带上前缀,经过Traefik的stripPrefix中间件处理后,会转发到对应服务的原始路径(如 /apis/v1/services),完全兼容内部调用。
方案2:通过中间件重写路径(适配无法修改仪表盘的情况)
如果无法修改仪表盘配置,可通过ReplacePathRegex中间件,结合请求的Referer头识别来源,重写绝对路径请求:
# 为dashboard1的API请求重写路径 apiVersion: traefik.containo.us/v1alpha1 kind: Middleware metadata: name: rewrite-dashboard1-api spec: replacePathRegex: regex: ^/apis/v1/services(.*) replacement: /dashboard1/apis/v1/services$1 # 在IngressRoute中添加对应规则 - match: Host(`dashboard.demo.com`) && Path(`/apis/v1/services`) && Headers(`Referer`, `https://dashboard.demo.com/dashboard1/.*`) kind: Rule services: - name: dashboard1-service port: 80 middlewares: - name: rewrite-dashboard1-api
同理为dashboard2添加相同逻辑的中间件和路由规则,即可解决路径冲突问题。
场景2:dashboard3使用多内部路径(如 /logo.png、/user/login)
由于我们已经为dashboard3配置了PathPrefix(/dashboard3)和strip-dashboard3中间件,所有以/dashboard3开头的请求都会被转发到dashboard3服务,并自动移除前缀。只要用户通过https://dashboard.demo.com/dashboard3访问仪表盘,页面内的相对路径请求会自动带上前缀,经过中间件处理后,会正确映射到dashboard3服务的原始路径(如 /logo.png、/user/login),无需额外配置。
内容的提问来源于stack exchange,提问作者Rupesh Shinde

