跳到正文
Træfɪk

在 Kubernetes 上使用 Traefik 暴露服务:高级篇

本指南建立在基础指南介绍的概念和配置之上。继续之前,请确保你已完成基础指南,并已在 Kubernetes 上部署可正常运行的 Traefik。

在本高级指南中,你将学习如何通过以下功能增强 Traefik 部署:

  • 使用中间件设置安全响应头和访问控制
  • 使用 Let's Encrypt 自动管理证书(IngressRoute)
  • 使用 cert-manager 自动管理证书(Gateway API)
  • 为有状态应用启用粘性会话
  • 使用多层路由实现分层路由,处理复杂的身份认证场景(仅适用于 IngressRoute)
  • 使用服务中间件在服务级别应用中间件

前提条件

  • 已完成基础指南
  • 已安装 Traefik Proxy 的 Kubernetes 集群
  • 已配置 kubectl,可与集群交互
  • 基础指南中的 Traefik 部署已正常运行

添加中间件

中间件可以在请求或响应经过 Traefik 时对其进行修改。下面添加两种实用的中间件:用于安全防护的 Headers,以及用于访问控制的 IP 允许列表。

创建中间件

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

将其保存为 middlewares.yaml,然后应用:

kubectl apply -f middlewares.yaml

在 Gateway API 中应用中间件

在 Gateway API 中,可以使用 ExtensionRef 过滤器类型来应用中间件。这是 Gateway API 使用 Traefik 中间件的首选标准方式,因为它直接集成在 HTTPRoute 规范中。

现在更新 HTTPRoute,使用 ExtensionRef 过滤器引用这些中间件:

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

更新 whoami-route.yaml 文件,然后应用:

kubectl apply -f whoami-route.yaml

这种方式使用 Gateway API 原生的过滤器机制,而非注解。ExtensionRef 过滤器类型允许你直接在 HTTPRoute 规范中引用 Traefik 中间件,更符合 Gateway API 的设计原则。

在 IngressRoute 中应用中间件

更新现有的 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: # 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

更新 whoami-ingressroute.yaml 文件,然后应用:

kubectl apply -f whoami-ingressroute.yaml

验证中间件的效果

检查安全响应头是否已应用:

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,然后验证访问是否被阻止。

使用 Let's Encrypt 生成证书

提示

Traefik 内置的 Let's Encrypt 集成支持 IngressRoute,但不会自动为 Gateway API 监听器签发证书。对于 Gateway API,应使用 cert-manager 或其他证书控制器。

在 IngressRoute 中使用 Let's Encrypt

在 Traefik 的 values.yaml 中配置证书解析器:

additionalArguments:
  - "[email protected]" #replace with your email
  - "--certificatesresolvers.le.acme.storage=/data/acme.json"
  - "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web"

需要公共 DNS

Let's Encrypt 可能需要一个可公开访问的域名来验证域名所有权。使用 whoami.docker.localhost 等本地域名测试时,证书仍为自签名证书。在生产环境中,请替换为真实域名,并为其配置可公开访问、指向 Traefik 实例的 DNS 记录。

使用此配置更新 Traefik 安装:

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

更新 IngressRoute,使用 Let's Encrypt 证书:

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

在 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:

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: letsencrypt
spec:
  acme:
    email: [email protected] # 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

需要公共 DNS

Let's Encrypt 需要一个可公开访问的域名来验证所有权。使用 whoami.docker.localhost 等本地域名时,cert-manager 会尝试执行验证,但验证将失败,证书仍为自签名证书。在生产环境中,请替换为具有公共 DNS 记录的域名,并将该记录指向集群的入口。

保存 YAML 文件,然后应用:

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

现在更新 Gateway,使用生成的证书:

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

应用更新后的 Gateway:

kubectl apply -f gateway.yaml

现在,现有 HTTPRoute 在连接到启用了安全连接的网关监听器时,会使用此证书。

验证 Let's Encrypt 证书

证书签发后,可以这样验证:

# Check certificate status
kubectl get certificate -n default

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

你应该看到证书由 Let's Encrypt 签发。

配置粘性会话

粘性会话可确保同一用户的请求始终发送到同一台后端服务器,这对维护会话状态的应用至关重要。下面为 whoami 服务实现粘性会话。

首先,扩容 Deployment

为了演示粘性会话,先将 Deployment 扩容到 3 个副本:

kubectl scale deployment whoami --replicas=3

通过 TraefikService 在 Gateway API 中实现粘性会话

首先,创建用于粘性会话的 TraefikService:

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

将其保存为 whoami-sticky-service.yaml,然后应用:

kubectl apply -f whoami-sticky-service.yaml

现在更新 HTTPRoute,通过注解引用 TraefikService:

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

更新 whoami-route.yaml 文件,然后应用:

kubectl apply -f whoami-route.yaml

通过 TraefikService 在 IngressRoute 中实现粘性会话

首先,创建用于粘性会话的 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

将其保存为 whoami-sticky-service.yaml,然后应用:

kubectl apply -f whoami-sticky-service.yaml

现在更新 IngressRoute,使其使用此 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

更新 whoami-ingressroute.yaml 文件,然后应用:

kubectl apply -f whoami-ingressroute.yaml

测试粘性会话

你可以发送多个请求,并观察它们是否都到达同一个后端 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 发送请求:

