k8s 常用的正则表达式
·
参考大佬:https://blog.csdn.net/remix_xy/article/details/127001584
示例 - ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
emr-vke/ray-cluster-uuid: 221167282729208548-emr-4yw63nfsim3u4ruc1oim-rayjob-sample-raycluster-b5x8f
emr/role: JOB
nginx.ingress.kubernetes.io/rewrite-target: /$1
ray.io/enable-ray-history-server: "true"
creationTimestamp: "2026-05-15T08:11:57Z"
generation: 1
labels:
app.kubernetes.io/created-by: kuberay-operator
app.kubernetes.io/name: kuberay
ray.io/cluster: rayjob-sample-raycluster-b5x8f
ray.io/identifier: rayjob-sample-raycluster-b5x8f-head
name: rayjob-sample-raycluster-b5x8f-head-ingress
namespace: emr-4yw63nfsim3u4ruc1oim-ray
ownerReferences:
- apiVersion: ray.io/v1
blockOwnerDeletion: true
controller: true
kind: RayCluster
name: rayjob-sample-raycluster-b5x8f
uid: 75e96b29-689a-40b3-8a38-281712e3a123
resourceVersion: "3967321"
uid: a083035f-0e6f-446d-9ba5-de1b4d6c405a
spec:
ingressClassName: nginx
rules:
- http:
paths:
- backend:
service:
name: rayjob-sample-raycluster-b5x8f-head-svc
port:
number: 8265
path: /rayjob-sample-raycluster-b5x8f/(.*)
pathType: Exact
status:
loadBalancer:
ingress:
- ip: 118.196.47.109
解释
1. (.*)
(.*) 是一个正则表达式,配合 nginx ingress 的 rewrite(重写) 功能使用。
拆开看:
• . 表示任意一个字符
• * 表示前面的字符出现 0 次或多次
• () 表示捕获分组,把匹配到的内容“抓出来”,可以在后面引用
所以 (.*) 的意思是:匹配任意长度的任意字符,并把它捕获下来。
2. annotations
结合annotations一起看
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
...
path: /rayjob-sample-raycluster-b5x8f/(.*)
工作流程:
1. 用户访问:http://118.196.47.109/rayjob-sample-raycluster-b5x8f/api/jobs
2. nginx 用正则 /rayjob-sample-raycluster-b5x8f/(.*) 去匹配路径
3. (.*) 捕获到的内容是:api/jobs → 这就是 $1
4. rewrite-target: /$1 告诉 nginx 把请求重写成 /api/jobs
5. 最后转发给后端 Service(Ray dashboard)的就是 /api/jobs
3. 为什么$1就是api/jobs呢

示例 - ingress2
代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
k8s.apisix.apache.org/rewrite-target-regex: /[^/]+/(.*)
k8s.apisix.apache.org/rewrite-target-regex-template: /$1
generation: 1
labels:
app.kubernetes.io/created-by: kuberay-operator
app.kubernetes.io/name: kuberay
ray.io/cluster: rayjob-sample-ingress-3-pzkcp
ray.io/identifier: rayjob-sample-ingress-3-pzkcp-head
name: rayjob-sample-ingress-3-pzkcp-head-ingress
namespace: ray-test
ownerReferences:
- apiVersion: ray.io/v1
blockOwnerDeletion: true
controller: true
kind: RayCluster
name: rayjob-sample-ingress-3-pzkcp
uid: 1af0cafb-d409-491c-90b6-928aabb07a2d
resourceVersion: "221515669"
uid: dce80917-8116-438b-9e88-8a8b4317699f
spec:
ingressClassName: apisix
rules:
- http:
paths:
- backend:
service:
name: rayjob-sample-ingress-3-pzkcp-head-svc
port:
number: 8265
path: /rayjob-sample-ingress-3-pzkcp/(.*)
pathType: Exact
status:
loadBalancer:
ingress:
- ip: 10.117.16.218
解释
1. [^/]
区分:[] 和 ()
• [] 字符集 —— 限定一个字符能是什么("允许的字符列表")
[] 在管"一个字符"
• [abc] = 一个字符,是 a、b、c 中的任一个
• [0-9] = 一个字符,是 0~9 中的任一个数字
• [^/] = 一个字符,只要不是 / 就行(^ 在 [] 开头表示"取反")
注意:[] 默认只匹配 1 个字符。要匹配多个,得在后面加量词 +、*、{n}:
• [^/] → 1 个非 / 字符(比如 r)
• [^/]+ → ≥1 个非 / 字符(比如 rayjob-sample-ingress-3-pzkcp)
所以我的正则里的 [^/]+ 正好可以吞掉 rayjob-sample-ingress-3-pzkcp 这整段,直到遇到下一个 / 才停。
• () 捕获组 —— 把一段匹配结果打包,方便用 $1 引用
() 在管"打包 + 捕获"
() 本身不限制能匹配什么字符,它只是"画个圈",把圈里匹配到的内容存起来,给后面 $1、$2 用。
• (.*) → 把"任意字符任意多个"这一整段打包成 $1
• 在我的例子里,圈住的是 api/jobs,所以 $1 = "api/jobs"
结合我的正则来看:

最后小测:
如果把你的正则改成:
/([^/]+)/(.*)
那匹配 /rayjob-sample-ingress-3-pzkcp/api/jobs 时:
• $1 = "rayjob-sample-ingress-3-pzkcp"
• $2 = "api/jobs"
这就是 [] 和 () 同时用上的效果——[] 决定每个字符能是什么,() 决定哪一段要被拎出来用。
2. annotation配合使用
APISIX 拿到原始 URI 后,再用 rewrite-target-regex 重新跑一次正则:

再代入 k8s.apisix.apache.org/rewrite-target-regex-template: /$1
把 $1 替换成 api/jobs,最终 /api/jobs 转发给后端 Service 的路径
更多推荐
所有评论(0)