首页
/ Traefik 在 Kubernetes 上暴露服务的进阶指南:Middleware、Let's Encrypt、Sticky Session、多层路由与服务级中间件

Traefik 在 Kubernetes 上暴露服务的进阶指南:Middleware、Let's Encrypt、Sticky Session、多层路由与服务级中间件

2026-09-07 11:33:56作者:瞿蔚英Wynne

本文基于仓库中的 进阶指南 整理而成,承接 入门指南 的部署基础,面向已经在 Kubernetes 中通过 Traefik Proxy 完成基础服务暴露的开发者。你将系统掌握如何用 Middleware 施加安全头与 IP 白名单、用 Let's Encrypt(IngressRoute)与 cert-manager(Gateway API)实现证书自动化、用 TraefikService 实现会话粘滞、用 IngressRoute parentRefs 构建按角色鉴权的多层路由,并在路由与服务两个层级精准编排中间件,最终打造可上生产环境的 Ingress 网关。

前置要求

  • 已完成 入门指南,拥有一个可用的 Traefik + Kubernetes 部署环境;
  • 一个已安装 Traefik Proxy 的 Kubernetes 集群;
  • 本地 kubectl 已正确配置并指向该集群;
  • 沿用入门指南中的 whoami 示例应用及其 HTTPRoute / IngressRoute 配置。

后续所有 YAML 均可在集群中直接 kubectl apply,用于演示的域名 whoami.docker.localhost 可替换为你自己的真实域名。

添加 Middlewares:安全头与访问控制

Middlewares 是 Traefik 处理管道中用于修改请求或响应的中间件,是安全加固的第一道关卡。下面先创建两个典型中间件:负责安全响应头的 Headers(详见 参考文档)和负责来源控制的 IP AllowList(详见 参考文档)。

创建 Middleware 资源

将下列内容保存为 middlewares.yaml

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: secure-headers
  namespace: default
spec:
  headers:
    frameDeny: true
    sslRedirect: true
    browserXssFilter: true
    contentTypeNosniff: true
    stsIncludeSubdomains: true
    stsPreload: true
    stsSeconds: 31536000
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: ip-allowlist
  namespace: default
spec:
  ipAllowList:
    sourceRange:
      - 127.0.0.1/32
      - 10.0.0.0/8  # Typical cluster network range
      - 192.168.0.0/16  # Common local network range

应用它:

kubectl apply -f middlewares.yaml

参数速查:

  • frameDeny:添加 X-Frame-Options: DENY,阻止页面被第三方站点以 iframe 嵌入(防点击劫持);
  • sslRedirect:HTTP 请求被重定向到 HTTPS;
  • browserXssFilter:添加 X-XSS-Protection: 1; mode=block
  • contentTypeNosniff:添加 X-Content-Type-Options: nosniff,禁止浏览器猜测 MIME 类型;
  • stsSeconds: 31536000:HSTS max-age 秒数,配合 stsIncludeSubdomains(作用于子域)与 stsPreload(申请加入浏览器预加载列表)构成完整 HSTS 策略;
  • ipAllowList.sourceRange:以 CIDR 列表声明放行来源,命中即放行,其余来源返回 403。

这些选项的实现与默认值逻辑位于仓库 pkg/middlewares/headerspkg/middlewares/ipallowlist 包内,阅读源码可核对每个头部字段在 Go 侧的默认行为。

Gateway API:通过 ExtensionRef 引用 Middlewares

Gateway API 的规范中,对请求的细粒度加工使用 Filters 机制。Traefik 通过 ExtensionRef 这种可扩展 filter 类型,让 HTTPRoute 能直接引用 traefik.io 组的 Middleware CRD——这是 Gateway API 场景下使用 Traefik 中间件的标准方式,与 HTTPRoute 规范天然融合,不依赖任何注解。

更新 whoami-route.yaml

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: whoami
  namespace: default