# 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 值,因为每个请求都会经负载均衡分发到不同的 Pod。

浏览器测试

在浏览器中测试时,需要保持同一个浏览器会话,以保留 cookie。为确保安全,cookie 设置了 httpOnly 和 secure 标志,因此只会通过 HTTPS 连接发送,且无法通过 JavaScript 访问。

更多高级配置选项请参阅参考文档。

设置多层路由

多层路由允许路由器之间建立层级关系:父路由器可以先通过中间件处理请求,再由子路由器作出最终的路由决策。这对基于身份认证的路由或分阶段应用中间件特别有用。

IngressRoute 支持

Kubernetes IngressRoute(CRD)通过 spec.parentRefs 字段原生支持多层路由。标准 Kubernetes Ingress 和 Gateway API 资源不支持此功能。

基于身份认证的路由示例

下面创建一个多层路由配置,由父 IngressRoute 对请求进行身份认证,子 IngressRoute 则根据用户角色分发流量。

父路由器要求

多层路由中的父路由器不得定义服务。子路由器将根据各自的匹配规则选择服务。请确保所有子 IngressRoute 都通过 parentRefs 正确引用父路由器。

首先,部署后端服务:

# 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

现在创建多层路由所需的中间件和 IngressRoute:

# 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

生成密码哈希

上面的 密码哈希使用 htpasswd 生成。若要创建自己的用户凭据:

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

应用多层路由配置:

kubectl apply -f mlr-ingressroute.yaml

测试多层路由

测试路由行为:

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

以 admin 身份认证时,你应该看到 admin-backend 服务的响应。尝试使用 user:test 凭据,则会访问 user-backend 服务。

工作原理

  1. 请求到达 api.docker.localhost/api
  2. 父 IngressRoute(api-parent)根据主机和路径匹配请求
  3. BasicAuth 中间件对用户进行身份认证,并将用户名写入 X-Auth-User 请求头
  4. 子 IngressRoute(api-admin 或 api-user)根据请求头的值进行匹配
  5. 请求被转发到相应的 Kubernetes 服务

跨命名空间的父级引用

你可以通过指定 namespace 字段,引用其他命名空间中的父 IngressRoute:

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

跨命名空间的要求

要使用跨命名空间的父级引用,必须在 Traefik Helm values 中启用 allowCrossNamespace 选项:

providers:
  kubernetesCRD:
    allowCrossNamespace: true

引用多个父级

子 IngressRoute 可以引用多个父 IngressRoute:

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

有关多层路由的更多详细信息,请参阅多层路由文档。

服务中间件

服务中间件允许你将中间件应用于服务,而不必逐个配置路由器。这意味着,无论由哪个路由器转发请求,中间件都会对该服务处理的所有请求生效。

当你希望对到达服务的所有流量应用相同的中间件(如响应头、速率限制或身份认证),又不想在每个路由器上分别配置时,这一功能就很有用。

何时使用服务中间件

以下情况适合使用服务中间件:

  • 多个路由器将流量转发到同一个服务,并且都需要应用相同的中间件
  • 你希望确保无论流量如何到达服务,该服务始终应用某个中间件
  • 你希望在服务级别集中配置中间件,以便管理

服务级别与路由器级别的中间件

  • 路由器级别的中间件:仅在流量匹配该路由器的规则时应用
  • 服务级别的中间件:应用于到达服务的所有流量,无论由哪个路由器转发

同时配置两者时,先执行路由器中间件,再执行服务中间件。

在 IngressRoute 中使用服务中间件

在 IngressRoute 中,可以将中间件直接附加到路由中的服务引用上:

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

在 Gateway API 中使用后端过滤器

Gateway API 支持通过 backendRefs[].filters 字段,直接为各个后端应用过滤器,从而实现后端级别的请求修改。

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

Gateway API 也支持原生的 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"

保存并应用:

kubectl apply -f service-middleware-gateway.yaml

在 Kubernetes Ingress 中使用服务注解

对于标准 Kubernetes Ingress,可以通过注解为服务应用中间件:

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 格式。

启用 safeNaming 后,该值变为 <namespace>_<middleware-name>@kubernetescrd,使用与提供者生成的其他名称相同的 _ 分隔符。

测试服务中间件

验证服务中间件是否正常工作:

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

在 whoami 的响应中,你应该看到服务中间件添加的自定义请求头:

X-Service-Middleware: applied

有关服务中间件的更多详细信息,请参阅参考文档。

总结

在本高级指南中,你已学会:

  • 使用安全响应头、IP 允许列表等中间件增强安全性
  • 使用 Let's Encrypt(IngressRoute)和 cert-manager(Gateway API)自动管理证书
  • 为有状态应用实现粘性会话
  • 设置多层路由,实现基于身份认证的路由(仅适用于 IngressRoute)
  • 在服务级别应用中间件,集中管理中间件配置

这些高级功能使你能够在 Kubernetes 上构建可用于生产的 Traefik 部署。你还可以进一步定制各项功能,以满足具体需求。

后续步骤

现在你已掌握 Kubernetes 上 Traefik 的基础和高级功能,还可以继续探索:


版权所有 © 头文件软件工作室

文档由 HeadFile Studio 翻译。

Traefik v3.7 中文快照 · 原文版权归 Traefik Labs 及贡献者所有 · MIT 许可证