Kubernetes IngressRoute
IngressRoute 是 Traefik HTTP 路由器的 CRD 实现。
在创建 IngressRoute 对象之前,你需要将 Traefik Kubernetes CRD(如 定义文件 和 RBAC)应用到你的 Kubernetes 集群。
这会注册 IngressRoute 类型以及其它 Traefik 专属资源。
配置示例
你可以按如下方式声明一个 IngressRoute:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: test-name
namespace: apps
spec:
ingressClassName: traefik-lb
entryPoints:
- web
parentRefs:
- name: parent-gateway
namespace: default # 可选 - 默认为同一命名空间
routes:
- kind: Rule
# 基于 Host 的规则
match: Host(`test.example.com`)
# 挂载中间件
middlewares:
- name: middleware1
namespace: apps
# 启用路由可观测性
observability:
accessLogs: true
metrics: true
tracing: true
# 设置优先级
priority: 10
services:
# 目标 Kubernetes Service
- kind: Service
name: foo
namespace: apps
# 自定义 Traefik 与后端之间的连接
passHostHeader: true
port: 80
responseForwarding:
flushInterval: 1ms
scheme: https
sticky:
cookie:
httpOnly: true
name: cookie
secure: true
strategy: wrr
weight: 10
tls:
# 使用证书解析器生成 TLS 证书
certResolver: foo
domains:
- main: example.net
sans:
- a.example.net
- b.example.net
# 自定义 TLS 选项
options:
name: opt
namespace: apps
# 从 Kubernetes Secret 添加 TLS 证书
secretName: supersecret配置选项
| 字段 | 描述 | 默认值 | 必填 |
|---|---|---|---|
ingressClassName | 定义要使用的 IngressClass 集群资源。它取代了已弃用的 kubernetes.io/ingress.class 注解。spec 字段优先于该注解。 | 否 | |
entryPoints | EntryPoint 名称列表。如果未指定,HTTP 路由器将接受默认 EntryPoint 列表中所有 EntryPoint 的请求。 | 否 | |
parentRefs | 父级 IngressRoute 资源的引用列表,用于多层路由。指定后,此 IngressRoute 的路由器将成为所引用的父 IngressRoute 路由器的子项。详见"多层路由"一节。 | 否 | |
parentRefs[n].name | 引用的父级 IngressRoute 资源名称。 | 是 | |
parentRefs[n].namespace | 引用的父级 IngressRoute 资源命名空间。如果未指定,默认为子 IngressRoute 所在的同一命名空间。跨命名空间引用需要启用 allowCrossNamespace provider 选项。 | 否 | |
routes | 路由列表。 | 是 | |
routes[n].kind | 路由匹配类型,目前只允许 Rule。 | "Rule" | 否 |
routes[n].match | 定义与底层路由器对应的规则。 | 是 | |
routes[n].priority | 定义用于区分相同长度规则的优先级。如果未设置,优先级直接等于规则的长度,最长的具有最高优先级。优先级为 0 会被忽略,使用默认规则长度排序。支持负值。 | 0 | 否 |
routes[n].middlewares | 要附加到 IngressRoute 的中间件列表。更多信息见下文。 | "" | 否 |
routes[n].middlewares[m].name | 中间件名称。字符 @ 不允许。 | 是 | |
routes[n].middlewares[m].namespace | 中间件命名空间。如果中间件与 IngressRoute 位于同一命名空间,可留空。 | 否 | |
routes[n].observability.accessLogs | 定义路由是否产生访问日志。 | false | 否 |
routes[n].observability.metrics | 定义路由是否产生指标。 | false | 否 |
routes[n].observability.tracing | 定义路由是否产生链路追踪数据。 | false | 否 |
routes[n].services | 任何 TraefikService 和 Kubernetes Service 的组合。 | 否 | |
tls | TLS 配置。可以是空值({}):此时会生成自签名证书(如果定义了 tlsStore,则使用其默认证书)。 | 否 | |
tls.secretName | 用于存储证书的 Secret 名称(与 IngressRoute 同一命名空间)。 | "" | 否 |
tls.options | 要使用的 TLSOption 引用。 | 否 | |
tls.options.name | TLSOption 名称。 | "" | 否 |
tls.options.namespace | TLSOption 命名空间。 | "" | 否 |
tls.certResolver | 用于生成自动 TLS 证书的证书解析器名称。 | "" | 否 |
tls.domains | 使用生成的证书提供服务的域名列表(一个 tls.domain 对应一个证书)。 | 否 | |
tls.domains[n].main | 主域名。 | "" | 是 |
tls.domains[n].sans | 备用域名(SANs)列表。 | 否 |
Middleware
- 你可以将 中间件 列表附加到每个 HTTP 路由器。
- 中间件仅在规则匹配时生效,并在请求被转发到 service 之前应用。
- 中间件按它们在 router 中声明的顺序应用。
- 在 Kubernetes 中,
middlewares选项允许你通过名称和命名空间附加中间件(当 Middleware 与 IngressRoute 在同一命名空间时,命名空间可省略)。
IngressRoute 附加多个中间件
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: my-app
namespace: apps
spec:
entryPoints:
- websecure
routes:
- match: Host(`example.com`)
kind: Rule
middlewares:
# 与 IngressRoute 同一命名空间
- name: middleware01
# 默认命名空间
- name: middleware02
namespace: apps
# 其它命名空间
- name: middleware03
namespace: other-ns
services:
- name: whoami
port: 80routes.services.kind
由于 name 字段可以引用不同类型的对象,使用 kind 字段来避免歧义。kind 允许以下值:
Service(默认值):引用 Kubernetes ServiceTraefikService:引用 TraefikService 对象
TLS Options
options 字段允许精细控制 TLS 参数。它引用 TLSOption,仅在定义了 Host 规则时应用。
服务器名称关联
TLS 选项引用始终映射到规则的 Host 部分中找到的主机名,而非路由器或路由器规则。一个规则中也可能有多个 Host 部分。在这种情况下,TLS 选项引用将映射到同样数量的主机名。
TLS 选项是从上述映射中挑选出来的,基于 TLS 握手期间提供的服务器名称,这一切都在实际路由发生之前完成。
在域名劫持(domain fronting)的情况下,如果与 Host Header 和 SNI 关联的 TLS 选项不同,Traefik 将以状态码 421 响应。
冲突的 TLS Options
由于 TLS 选项引用映射到主机名,如果某个配置引入了相同主机名(来自 Host 规则)被两个 TLS 选项引用匹配的情况,就会发生冲突,如下例所示。
示例
IngressRoute01
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: IngressRoute01
namespace: apps
spec:
entryPoints:
- foo
routes:
- match: Host(`example.net`)
kind: Rule
tls:
options: foo
...IngressRoute02
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: IngressRoute02
namespace: apps
spec:
entryPoints:
- foo
routes:
- match: Host(`example.net`)
kind: Rule
tls:
options: bar
...如果发生这种情况,两个映射都会被丢弃,这些路由器的主机名(示例中的 example.net)会改用默认 TLS 选项。
使用 IngressRoute 进行多层路由
多层路由允许在 IngressRoute 之间创建层次关系,父级 IngressRoute 可以在子 IngressRoute 做出路由决策之前应用中间件。
这对于基于身份验证的路由特别有用:父 IngressRoute 对请求进行身份验证并添加上下文(例如,将用户角色作为 Header),子 IngressRoute 基于该上下文进行路由。
当子 IngressRoute 引用具有多个路由的父 IngressRoute 时,所有父路由器都将成为所有子路由器的父级。
有关多层路由概念、验证规则和使用场景的详细信息,请参阅专用的 多层路由 页面。
配置要求
根 IngressRoute
- 没有
parentRefs(层次结构顶部) - 可以有
entryPoints、tls和observability配置 - 可以是父 IngressRoute(有子项)或独立 IngressRoute(有 service)
中间层 IngressRoute
- 通过
parentRefs引用其父 IngressRoute - 有一个或多个子 IngressRoute
- 不得定义
service - 不得有
entryPoints、tls或observability配置
叶子 IngressRoute
- 通过
parentRefs引用其父 IngressRoute - 必须定义
service - 不得有
entryPoints、tls或observability配置
跨命名空间引用
跨命名空间父引用需要启用
allowCrossNamespaceprovider 选项。如果禁用,子 IngressRoute 创建将被跳过并记录错误。
示例:基于身份验证的路由
父 IngressRoute 配合 ForwardAuth 及子 IngressRoute
Parent IngressRoute
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-parent
namespace: default
spec:
entryPoints:
- websecure
tls:
certResolver: letsencrypt
routes:
# 带身份验证的父路由 - 没有 services
- match: Host(`api.example.com`) && PathPrefix(`/api`)
kind: Rule
middlewares:
- name: auth-middleware
namespace: default
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: auth-middleware
namespace: default
spec:
forwardAuth:
address: "http://auth-service.default.svc.cluster.local:8080/auth"
authResponseHeaders:
- X-User-Role
- X-User-NameChild IngressRoutes
# 管理员用户的子 IngressRoute
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-admin
namespace: default
spec:
parentRefs:
- name: api-parent
namespace: default # 可选 - 默认为同一命名空间
routes:
- match: HeadersRegexp(`X-User-Role`, `admin`)
kind: Rule
services:
- name: admin-service
port: 80
---
# 普通用户的子 IngressRoute
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-user
namespace: default
spec:
parentRefs:
- name: api-parent
routes:
- match: HeadersRegexp(`X-User-Role`, `user`)
kind: Rule
services:
- name: user-service
port: 80Services
apiVersion: v1
kind: Service
metadata:
name: auth-service
namespace: default
spec:
ports:
- port: 8080
selector:
app: auth-service
---
apiVersion: v1
kind: Service
metadata:
name: admin-service
namespace: default
spec:
ports:
- port: 80
selector:
app: admin-backend
---
apiVersion: v1
kind: Service
metadata:
name: user-service
namespace: default
spec:
ports:
- port: 80
selector:
app: user-backend工作原理:
- 对
https://api.example.com/api/endpoint的请求匹配父路由器 auth-middleware(ForwardAuth)使用auth-service验证请求auth-service返回 200 OK 并携带X-User-Role头(例如admin或user)- 子路由器根据修改后的请求(带
X-User-Role头)评估规则 - 根据角色将请求路由到
admin-service或user-service
在生产环境使用 Traefik OSS?
如果你在工作中使用 Traefik,可以考虑为其添加企业级 API 网关能力或获取 Traefik OSS 的商业支持。