spec:
  parentRefs:
  - name: traefik-gateway
    sectionName: websecure
  hostnames:
  - "whoami.docker.localhost"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /api
    filters:
    - type: ExtensionRef
      extensionRef:  # Headers Middleware Definition
        group: traefik.io
        kind: Middleware
        name: secure-headers
    - type: ExtensionRef
      extensionRef: # IP AllowList Middleware Definition
        group: traefik.io
        kind: Middleware
        name: ip-allowlist
    backendRefs:
    - name: whoami-api
      port: 80
  - matches:
    - path:
        type: PathPrefix
        value: /
    filters:
    - type: ExtensionRef
      extensionRef:  # Headers Middleware Definition
        group: traefik.io
        kind: Middleware
        name: secure-headers
    - type: ExtensionRef
      extensionRef: # IP AllowList Middleware Definition
        group: traefik.io
        kind: Middleware
        name: ip-allowlist
    backendRefs:
    - name: whoami
      port: 80

应用变更:

kubectl apply -f whoami-route.yaml

注意 /api/ 两条规则都同时应用了两个中间件,含义是:无论走 API 还是首页路径,都先加安全头、再做来源白名单校验。

IngressRoute:通过 routes.middlewares 引用 Middlewares

若你使用 Traefik 自有的 IngressRoute CRD,更新 whoami-ingressroute.yaml,把中间件挂在每条 route 上:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: whoami
  namespace: default
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`whoami.docker.localhost`) && Path(`/api`)
    kind: Rule
    middlewares: # Middleware Definition
    - name: secure-headers
    - name: ip-allowlist
    services:
    - name: whoami-api
      port: 80
  - match: Host(`whoami.docker.localhost`)
    kind: Rule
    middlewares: # Middleware Definition
    - name: secure-headers
    - name: ip-allowlist
    services:
    - name: whoami
      port: 80
  tls:
    certResolver: le
kubectl apply -f whoami-ingressroute.yaml

此处 tls.certResolver: le 指向后续小节配置的 Let's Encrypt 证书解析器。IngressRoute CRD 结构中,routes[].middlewares(类型 []MiddlewareRef)与 spec.tls.certResolver 的定义见仓库 pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressroute.go

验证中间件是否生效

用 curl 检查响应头是否带上安全策略:

curl -k -I -H "Host: whoami.docker.localhost" https://localhost/

预期可见类似输出:

HTTP/2 200
x-content-type-options: nosniff
x-frame-options: DENY
x-xss-protection: 1; mode=block
strict-transport-security: max-age=31536000; includeSubDomains; preload
content-type: text/plain; charset=utf-8
content-length: 403

验证 IP 白名单时,可临时把 sourceRange 改成不包含你当前出口 IP 的网段,再请求一次,应收到 403 被拒绝的结果,从而确认访问控制真实生效。

使用 Let's Encrypt 自动化签发证书

!!! info Traefik 内置的 Let's Encrypt 集成仅面向 IngressRoute 生效,不会为 Gateway API 的 listener 自动签发证书。Gateway API 场景请使用 cert-manager 或其他证书控制器。

!!! important "Public DNS 前提" Let's Encrypt 需要公网可达的域名来完成所有权校验。若像示例一样使用 whoami.docker.localhost 这类本地域名,证书将保持自签名。生产环境请换成拥有公网 DNS 记录并指向 Traefik 实例的真实域名。

IngressRoute + Traefik 内置 ACME

在 Traefik 的 Helm values.yaml 中配置证书解析器(resolver):

additionalArguments:
  - "--certificatesresolvers.le.acme.email=your-email@example.com" #replace with your email
  - "--certificatesresolvers.le.acme.storage=/data/acme.json"
  - "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web"

三个参数分别声明:ACME 账户邮箱、证书存储文件路径(持久化挂载的关键,证书与账户密钥都写入该 json 文件)、使用 HTTP-01 challenge 并指定走名为 web 的入口点完成质询。

升级 Traefik 使其加载上述配置:

helm upgrade traefik traefik/traefik -n traefik --reuse-values -f values.yaml

随后让 IngressRoute 使用该解析器申请证书:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: whoami
  namespace: default
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`whoami.docker.localhost`) && Path(`/api`)
    kind: Rule
    middlewares:
    - name: secure-headers
    - name: ip-allowlist
    services:
    - name: whoami-api
      port: 80
  - match: Host(`whoami.docker.localhost`)
    kind: Rule
    middlewares:
    - name: secure-headers
    - name: ip-allowlist
    services:
    - name: whoami
      port: 80
  tls:
    certResolver: le
