如何在 kubernetes 上的 nginx 控制器中将 URL 重写为小写
How to rewrite URLs to lowercase in nginx controller on kubernetes
我有一个要求将所有 URL 重写为小写。
例如test.com/CHILD
至 test.com/child
前端应用程序是在 docker Azure kubernetes 服务上开发的。入口由 nginx 入口控制器控制。
入口控制器在 spec.rules.http.paths.path
字段中支持 不区分大小写 正则表达式。这可以通过将 nginx.ingress.kubernetes.io/use-regex
注释设置为 true(默认为 false)来启用。有关更多信息,请查看 here
使用 nginx.ingress.kubernetes.io/use-regex
注释将指示 Ingress 上定义的路径是否使用正则表达式。默认值为 false。
以下将表明正在使用正则表达式路径:
nginx.ingress.kubernetes.io/use-regex: "true"
以下将指示未使用正则表达式路径:
nginx.ingress.kubernetes.io/use-regex: "false"
当此注释设置为 true
时,不区分大小写的正则表达式 location modifier 将在给定主机的所有路径上强制执行,无论它们是在哪个 Ingress 上定义的。
您可以使用 Lua 重写 URL,如 Enforce Lower Case URLs (NGINX) 文章中所述。
我们需要做的就是在nginx中添加如下配置块:
location ~ [A-Z] {
rewrite_by_lua_block {
ngx.redirect(string.lower(ngx.var.uri), 301);
}
}
我会告诉你它是如何工作的。
首先,我使用前面提到的配置创建了一个 Ingress 资源:
$ cat test-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/server-snippet: |
location ~ [A-Z] {
rewrite_by_lua_block {
ngx.redirect(string.lower(ngx.var.uri), 301);
}
}
spec:
rules:
- http:
paths:
- path: /app-1
pathType: Prefix
backend:
service:
name: app-1
port:
number: 80
$ kubectl apply -f test-ingress.yaml
ingress.networking.k8s.io/test-ingress created
$ kubectl get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
test-ingress <none> * <PUBLIC_IP> 80 58s
然后我创建了一个示例 app-1
Pod 并将其暴露在端口 80
:
$ kubectl run app-1 --image=nginx
pod/app-1 created
$ kubectl expose pod app-1 --port=80
service/app-1 exposed
最后,我们可以测试重写是否按预期工作:
$ curl -I <PUBLIC_IP>/APP-1
HTTP/1.1 301 Moved Permanently
Date: Wed, 06 Oct 2021 13:53:56 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: /app-1
$ curl -L <PUBLIC_IP>/APP-1
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
此外,在 ingress-nginx-controller
日志中,我们可以看到以下日志条目:
10.128.15.213 - - [06/Oct/2021:13:54:34 +0000] "GET /APP-1 HTTP/1.1" 301 162 "-" "curl/7.64.0" 83 0.000 [-] [] - - - - c4720e38c06137424f7b951e06c3762b
10.128.15.213 - - [06/Oct/2021:13:54:34 +0000] "GET /app-1 HTTP/1.1" 200 615 "-" "curl/7.64.0" 83 0.001 [default-app-1-80] [] 10.4.1.13:80 615 0.001 200 f96b5664765035de8832abebefcabccf
解决方案的想法是好的,但这会重写这个控制器的所有 url,而不仅仅是这个入口的 url。将它放入 configuration-snippet 也是不可能的,因为这会导致重复 rewrite_by_lua_block。
我将规则放入不同的 lua 块
nginx.ingress.kubernetes.io/configuration-snippet: |
access_by_lua_block {
if string.match(ngx.var.uri, "[A-Z]") then
ngx.redirect(string.lower(ngx.var.uri), 301);
end
}
我有一个要求将所有 URL 重写为小写。
例如test.com/CHILD
至 test.com/child
前端应用程序是在 docker Azure kubernetes 服务上开发的。入口由 nginx 入口控制器控制。
入口控制器在 spec.rules.http.paths.path
字段中支持 不区分大小写 正则表达式。这可以通过将 nginx.ingress.kubernetes.io/use-regex
注释设置为 true(默认为 false)来启用。有关更多信息,请查看 here
使用 nginx.ingress.kubernetes.io/use-regex
注释将指示 Ingress 上定义的路径是否使用正则表达式。默认值为 false。
以下将表明正在使用正则表达式路径:
nginx.ingress.kubernetes.io/use-regex: "true"
以下将指示未使用正则表达式路径:
nginx.ingress.kubernetes.io/use-regex: "false"
当此注释设置为 true
时,不区分大小写的正则表达式 location modifier 将在给定主机的所有路径上强制执行,无论它们是在哪个 Ingress 上定义的。
您可以使用 Lua 重写 URL,如 Enforce Lower Case URLs (NGINX) 文章中所述。
我们需要做的就是在nginx中添加如下配置块:
location ~ [A-Z] {
rewrite_by_lua_block {
ngx.redirect(string.lower(ngx.var.uri), 301);
}
}
我会告诉你它是如何工作的。
首先,我使用前面提到的配置创建了一个 Ingress 资源:
$ cat test-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/server-snippet: |
location ~ [A-Z] {
rewrite_by_lua_block {
ngx.redirect(string.lower(ngx.var.uri), 301);
}
}
spec:
rules:
- http:
paths:
- path: /app-1
pathType: Prefix
backend:
service:
name: app-1
port:
number: 80
$ kubectl apply -f test-ingress.yaml
ingress.networking.k8s.io/test-ingress created
$ kubectl get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
test-ingress <none> * <PUBLIC_IP> 80 58s
然后我创建了一个示例 app-1
Pod 并将其暴露在端口 80
:
$ kubectl run app-1 --image=nginx
pod/app-1 created
$ kubectl expose pod app-1 --port=80
service/app-1 exposed
最后,我们可以测试重写是否按预期工作:
$ curl -I <PUBLIC_IP>/APP-1
HTTP/1.1 301 Moved Permanently
Date: Wed, 06 Oct 2021 13:53:56 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: /app-1
$ curl -L <PUBLIC_IP>/APP-1
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
此外,在 ingress-nginx-controller
日志中,我们可以看到以下日志条目:
10.128.15.213 - - [06/Oct/2021:13:54:34 +0000] "GET /APP-1 HTTP/1.1" 301 162 "-" "curl/7.64.0" 83 0.000 [-] [] - - - - c4720e38c06137424f7b951e06c3762b
10.128.15.213 - - [06/Oct/2021:13:54:34 +0000] "GET /app-1 HTTP/1.1" 200 615 "-" "curl/7.64.0" 83 0.001 [default-app-1-80] [] 10.4.1.13:80 615 0.001 200 f96b5664765035de8832abebefcabccf
解决方案的想法是好的,但这会重写这个控制器的所有 url,而不仅仅是这个入口的 url。将它放入 configuration-snippet 也是不可能的,因为这会导致重复 rewrite_by_lua_block。 我将规则放入不同的 lua 块
nginx.ingress.kubernetes.io/configuration-snippet: |
access_by_lua_block {
if string.match(ngx.var.uri, "[A-Z]") then
ngx.redirect(string.lower(ngx.var.uri), 301);
end
}