跳到正文
Træfɪk

Traefik 与使用 NGINX 注解的 Ingress

通过兼容 NGINX 注解,支持将 NGINX Ingress Controller 迁移到 Traefik。

NGINX Ingress Controller 退役

Kubernetes NGINX Ingress Controller 项目已宣布于 2026 年 3 月退役,此后不再提供更新或安全补丁。 Traefik 通过支持 NGINX 注解提供迁移路径,使你无需重写所有 Ingress 配置即可迁移工作负载。

→ 分步操作请参阅 NGINX 到 Traefik 迁移指南。

有关 NGINX Ingress Controller 退役的更多信息,请参阅 Kubernetes 官方博客公告。

Ingress 发现

默认情况下,此提供者会发现集群中的所有 Ingress, 如果同时使用标准 Kubernetes Ingress 提供者,可能会创建重复的路由器。

最佳实践:

  • 通过 IngressClass 指定应由此提供者处理的 Ingress
  • 配置 watchNamespace,将发现范围限制到单个命名空间
  • 使用 watchNamespaceSelector,根据命名空间标签选择 Ingress

路由配置

此提供者监听传入的 Ingress 事件,并自动将 NGINX 注解转换为 Traefik 动态配置, 创建处理流量所需的路由器、服务、中间件及其他组件。

ConfigMap 配置与默认行为

路由注解的优先级高于提供者级别的默认值, 但它们不能控制 NGINX Ingress Controller 通过 ConfigMap 在全局配置的所有行为。

需要注意的默认行为差异:

  • 请求缓冲:NGINX 默认启用 proxy-request-buffering,而 Traefik 需要通过提供者的 proxyRequestBuffering 选项显式启用。

为了让迁移前后的行为保持一致, 请检查并配置 Traefik 提供者级别的选项,使其与当前 NGINX ConfigMap 设置一致。 可用设置见提供者配置选项。

配置示例

配置 Kubernetes Ingress NGINX 控制器
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: traefik-ingress-controller
rules:
  - apiGroups:
      - ""
    resources:
      - namespaces
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - configmaps
      - pods
      - secrets
      - endpoints
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - services
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - networking.k8s.io
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - networking.k8s.io
    resources:
      - ingresses/status
    verbs:
      - update
  - apiGroups:
      - networking.k8s.io
    resources:
      - ingressclasses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - events
    verbs:
      - create
      - patch
  - apiGroups:
      - discovery.k8s.io
    resources:
      - endpointslices
    verbs:
      - list
      - watch
      - get

    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: traefik-ingress-controller
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: traefik-ingress-controller
    subjects:
      - kind: ServiceAccount
        name: traefik-ingress-controller
        namespace: default
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: traefik
  labels:
    app: traefik

spec:
  replicas: 1
  selector:
    matchLabels:
      app: traefik
  template:
    metadata:
      labels:
        app: traefik
    spec:
      serviceAccountName: traefik-ingress-controller
      containers:
        - name: traefik
          image: traefik:v3.7
          args:
            - --entryPoints.web.address=:80
            - --providers.kubernetesingressnginx
          ports:
            - name: web
              containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  name: traefik
spec:
  type: LoadBalancer
  selector:
    app: traefik
  ports:
    - name: web
      port: 80
      targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: whoami
  labels:
    app: whoami

spec:
  replicas: 2
  selector:
    matchLabels:
      app: whoami
  template:
    metadata:
      labels:
        app: whoami
    spec:
      containers:
        - name: whoami
          image: traefik/whoami
          ports:
            - containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  name: whoami

spec:
  selector:
    app: whoami
  ports:
    - name: http
      port: 80
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: nginx
spec:
  controller: k8s.io/ingress-nginx

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myingress

spec:
  ingressClassName: nginx
  rules:
    - host: whoami.localhost
      http:
        paths:
          - path: /bar
            pathType: Exact
            backend:
              service:
                name:  whoami
                port:
                  number: 80
          - path: /foo
            pathType: Exact
            backend:
              service:
                name:  whoami
                port:
                  number: 80

注解支持

本节列出所有已知的 NGINX Ingress 注解。 以下注解按类别分组,便于查阅。

身份认证