kubectl apply -f whoami-ingressroute.yaml

Traefik 会在配置热加载后,按 Host 规则自动为匹配的域名申请并续期证书,全程无需手工管理 Secret。

Gateway API + cert-manager

Gateway API 一侧先安装 cert-manager:

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.10.0/cert-manager.yaml

随后创建 Issuer 与 Certificate(保存为 letsencrypt-issuer-andwhoami-certificate.yaml):

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: letsencrypt
spec:
  acme:
    email: your-email@example.com # replace with your email
    server: https://acme-v02-staging.api.letsencrypt.org/directory # Replace with the production server in production
    privateKeySecretRef:
      name: letsencrypt-account-key
    solvers:
      - http01:
          gatewayHTTPRoute:
            parentRefs:
              - name: traefik
                namespace: default
                kind: Gateway
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: whoami
  namespace: default
spec:
  secretName: whoami-tls-le        # Name of secret where the generated certificate will be stored.
  dnsNames:
    - "whoami.docker.localhost" # Replace a real domain
  issuerRef:
    name: letsencrypt
    kind: Issuer

要点解读:

  • solvers[].http01.gatewayHTTPRoute.parentRefs 告诉 cert-manager:用 HTTP-01 质询时,把挑战请求经名为 traefik、位于 default 命名空间的 Gateway(HTTPRoute)发布出去,由其转发到 ACME 验证服务器;
  • 示例使用 staging 环境(acme-v02-staging),便于反复调试且不消耗生产配额;上线前请替换为生产目录 https://acme-v02.api.letsencrypt.org/directory
  • Certificate.secretName 指定证书落地 Secret 名,即下一步 Gateway 引用的 whoami-tls-le

!!! important "Public DNS 前提" Let's Encrypt 必须通过公网验证域名所有权。使用 whoami.docker.localhost 之类的本地域名时,cert-manager 会发起质询但无法完成,证书仍将保持自签名。生产环境请改用指向集群入口的公网域名。

应用上述资源:

kubectl apply -f letsencrypt-issuer-andwhoami-certificate.yaml

更新 Gateway,让 websecure listener 引用 cert-manager 生成的证书:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: traefik-gateway
  namespace: default
spec:
  gatewayClassName: traefik
  listeners:
  - name: web
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: All
  - name: websecure
    port: 443
    protocol: HTTPS
    allowedRoutes:
      namespaces:
        from: All
    tls:
      certificateRefs:
      - name: whoami-tls-le  # References the secret created by cert-manager
kubectl apply -f gateway.yaml

此后,既有 HTTPRoute 在访问 websecure listener 时将自动使用这份证书完成 TLS 握手。

验证证书签发结果

# Check certificate status
kubectl get certificate -n default

# Verify the certificate chain
curl -v https://whoami.docker.localhost/ 2>&1 | grep -i "server certificate"

当签发成功后,可从返回的证书链中看到 issuer 为 Let's Encrypt。若使用 staging 环境,证书链中会体现其 staging 根,属正常现象。

配置 Sticky Sessions(会话粘滞)

会话粘滞保证同一用户的多次请求始终落在同一个后端 Pod 上,是带本地会话状态应用(如含内存 Session 的 Web 服务)的必备能力。Traefik 通过加权负载均衡的 sticky.cookie 实现:首次请求时种下一个 Cookie,后续请求依据该 Cookie 计算同后端转发。

先把副本扩容到 3

kubectl scale deployment whoami --replicas=3

多副本才能直观对比"粘滞"与"普通负载均衡"的差异。

Gateway API + TraefikService

Gateway API 本身只认识原生 Service 后端;要让其使用 Traefik 的负载均衡能力(加权、粘滞),需要借助 Traefik 扩展出的 TraefikService CRD。先创建粘滞服务(保存为 whoami-sticky-service.yaml):

apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: whoami-sticky
  namespace: default
spec:
  weighted:
    services:
      - name: whoami
        port: 80
        weight: 1
    sticky:
      cookie:
        name: sticky_cookie
        secure: true
        httpOnly: true
