路由
Ingress 提供灵活的路由功能来匹配请求并将它们路由到相应的后端服务。您可以按主机名和路径匹配请求,支持精确、正则表达式和通配符匹配。
主机匹配
主机匹配是路由请求的主要方式。Ingress 支持三种主机匹配方式:精确(exact)、正则(regex)、通配符(wildcard)。
自动 host_type(默认)
若省略 host_type 或设为 host_type: auto,Ingress 会在编译路由索引时(进程启动或配置 Reload)根据 host 字符串自动选择匹配类型:
- 若
host中含正则元字符( ) [ ] ^ $ | + ? \→ 按 regex 处理 - 否则若含
*→ 按 wildcard 处理 - 否则 → exact
会先判断正则再判断 *,因此像 ^.*\.example\.com$ 这类完整正则不会被误判为通配符。
解析后的类型会写回规则上的 host_type,供后续逻辑使用(如 service.name 捕获、错误页分支等)。若必须按字面量匹配 host(即使看起来像模式),请显式写 host_type: exact。
省略 host_type 的示例:
rules:
# 编译为 regex(括号、\w 等)
- host: ^([a-z0-9-]+)\.inlets\.example\.com$
backend:
service:
name: inlets
port: 8080
# 编译为 wildcard
- host: '*.api.example.com'
backend:
service:
name: api-gateway
port: 8080
# 编译为 exact
- host: idp.example.com
backend:
service:
name: idp
port: 443精确匹配
精确匹配按字面量完全匹配主机名。在自动 host_type 下,普通主机名(无正则元字符且无 *)会解析为 exact:
rules:
- host: example.com
backend:
service:
name: backend-service
port: 8080这将精确匹配 Host: example.com 的请求。
正则表达式匹配
正则表达式匹配允许您使用正则表达式来匹配主机名。可显式写 host_type: regex,也可在模式中含正则元字符时省略 host_type,由编译阶段自动推断为 regex。
rules:
- host: ^t-(\w+).example.work
host_type: regex
backend:
service:
name: task.$1.svc
port: 8080在此示例中,$1 引用 host 正则中的第一个捕获组。对 t-myapp.example.work 的请求将被路由到 task.myapp.svc。
说明: 在 Go 的 regexp 中,\w 等价于 [0-9A-Za-z_],不包含连字符 -。若子域带横线(如 my-app.example.work),需使用允许 - 的写法,例如 ^t-([a-zA-Z0-9-]+).example.work,不能仅依赖 (\w+)。
Service 名称捕获模板
当使用 host_type: regex 时,也可以在 service.name 中使用带作用域的捕获模板(高级用法):
${host.<索引>}:来自 host 正则的捕获组${path.<索引>}:来自命中 path 正则的捕获组
rules:
- host: ^t-(\w+)-(dev|prod).example.work$
host_type: regex
backend:
service:
name: task.${host.1}.${host.2}.svc
port: 8080
paths:
- path: ^/api/v1/([^/]+)/([^/]+)$
backend:
service:
name: ${path.2}.${path.1}.${host.2}.${host.1}.svc
port: 8080兼容性说明:
service.name中旧写法$1、$2...(基于 host 正则)是默认优先/基础用法,并持续完全兼容。request.path.rewrites仍使用重写语法里的$1、$2...(例如^/api/(.*):/v2/$1)。
通配符匹配
通配符匹配使用 * 作为通配符。可显式写 host_type: wildcard,也可在 host 含 * 且无正则元字符时省略 host_type(见上文「自动 host_type」一节)。
rules:
- host: '*.example.work'
host_type: wildcard
backend:
service:
name: wildcard-service
port: 8080这将匹配 example.work 的任何子域,例如 app.example.work、api.example.work 等。
基于路径的路由
您可以在主机规则内定义基于路径的路由规则。路径使用正则表达式模式匹配:
rules:
- host: example.com
backend:
service:
name: default-service
port: 8080
paths:
- path: /api
backend:
service:
name: api-service
port: 8080
- path: /admin
backend:
service:
name: admin-service
port: 8080路径匹配使用正则表达式模式。路径 /api 将匹配 /api、/api/、/api/users 等。
路径匹配优先级
路径按定义的顺序匹配。将使用第一个匹配的路径。如果没有路径匹配,将使用主机级后端。
请求重写
在路由到后端服务时,您可以重写请求路径、头和查询参数。
路径重写
使用正则表达式模式重写请求路径:
rules:
- host: example.com
backend:
service:
name: backend-service
port: 8080
request:
path:
rewrites:
- ^/api/v1/(.*):/api/v2/$1
- ^/old:/new重写格式为 pattern:replacement,其中 pattern 是正则表达式,replacement 是新路径。可以使用 $1、$2 等引用捕获组。
Host 头重写
重写发送到后端的 Host 头:
rules:
- host: example.com
backend:
service:
name: backend-service
port: 8080
request:
host:
rewrite: true当 rewrite: true 时,Host 头将设置为后端服务名称和端口。
头修改
添加或修改请求头:
rules:
- host: example.com
backend:
service:
name: backend-service
port: 8080
request:
headers:
X-Forwarded-Proto: https
X-Custom-Header: value查询参数修改
添加或修改查询参数:
rules:
- host: example.com
backend:
service:
name: backend-service
port: 8080
request:
query:
api_key: secret-key
version: v2重定向
除了代理到后端服务,您还可以重定向请求:
rules:
- host: old.example.com
backend:
redirect:
url: https://new.example.com
permanent: trueurl: 重定向目标 URLpermanent: 如果为true,返回 301 重定向;如果为false,返回 302 重定向
Handler 后端
除了转发到 service,您还可以设置 backend.type: handler,并通过 handler.type 选择:
static_response(默认)file_servertemplatesscript
rules:
- host: handler.example.com
backend:
service:
name: api-service
port: 8080
paths:
- path: /custom/handler/json
backend:
type: handler
handler:
type: static_response
status_code: 200
headers:
Content-Type: application/json
body: |
{"message":"Hello, World!"}
- path: /custom/handler/files
backend:
type: handler
handler:
type: file_server
root_dir: /app/public
index_file: index.html
- path: /custom/handler/templates
backend:
type: handler
handler:
type: templates
root_dir: /app/templates
- path: /custom/handler/script/js
backend:
type: handler
handler:
type: script
engine: javascript
script: |
ctx.response.status_code = 200
ctx.type = "application/json"
ctx.body = JSON.stringify({ method: ctx.method, path: ctx.path })
ctx.setHeader("X-Handler-Engine", "javascript")
- path: /custom/handler/script/go
backend:
type: handler
handler:
type: script
engine: go
script: |
ctx.SetHeader("X-Handler-Engine", "go")
ctx.String(200, "%s %s", ctx.Method, ctx.Path)backend.type:service(默认)或handlerhandler.type:static_response(默认)、file_server、templates、script- 当
handler.type=static_response:支持status_code、headers、body - 当
handler.type=file_server:支持root_dir、index_file - 当
handler.type=templates:支持root_dir - 当
handler.type=script:支持engine、scriptengine=javascript:使用goja;提供ctx:ctx.request/ctx.response- 别名:
ctx.method、ctx.path、ctx.headers - 响应别名:
ctx.status(ctx.response.status_code)、ctx.type(ctx.response.content_type)、ctx.body(ctx.response.body) - 方法:
ctx.setHeader(key, value)和ctx.response.setHeader(key, value)
engine=go:使用yaegi执行脚本,ctx为原生*zoox.Context(例如:ctx.SetHeader(...)、ctx.String(...)、ctx.Fetch())
回退服务
如果没有规则匹配请求,则使用回退服务:
fallback:
service:
name: fallback-service
port: 8080回退服务对于处理未匹配的请求或提供默认后端很有用。
路由示例
同一主机上的多个服务
rules:
- host: example.com
backend:
service:
name: web-service
port: 8080
paths:
- path: /api
backend:
service:
name: api-service
port: 8081
- path: /admin
backend:
service:
name: admin-service
port: 8082带路径重写的正则主机
rules:
- host: ^t-(\w+).example.work
host_type: regex
backend:
service:
name: task.$1.svc
port: 8080
paths:
- path: /api/v1/([^/]+)
backend:
service:
name: $1.example.work
port: 8080
request:
path:
rewrites:
- ^/api/v1/([^/]+):/api/v1/task/$1通配符主机匹配
rules:
- host: '*.example.work'
host_type: wildcard
backend:
service:
name: wildcard-service
port: 8080这匹配 example.work 的任何子域并路由到同一个后端服务。
匹配如何构建(预编译)
Ingress 不会在每次请求时再为 host、path 解析正则。
- 进程启动或配置 Reload 时,
prepare()会构建内部路由索引(core/compile.go):对每条规则先解析最终host_type(含省略或auto时的自动推断),再对作为regex/wildcard的host以及每条paths[].path,使用 Goregexp只编译一次。 - 配置里规则的顺序会保留。 匹配按规则顺序遍历;先命中的 host 规则生效;在同一 host 下 先命中的 path 生效(与优化前语义一致)。
- 若存在非法模式(例如
host或path的正则无法编译),启动或Reload会直接报错失败,需先修正配置。这与早期「可能直到第一次匹配请求才暴露错误」的行为不同。
请求路径上实际仍使用预编译索引。若启用缓存,按主机缓存的路由结果可能以 match.host:v2:<hostname> 形式的键保存(见 缓存),直至 cache.ttl 过期。
最佳实践
- 顺序很重要:将更具体的规则放在通用规则之前
- 尽可能使用精确匹配:普通主机名会推断为 exact,通常比正则或通配符更快
- 需要时可省略
host_type或写auto:看起来像正则或通配符的host会在编译阶段自动识别;若需覆盖(例如含*或括号但必须按字面量匹配),请显式写host_type - 测试正则表达式模式:确保模式符合预期;非法模式会在启动或重载阶段失败
- 使用路径路由:按路径组织路由以提高可维护性
- 设置回退:始终为未匹配的请求配置回退服务