注解 限制与说明
nginx.ingress.kubernetes.io/auth-type
nginx.ingress.kubernetes.io/auth-secret
nginx.ingress.kubernetes.io/auth-secret-type
nginx.ingress.kubernetes.io/auth-realm
nginx.ingress.kubernetes.io/auth-url 仅支持 URL 和复制响应头。转发认证与 NGINX 的行为不同。在同一个 Ingress 中与 rewrite-target(或 configuration-snippet/auth-snippet 中的 rewrite 指令)组合使用时,发送给认证服务的 X-Forwarded-Uri 请求头反映的是重写后的路径,而不是客户端的原始请求路径。支持使用以下 NGINX 变量进行有限的变量插值:$scheme, $host, $http_*, $hostname, $request_uri, $request_method, $query_string, $args, $arg_*, $remote_addr, $uri, $document_uri, $server_name, $server_port, $content_type, $content_length, $cookie_*, $is_args, $best_http_host, $escaped_request_uri, $proxy_add_x_forwarded_for。
nginx.ingress.kubernetes.io/auth-signin 收到 401 响应时重定向到登录 URL。支持使用以下 NGINX 变量进行有限的变量插值:$scheme, $host, $http_*, $hostname, $request_uri, $request_method, $query_string, $args, $arg_*, $remote_addr, $uri, $document_uri, $server_name, $server_port, $content_type, $content_length, $cookie_*, $is_args, $best_http_host, $escaped_request_uri, $proxy_add_x_forwarded_for。

与 ingress-nginx 一样,Traefik 会自动附加 rd=$scheme://$best_http_host$escaped_request_uri,以便认证服务在登录后跳转回来;传入空的 rd 可以禁用此行为。路由没有 Host 匹配器时,变量插值会使用请求的 Host 请求头,因此可能被利用来制造开放重定向。依赖此行为时,强烈建议通过 Host 规则限定路由器的作用范围。
nginx.ingress.kubernetes.io/auth-snippet 支持的指令:proxy_method、more_set_headers、proxy_set_header、more_set_input_headers、set、if、return code [text]。支持使用以下 NGINX 变量进行有限的变量插值:$scheme, $host, $http_*, $hostname, $request_uri, $request_method, $query_string, $args, $arg_*, $remote_addr, $uri, $document_uri, $server_name, $server_port, $content_type, $content_length, $cookie_*, $is_args, $best_http_host, $escaped_request_uri, $proxy_add_x_forwarded_for。
nginx.ingress.kubernetes.io/auth-method 此注解使用 Nginx 的 proxy_method 指令,因此不能用于已经在 auth-snippet 注解中包含 proxy_method 指令的 Ingress。
nginx.ingress.kubernetes.io/auth-response-headers
nginx.ingress.kubernetes.io/enable-global-auth

SSL/TLS

注解 限制与说明
nginx.ingress.kubernetes.io/ssl-redirect 全局启用后,无法针对单条路由禁用。
nginx.ingress.kubernetes.io/force-ssl-redirect 全局启用后,无法针对单条路由禁用。
nginx.ingress.kubernetes.io/ssl-passthrough SNI 和默认后端处理方式存在部分差异。
nginx.ingress.kubernetes.io/proxy-ssl-server-name
nginx.ingress.kubernetes.io/proxy-ssl-name
nginx.ingress.kubernetes.io/proxy-ssl-verify
nginx.ingress.kubernetes.io/proxy-ssl-secret
nginx.ingress.kubernetes.io/auth-tls-secret 验证失败时,在 TLS 握手阶段拒绝连接,而不是返回 400 Bad Request。
nginx.ingress.kubernetes.io/auth-tls-verify-client 验证失败时,在 TLS 握手阶段拒绝连接,而不是返回 400 Bad Request。
nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream
nginx.ingress.kubernetes.io/auth-tls-verify-depth Go 不支持配置证书链深度限制。只要证书链有效,不论包含多少中间证书都会接受。

会话亲和性

注解 限制与说明
nginx.ingress.kubernetes.io/affinity
nginx.ingress.kubernetes.io/affinity-mode 仅支持 persistent 模式,不支持 balanced 模式。
nginx.ingress.kubernetes.io/affinity-canary-behavior 仅支持 sticky 行为,不支持 legacy 行为。
nginx.ingress.kubernetes.io/session-cookie-name
nginx.ingress.kubernetes.io/session-cookie-secure
nginx.ingress.kubernetes.io/session-cookie-path
nginx.ingress.kubernetes.io/session-cookie-domain
nginx.ingress.kubernetes.io/session-cookie-samesite
nginx.ingress.kubernetes.io/session-cookie-max-age
nginx.ingress.kubernetes.io/session-cookie-expires

负载均衡与后端