kubectl apply -f whoami-sticky-service.yaml

weighted 分组只放一个成员也可启用粘滞——粘滞语义与权重互不冲突。接着在 HTTPRoute 中,把对应 backendRefs 指向该 TraefikService(通过 group: traefik.io + kind: TraefikService 显式告知 Gateway API 这是扩展后端类型):

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: whoami
  namespace: default
spec:
  parentRefs:
  - name: traefik-gateway
    sectionName: websecure
  hostnames:
  - "whoami.docker.localhost"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /api
    filters:
    - type: ExtensionRef
      extensionRef:  # Headers Middleware Definition
        group: traefik.io
        kind: Middleware
        name: secure-headers
    - type: ExtensionRef
      extensionRef: # IP AllowList Middleware Definition
        group: traefik.io
        kind: Middleware
        name: ip-allowlist
    backendRefs:
    - name: whoami-api
      port: 80
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - group: traefik.io          # <── tell Gateway this is a TraefikService
      kind: TraefikService
      name: whoami-sticky
    filters:
    - type: ExtensionRef
      extensionRef:  # Headers Middleware Definition
        group: traefik.io
        kind: Middleware
        name: secure-headers
    - type: ExtensionRef
      extensionRef: # IP AllowList Middleware Definition
        group: traefik.io
        kind: Middleware
        name: ip-allowlist
    backendRefs:
    - name: whoami
      port: 80
kubectl apply -f whoami-route.yaml

仓库 Gateway API provider 在解析 HTTPRoute 时,对这类指向 Traefik 扩展资源的 backendRef 会转换为对应的 Traefik 服务模型,其解析逻辑见 pkg/provider/kubernetes/gateway/httproute.go

IngressRoute + TraefikService

IngressRoute 同样可把某条 route 的服务替换为粘滞版 TraefikService:

apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: whoami-sticky
  namespace: default
spec:
  weighted:
    services:
    - name: whoami
      port: 80
      sticky:
        cookie:
          name: sticky_cookie
          secure: true
          httpOnly: true
kubectl apply -f whoami-sticky-service.yaml

更新 IngressRoute,在 services 项中指明 kind: TraefikService

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: whoami
  namespace: default
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`whoami.docker.localhost`) && Path(`/api`)
    kind: Rule
    middlewares: # Middleware Definition
    - name: secure-headers
    - name: ip-allowlist
    services:
    - name: whoami-api
      port: 80
  - match: Host(`whoami.docker.localhost`)
    kind: Rule
    middlewares: # Middleware Definition
    - name: secure-headers
    - name: ip-allowlist
    services:
    - name: whoami-sticky  # Changed from whoami to whoami-sticky
      kind: TraefikService  # Added kind: TraefikService
  tls:
    certResolver: le
kubectl apply -f whoami-ingressroute.yaml

底层实现上,CRD provider 会把 TraefikServicespec.weighted.sticky.cookie 字段翻译成动态配置中的负载均衡 Sticky(含 Cookie 名称、Secure、HTTPOnly 以及可选的 SameSite、MaxAge、Domain、Path),并写入 LoadBalancer 服务;映射逻辑集中在 pkg/provider/kubernetes/crd/kubernetes_http.go。CRD 的类型定义则见 pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressroute.go

验证粘滞会话

带 Cookie 连续请求,应始终命中同一后端 Pod:

# First request - save cookies to a file
curl -k -c cookies.txt -H "Host: whoami.docker.localhost" https://localhost/

# Subsequent requests - use the cookies
curl -k -b cookies.txt -H "Host: whoami.docker.localhost" https://localhost/
curl -k -b cookies.txt -H "Host: whoami.docker.localhost" https://localhost/

观察每次响应的 Hostname 字段:使用同一 cookie 文件时它应保持不变,即粘滞生效。

对照实验——不带 Cookie 请求,应被轮询到不同 Pod:

# Requests without cookies should be load-balanced across different pods
curl -k -H "Host: whoami.docker.localhost" https://localhost/
curl -k -H "Host: whoami.docker.localhost" https://localhost/

此时各次响应的 Hostname 会不同。

