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/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 在突发负载下稍显宽松,因为它会平滑突发流量,而不是直接丢弃;但稳态吞吐量上限相近。
不支持的注解¶
全局配置¶
Traefik 没有像 NGINX 那样暴露全部全局配置选项,以控制 Ingress 的默认行为。
NGINX 中某些可全局配置的行为(例如默认 SSL 重定向、速率限制或会话亲和性)目前不受支持,也不能像 NGINX 一样按 Ingress 覆盖。适用的限制已在下方注解表中注明。