注解 限制与说明
nginx.ingress.kubernetes.io/load-balance 尚未实现,会静默忽略。
nginx.ingress.kubernetes.io/backend-protocol 不支持 FCGI 和 AUTO_HTTP。
nginx.ingress.kubernetes.io/service-upstream
nginx.ingress.kubernetes.io/upstream-hash-by 支持使用以下 NGINX 变量进行有限的变量插值:$scheme, $host, $http_*, $hostname, $request_uri, $request_method, $query_string, $args, $arg_*, $remote_addr, $uri, $document_uri, $server_name, $server_port, $content_type, $content_length, $cookie_*, $is_args, $best_http_host, $escaped_request_uri, $proxy_add_x_forwarded_for。
nginx.ingress.kubernetes.io/upstream-vhost 支持 NGINX 变量插值。支持请求时变量($scheme, $host, $http_*, $hostname, $request_uri, $request_method, $query_string, $args, $arg_*, $remote_addr, $uri, $document_uri, $server_name, $server_port, $content_type, $content_length, $cookie_*, $is_args, $best_http_host, $escaped_request_uri, $proxy_add_x_forwarded_for),以及由提供者解析的逐 location 变量($namespace、$ingress_name、$service_name、$service_port、$location_path)。不提供 NGINX 内部变量 $proxy_upstream_name。
nginx.ingress.kubernetes.io/custom-headers 不支持类似 NGINX global-allowed-response-headers 配置的响应头白名单功能。
nginx.ingress.kubernetes.io/default-backend 指定与 Ingress 资源位于同一命名空间的备用服务,在主后端服务没有活动端点时处理请求。如果该服务暴露多个端口,将流量发送到第一个端口。
nginx.ingress.kubernetes.io/proxy-http-version 控制与后端通信使用的 HTTP 协议版本。支持值 "1.1",表示禁用到后端的 HTTP/2。值 "1.0" 不受支持,并会记录警告。
nginx.ingress.kubernetes.io/canary
nginx.ingress.kubernetes.io/canary-by-header
nginx.ingress.kubernetes.io/canary-by-header-value
nginx.ingress.kubernetes.io/canary-by-header-pattern
nginx.ingress.kubernetes.io/canary-by-cookie
nginx.ingress.kubernetes.io/canary-weight
nginx.ingress.kubernetes.io/canary-weight-total
nginx.ingress.kubernetes.io/x-forwarded-prefix

CORS

注解 限制与说明
nginx.ingress.kubernetes.io/enable-cors 部分支持。
nginx.ingress.kubernetes.io/cors-allow-credentials
nginx.ingress.kubernetes.io/cors-allow-headers
nginx.ingress.kubernetes.io/cors-allow-methods
nginx.ingress.kubernetes.io/cors-allow-origin 支持 protocol://*.domain[:port] 形式的单层通配符来源,其中 * 恰好匹配一个 DNS 标签。与 ingress-nginx 一样,其他位置的通配符会被忽略。
nginx.ingress.kubernetes.io/cors-expose-headers
nginx.ingress.kubernetes.io/cors-max-age

路由

注解 限制与说明
nginx.ingress.kubernetes.io/app-root
nginx.ingress.kubernetes.io/from-to-www-redirect 不支持通配符主机名。
nginx.ingress.kubernetes.io/use-regex
nginx.ingress.kubernetes.io/rewrite-target 在同一个 Ingress 中与 auth-url/auth-snippet 组合使用时,下游中间件(包括 ForwardAuth 请求)看到的是重写后的路径,而不是原始请求路径。
nginx.ingress.kubernetes.io/permanent-redirect 默认使用 301 Moved Permanently 状态码。
nginx.ingress.kubernetes.io/permanent-redirect-code 仅接受有效的 3XX HTTP 状态码。
nginx.ingress.kubernetes.io/temporal-redirect 优先于 permanent-redirect 注解,默认使用 302 Found 状态码。
nginx.ingress.kubernetes.io/temporal-redirect-code 仅接受有效的 3XX HTTP 状态码。
nginx.ingress.kubernetes.io/custom-http-errors 指定需要拦截并交由错误页后端处理的 HTTP 状态码列表,以逗号分隔。出现其中任意状态码时,请求会被转发到全局默认后端,或转发到 default-backend 注解指定的后端。
nginx.ingress.kubernetes.io/server-alias 如果别名与已有 Ingress Host 规则冲突,则忽略该别名。Ingress Host 规则始终优先。
nginx.ingress.kubernetes.io/server-snippet 支持的指令:add_header、location、proxy_method、more_set_headers、proxy_set_header、more_set_input_headers、set、if、return code [text]。支持使用以下 NGINX 变量进行有限的变量插值:$scheme, $host, $http_*, $hostname, $request_uri, $request_method, $query_string, $args, $arg_*, $remote_addr, $uri, $document_uri, $server_name, $server_port, $content_type, $content_length, $cookie_*, $is_args, $best_http_host, $escaped_request_uri, $proxy_add_x_forwarded_for。
nginx.ingress.kubernetes.io/configuration-snippet 支持的指令:add_header、proxy_method、more_set_headers、proxy_set_header、more_set_input_headers、set、rewrite、if、return code [text]。支持使用以下 NGINX 变量进行有限的变量插值:$scheme, $host, $http_*, $hostname, $request_uri, $request_method, $query_string, $args, $arg_*, $remote_addr, $uri, $document_uri, $server_name, $server_port, $content_type, $content_length, $cookie_*, $is_args, $best_http_host, $escaped_request_uri, $proxy_add_x_forwarded_for。

