前情提要 - fowardAuth鉴权中间件的使用:
【traefik】使用forwardAuth中间件做网关层的全局鉴权
1. 问题
我的 traefik-ingress-controller 所在 namespace: traefik
业务服务所在 namespace: apps
路由与 forwardAuth 中间件配置如下:
# 路由
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami-ingressroute
namespace: apps
spec:
entryPoints:
- http
routes:
- match: Host(`vm.apps.com`) && PathPrefix(`/`)
kind: Rule
services:
- name: whoami-svc
port: 80
middlewares:
- name: forward-auth # 鉴权中间件
# 鉴权中间件
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: forward-auth
namespace: apps
spec:
forwardAuth:
address: "http://whoami-svc:80/forwardAuth" # 转发到whoami-svc这个service
发现 traefik 找不到这个 address 地址,traefik 日志报错如下:
msg="Error calling http://whoami-svc:80/forwardAuth. Cause: Get \"http://whoami-svc:80/forwardAuth\\": dial tcp: lookup whoami-svc on 10.96.0.10:53: no such host" middlewareName=apps-forward-auth@kubernetescrd middlewareType=ForwardedAuthType
2. 解决
这个请求是一个跨 namespace 的请求,即 traefik-ingress-controller(在 ns: traefik 下)经过中间件请求 http://whoami-svc:80/forwardAuth 时,k8s DNS 根据 traefik 当前所在的 namespace 解析这个域名,而 ns: traefik 中并没有 whoami-svc 这个 service,因此解析失败。
因此,当你的 traefik 需要使用跨 namespace 的功能时,最好在 address 中配置完整的、携带 ns 名称的域名,即:
将
forwardAuth:
address: "http://whoami-svc:80/forwardAuth"
改为
forwardAuth:
address: "http://whoami-svc.apps:80/forwardAuth" # 显式指明apps这个ns
这样做的好处是增加了配置的明确性和可靠性,尤其是在多命名空间环境中。
这样可以确保无论 traefik 位于哪个命名空间,它都能正确解析到目标服务。