!!! important "浏览器测试注意" 浏览器中测试需保持同一浏览器会话以维持 Cookie。示例 Cookie 带有 httpOnlysecure 标记:前者保证脚本(JavaScript)无法读取,后者保证仅通过 HTTPS 传输,因此只能用同一 HTTPS 会话持续访问。

更完整的粘滞与加权配置说明见 负载均衡 Service 参考文档

搭建 Multi-Layer Routing(多层路由)

多层路由让 Router 之间形成父子层级:父 Router 先经过中间件处理请求(如完成鉴权、注入头部),再由子 Router 依据加工后的请求做最终路由决策。典型场景包括"先鉴权、再按角色分发",以及分层逐步叠加中间件(父层做限流/CORS,子层做更具体的处理)。

!!! info "IngressRoute 专属能力" 多层路由由 Kubernetes IngressRoute(CRD)通过 spec.parentRefs 字段原生支持,标准 Kubernetes Ingress 与 Gateway API 资源不提供该能力。从源码结构看,Gateway API provider 解析 HTTPRoute 时不具备 parentRefs 语义,而 multi-layer-routing.md 明确指出其受支持面为 File、KV 存储与 Kubernetes CRD provider。

基于认证的多层路由示例

设计:父 IngressRoute api-parent 负责 Host(api.docker.localhost) && PathPrefix(/api) 匹配并施加 BasicAuth;两个子 IngressRoute 依据中间件写入的 X-Auth-User 头分别路由到 admin 与 user 后端。

!!! important "父 Router 约束" 多层路由中的父 Router 不得定义 services,服务选择完全交由子 Router 依据各自规则完成。所有子 IngressRoute 必须通过 parentRefs 正确引用父级。

先部署两个后端服务(保存为 whoami-backends.yaml):

# whoami-backends.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: admin-backend
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: admin-backend
  template:
    metadata:
      labels:
        app: admin-backend
    spec:
      containers:
      - name: whoami
        image: traefik/whoami
        env:
        - name: WHOAMI_NAME
          value: "Admin Backend"
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: admin-backend
  namespace: default
spec:
  selector:
    app: admin-backend
  ports:
  - port: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: user-backend
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: user-backend
  template:
    metadata:
      labels:
        app: user-backend
    spec:
      containers:
      - name: whoami
        image: traefik/whoami
        env:
        - name: WHOAMI_NAME
          value: "User Backend"
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: user-backend
  namespace: default
spec:
  selector:
    app: user-backend
  ports:
  - port: 80
kubectl apply -f whoami-backends.yaml

接着创建 Secret(存放 htpasswd 账号)、BasicAuth 中间件与三份 IngressRoute(保存为 mlr-ingressroute.yaml):

# mlr-ingressroute.yaml
apiVersion: v1
kind: Secret
metadata:
  name: auth-secret
  namespace: default
type: Opaque
stringData:
  users: |
    admin:$apr1$DmXR3Add$wfdbGw6RWIhFb0ffXMM4d0
    user:$apr1$GJtcIY1o$mSLdsWYeXpPHVsxGDqadI.
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: auth-middleware
  namespace: default
spec:
  basicAuth:
    secret: auth-secret
    headerField: X-Auth-User
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: api-parent
  namespace: default
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`api.docker.localhost`) && PathPrefix(`/api`)
    kind: Rule
    middlewares:
    - name: auth-middleware
  # Note: No services and no TLS config - this is a parent IngressRoute
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: api-admin
  namespace: default
spec:
  parentRefs:
  - name: api-parent
    namespace: default  # Optional, defaults to same namespace
  routes:
  - match: HeadersRegexp(`X-Auth-User`, `admin`)
    kind: Rule
    services:
    - name: admin-backend
      port: 80
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: api-user
  namespace: default
spec:
  parentRefs:
  - name: api-parent
    namespace: default  # Optional, defaults to same namespace
  routes:
  - match: HeadersRegexp(`X-Auth-User`, `user`)
    kind: Rule
    services:
    - name: user-backend
      port: 80