IP 白名单

客户端 IP 策略

默认情况下,根据传入请求的远端地址确定客户端 IP。 Traefik 位于反向代理之后时,实际客户端 IP 通常包含在 X-Forwarded-For 请求头中。 可以通过提供者选项 ipAllowListStrategy 在全局配置此行为。

注解 限制与说明
nginx.ingress.kubernetes.io/whitelist-source-range
nginx.ingress.kubernetes.io/allowlist-source-range

速率限制

注解 限制与说明
nginx.ingress.kubernetes.io/limit-rps 超出限制时,返回 429 Too Many Requests,而不是 NGINX 默认的 503 Service Unavailable。
nginx.ingress.kubernetes.io/limit-rpm 超出限制时,返回 429 Too Many Requests,而不是 NGINX 默认的 503 Service Unavailable。
nginx.ingress.kubernetes.io/limit-burst-multiplier 配置值小于 1 时,默认采用 5 倍乘数。超出限制时,返回 429 Too Many Requests,而不是 NGINX 默认的 503 Service Unavailable。
nginx.ingress.kubernetes.io/limit-connections 超出限制时,返回 429 Too Many Requests,而不是 NGINX 默认的 503 Service Unavailable。并发连接限制按客户端 IP 地址计算,小于或等于 0 的值会被安全忽略。

缓冲

注解 限制与说明
nginx.ingress.kubernetes.io/proxy-request-buffering
nginx.ingress.kubernetes.io/proxy-body-size
nginx.ingress.kubernetes.io/client-body-buffer-size
nginx.ingress.kubernetes.io/proxy-buffering
nginx.ingress.kubernetes.io/proxy-buffer-size
nginx.ingress.kubernetes.io/proxy-buffers-number 在 Traefik 中,proxy-buffers-number 实际上用于计算单个缓冲区的大小,计算方式为 size * number。
nginx.ingress.kubernetes.io/proxy-max-temp-file-size

可观测性

注解 限制与说明
nginx.ingress.kubernetes.io/enable-access-log 必须先在安装配置中启用访问日志(全局或按入口点启用),此注解才会生效。访问日志已启用时,可以将此注解设为 "false",为指定 Ingress 禁用日志。相反,如果某入口点禁用了访问日志,可以将此注解设为 "true",为指定 Ingress 启用日志。

超时

注解 限制与说明
nginx.ingress.kubernetes.io/proxy-connect-timeout 可以通过提供者级别的 proxyConnectTimeout 选项 在全局定义超时。
nginx.ingress.kubernetes.io/proxy-send-timeout 可以通过提供者级别的 proxySendTimeout 选项 在全局定义超时。
nginx.ingress.kubernetes.io/proxy-read-timeout 可以通过提供者级别的 proxyReadTimeout 选项 在全局定义超时。

重试

注解 限制与说明
nginx.ingress.kubernetes.io/proxy-next-upstream 与 NGINX 不同,Traefik 不保证将重试请求发送到不同服务器。error 与 timeout 没有区别,二者都被视为 TCP 层故障。可以通过提供者级别的 proxyNextUpstream 选项 在全局定义此配置。
nginx.ingress.kubernetes.io/proxy-next-upstream-tries 为避免无限重试,不限次数的重试(0)会被限制为可用服务器的数量。可以通过提供者级别的 proxyNextUpstreamTries 选项 在全局定义此值。
nginx.ingress.kubernetes.io/proxy-next-upstream-timeout 可以通过提供者级别的 proxyNextUpstreamTimeout 选项 在全局定义超时。

限制

注意事项与关键行为差异

  • 身份认证:转发认证的行为不同,且不支持会话缓存。NGINX 支持基于子请求的认证,而 Traefik 转发原始请求。
  • 会话亲和性:仅支持 persistent 模式。
  • 主节点选举:不支持,不提供带主节点选举的集群模式。
  • 负载均衡:仅支持 round_robin,不支持 EWMA 和 IP 哈希。
  • CORS:NGINX 无条件返回所有配置的响应头;Traefik 对预检请求和普通请求的响应头处理方式不同。
  • TLS/后端协议:Traefik 不支持 AUTO_HTTP、FCGI 和部分 TLS 选项。
  • 路径处理:Traefik 默认保留尾斜杠;NGINX 默认移除尾斜杠,除非另行配置。
  • 重试:NGINX 保证下一次重试会交给下一台服务器;Traefik 则可能仍将重试交给同一台服务器。
  • 速率限制:NGINX 使用漏桶算法,将请求排队并以固定速率放行。队列(burst)填满后,超出的请求立即被拒绝,并返回 503。 Traefik 使用令牌桶算法,桶最初装满 burst 个令牌,每个请求消耗一个令牌,再以 limit-rps 的速率补充令牌。桶为空时,请求会等待补充令牌;如果预计等待时间过长,则返回 429 拒绝请求。 实践中,Traefik 在突发负载下稍显宽松,因为它会平滑突发流量,而不是直接丢弃;但稳态吞吐量上限相近。

不支持的注解

希望支持更多注解?

可以通过两种方式扩展支持范围:

欢迎所有贡献和建议,一起完善支持。

注解 说明
nginx.ingress.kubernetes.io/auth-tls-error-page
nginx.ingress.kubernetes.io/auth-tls-match-cn
nginx.ingress.kubernetes.io/auth-cache-key
nginx.ingress.kubernetes.io/auth-cache-duration
nginx.ingress.kubernetes.io/auth-keepalive
nginx.ingress.kubernetes.io/auth-keepalive-share-vars
nginx.ingress.kubernetes.io/auth-keepalive-requests
nginx.ingress.kubernetes.io/auth-keepalive-timeout
nginx.ingress.kubernetes.io/auth-proxy-set-headers
nginx.ingress.kubernetes.io/disable-proxy-intercept-errors
nginx.ingress.kubernetes.io/limit-rate-after
nginx.ingress.kubernetes.io/limit-rate
nginx.ingress.kubernetes.io/limit-whitelist
nginx.ingress.kubernetes.io/global-rate-limit
nginx.ingress.kubernetes.io/global-rate-limit-window
nginx.ingress.kubernetes.io/global-rate-limit-key
nginx.ingress.kubernetes.io/global-rate-limit-ignored-cidrs
nginx.ingress.kubernetes.io/preserve-trailing-slash Traefik 默认保留尾斜杠。
nginx.ingress.kubernetes.io/proxy-cookie-domain
nginx.ingress.kubernetes.io/proxy-cookie-path
nginx.ingress.kubernetes.io/proxy-redirect-from
nginx.ingress.kubernetes.io/proxy-redirect-to
nginx.ingress.kubernetes.io/proxy-ssl-ciphers
nginx.ingress.kubernetes.io/proxy-ssl-verify-depth
nginx.ingress.kubernetes.io/proxy-ssl-protocols
nginx.ingress.kubernetes.io/enable-rewrite-log
nginx.ingress.kubernetes.io/satisfy
nginx.ingress.kubernetes.io/session-cookie-conditional-samesite-none
nginx.ingress.kubernetes.io/session-cookie-change-on-failure
nginx.ingress.kubernetes.io/ssl-ciphers
nginx.ingress.kubernetes.io/ssl-prefer-server-ciphers
nginx.ingress.kubernetes.io/connection-proxy-header
nginx.ingress.kubernetes.io/enable-opentracing
nginx.ingress.kubernetes.io/opentracing-trust-incoming-span
nginx.ingress.kubernetes.io/enable-opentelemetry
nginx.ingress.kubernetes.io/opentelemetry-trust-incoming-span
nginx.ingress.kubernetes.io/enable-modsecurity
nginx.ingress.kubernetes.io/enable-owasp-core-rules
nginx.ingress.kubernetes.io/modsecurity-transaction-id
nginx.ingress.kubernetes.io/modsecurity-snippet
nginx.ingress.kubernetes.io/mirror-request-body
nginx.ingress.kubernetes.io/mirror-target
nginx.ingress.kubernetes.io/mirror-host
nginx.ingress.kubernetes.io/denylist-source-range
nginx.ingress.kubernetes.io/stream-snippet

全局配置

Traefik 没有像 NGINX 那样暴露全部全局配置选项,以控制 Ingress 的默认行为。

NGINX 中某些可全局配置的行为(例如默认 SSL 重定向、速率限制或会话亲和性)目前不受支持,也不能像 NGINX 一样按 Ingress 覆盖。适用的限制已在下方注解表中注明。


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

文档由 HeadFile Studio 翻译。

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