配置要点:

  • BasicAuth 中间件的 headerField: X-Auth-User 让认证通过后把用户名写入请求头,供下游规则匹配——这是"先鉴权、再分流"的枢纽;
  • 父 IngressRoute 的 route 只挂中间件、无 services、无 TLS;
  • 子 IngressRoute 不声明 entryPoints,仅凭 parentRefs 挂接到父级,其中 namespace 省略时默认同命名空间。

!!! note "生成密码哈希" 上文哈希由 Apache 工具 htpasswd 生成。需要自建账号时执行:

```bash
# Using htpasswd (Apache utils)
htpasswd -nb admin yourpassword
```

应用整份配置:

kubectl apply -f mlr-ingressroute.yaml

在 CRD 层,spec.parentRefs []IngressRouteRef 即为多层路由入口字段(见 ingressroute.go);HTTP provider 会读取每个子路由的 parentRefs 建立父子拓扑并把这些引用并入"父路由器名"集合,处理逻辑见 kubernetes_http.go

验证多层路由

# Request goes through parent router → auth middleware → admin child router
curl -k -u admin:test -H "Host: api.docker.localhost" https://localhost/api

admin:test 认证应得到 admin-backend 的响应;改用 user:test 则命中 user-backend。

工作原理

  1. 请求到达 api.docker.localhost/api
  2. 父 IngressRouteapi-parent)按 host + path 命中;
  3. BasicAuth 中间件完成认证并把用户名写入 X-Auth-User 头;
  4. 子 IngressRouteapi-adminapi-user)按该头的值匹配;
  5. 请求被转发到对应的 Kubernetes Service。

跨命名空间引用父级

在子路由 parentRefs 中显式给出父级所在命名空间即可:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: api-child
  namespace: app-namespace
spec:
  parentRefs:
  - name: api-parent
    namespace: shared-namespace  # Parent in different namespace
  routes:
  - match: Path(`/child`)
    kind: Rule
    services:
    - name: child-service
      port: 80

!!! important "跨命名空间开关" 使用跨命名空间父引用必须先在 Traefik Helm values 中开启 allowCrossNamespace

```yaml
providers:
  kubernetesCRD:
    allowCrossNamespace: true
```

该开关即 CRD provider 配置结构中的 `AllowCrossNamespace` 字段(见 [kubernetes.go](https://gitcode.com/GitHub_Trending/tr/traefik/blob/14bc52dd1f1d1c08cedd1da531a527fc04d79c19/pkg/provider/kubernetes/crd/kubernetes.go?utm_source=gitcode_repo_files)),开启时 Traefik 会打印一条警示日志,提醒你已允许跨命名空间引用资源、请确认符合安全预期。

一个子路由挂接多个父级

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: api-child
  namespace: default
spec:
  parentRefs:
  - name: parent-one
  - name: parent-two
  routes:
  - match: Path(`/api`)
    kind: Rule
    services:
    - name: child-service
      port: 80

同一份路由逻辑可被多个入口域/路径共享,减少重复配置。仓库集成测试中也有同构用例(integration/fixtures/routing/multi_layer_auth.toml 即文件 provider 下的多层鉴权示例)。更完整语义参见 多层路由参考文档

Service Middlewares(服务级中间件)

路由级中间件只在命中某条路由规则时生效;服务级中间件则挂在"服务"上,对流向该服务的所有请求生效——无论流量来自哪个 Router。适合把同一套 headers / 限流 / 鉴权统一下沉到服务层,避免在每个 Router 上重复声明。

何时使用服务级中间件

  • 多个 Router 转发到同一服务,且都需要施加同一中间件;
  • 需要确保无论流量从何而来,该服务始终经过某个中间件;
  • 希望把中间件配置集中在服务层统一管理。

!!! info "服务级 vs 路由级" - 路由级:仅当流量命中该 Router 规则时执行; - 服务级:对该服务收到的全部流量执行; - 两者同时配置时,先执行路由级中间件,再执行服务级中间件。这一顺序由动态配置的服务引用机制保证:请求先穿过路由构建的中间件链,再进入服务内的负载均衡处理器链。

IngressRoute:在 services 项内嵌中间件

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: service-headers
  namespace: default
spec:
  headers:
    customRequestHeaders:
      X-Service-Middleware: "applied"
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: whoami
  namespace: default
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`whoami.docker.localhost`)
    kind: Rule
    services:
    - name: whoami
      port: 80
      middlewares:
        - name: service-headers
  tls: {}

保存为 service-middleware-ingressroute.yaml 并应用:

kubectl apply -f service-middleware-ingressroute.yaml

CRD 类型中,ServiceSpec.middlewares []MiddlewareRef 正是该内嵌引用的定义位置(见 ingressroute.go)。

Gateway API:backendRefs 内置 Filters

Gateway API 支持在单个后端上直接施加 filter:既可用 Traefik 扩展的 ExtensionRef 引用任意 Middleware CRD,也可用原生 RequestHeaderModifier 完成纯增删改头的场景。

ExtensionRef 方式:

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: service-headers
  namespace: default
spec:
  headers:
    customRequestHeaders:
      X-Service-Middleware: "applied"
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: whoami
  namespace: default
spec:
  parentRefs:
  - name: traefik-gateway
    sectionName: websecure
  hostnames:
  - "whoami.docker.localhost"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: whoami
      port: 80
      filters:
      - type: ExtensionRef
        extensionRef:
          group: traefik.io
          kind: Middleware
          name: service-headers

原生 RequestHeaderModifier 方式:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: whoami
  namespace: default
spec:
  parentRefs:
  - name: traefik-gateway
    sectionName: websecure
  hostnames:
  - "whoami.docker.localhost"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: whoami
      port: 80
      filters:
      - type: RequestHeaderModifier
        requestHeaderModifier:
          add:
          - name: X-Backend-Header
            value: "gateway-api-filter"

保存为 service-middleware-gateway.yaml 并应用:

kubectl apply -f service-middleware-gateway.yaml

标准 Ingress:服务注解方式

使用标准 Kubernetes Ingress 时,用 Service 注解声明服务级中间件:

apiVersion: v1
kind: Service
metadata:
  name: whoami
  namespace: default
  annotations:
    traefik.ingress.kubernetes.io/service.middlewares: default-service-headers@kubernetescrd
spec:
  selector:
    app: whoami
  ports:
    - port: 80

注解值格式为 <namespace>-<middleware-name>@kubernetescrd,其中 @kubernetescrd 表明中间件来源为 Kubernetes CRD provider。

验证服务级中间件

curl -k -H "Host: whoami.docker.localhost" https://localhost/

whoami 返回体中应能看到由服务级中间件注入的自定义请求头:

X-Service-Middleware: applied

服务级中间件更完整的字段语义见 service.md 中 middlewares 一节

总结

完成本篇后,你已具备生产级 Traefik on Kubernetes 的关键能力:

  • 用 Middleware 施加安全头(HSTS、X-Frame-Options、nosniff 等)与 IP 白名单,在 Gateway API(ExtensionRef)与 IngressRoute(routes.middlewares)两条路径上都可编排;
  • 证书自动化双方案:IngressRoute 走内置 Let's Encrypt resolver,Gateway API 走 cert-manager + Gateway certificateRefs,并理解本地域名下证书保持自签名的约束;
  • 通过 TraefikService 的加权粘滞 Cookie 为有状态应用启用会话保持,覆盖 Gateway API 与 IngressRoute 两种后端引用形态;
  • parentRefs 构建"父层鉴权、子层按角色分流"的多层路由,包括跨命名空间(需开启 allowCrossNamespace)与多父级引用;
  • 把中间件下沉到服务层(IngressRoute services 内嵌 / HTTPRoute backendRefs.filters / Ingress Service 注解),实现集中化管理。

延伸方向

入门指南 与本文基础上,可继续探索:

  • 更精细的路由规则与优先级,如按查询参数、请求头、HTTP 方法匹配;
  • 更多中间件能力,如鉴权(Basic/Digest/Forward)、限流(ratelimit 等)、请求改写(StripPrefix、AddPrefix 等);
  • Kubernetes CRD 与 Gateway API provider 的完整配置项(分别对应 providers.kubernetesCRDproviders.kubernetesGateway),可用于调整命名空间隔离、标签选择器、入口点绑定等行为。
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
docsdocs
暂无描述
Markdown
899
5.83 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
925
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.84 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
601
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.03 K
525
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
395