通常会重写目标如下:
nginx.ingress.kubernetes.io/rewrite-target: /
这将重写您服务名称的目标,因为它们在根目录中。因此,如果我有这个:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: demo-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
rules:
http:
paths:
- path: /
backend:
serviceName: front-main
servicePort: 80
- path: /api
backend:
serviceName: back-main
servicePort: 80
我的服务将像/
一样接收数据。但是,我希望我的服务front-main
发送根/
和服务器back-main
发送/someotherpath/
。我该怎么做?
是否有以下行?
nginx.ingress.kubernetes.io/rewrite-target: "front-main: / ; back-main: /someotherpath"
我似乎没有在文档中找到答案。
不幸的是,基于免费版本的nginx没有该功能。
,但是,如果您可以使用基于Nginx Plus的入口,则可以通过注释进行。
这是官方仓库的一个示例:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: cafe-ingress
annotations:
nginx.org/rewrites: "serviceName=tea-svc rewrite=/;serviceName=coffee-svc rewrite=/beans/"
spec:
rules:
- host: cafe.example.com
http:
paths:
- path: /tea/
backend:
serviceName: tea-svc
servicePort: 80
- path: /coffee/
backend:
serviceName: coffee-svc
servicePort: 80
以下是如何重写tea-svc
请求的URI的示例(请注意,/TEA请求被重定向到/tea/(.
/tea/ -> /
/tea/abc -> /abc
以下是如何重写coffee-svc
请求的URI的示例(请注意,/咖啡请求被重定向到/beans/(.
/coffee/ -> /beans/
/coffee/abc -> /beans/abc
另一个解决方案是创建两个Ingress yaml文件
每个使用不同的注释。它有效!
重写注释的新语法允许您使用捕获组定义rewrite-target
,可以在某些情况下使用来实现您所处的位置for。
例如,如果您想要一种服务将匹配的URL 保留在其重写中,但是不是其他,则可以使用以下方式使用匹配组:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-ingress
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$1$2 # Here we concatenate the two matched groups
spec:
rules:
- http:
paths:
- path: /front()(.*) # Here the first matching group is always empty
pathType: Prefix
backend:
service:
name: front-main
port:
number: 80
- path: /(back)(.*) # Here the first matching group matches 'back'
pathType: Prefix
backend:
service:
name: back-main
port:
number: 80
因此,/back/foo
将重定向到/back/foo
上的back-service
,但是/front/foo
仅将front-service
重定向到/foo
。
据我所知,这不能用于您要求的更一般情况,例如将/back/foo
重写为/some-completely-different-path
。
使它起作用是巨大的痛苦,但是您可以。
诀窍是:
"nginx.ingress.kubernetes.io/configuration-snippet" = "if ($request_uri !~* ^/(api|assets)) { rewrite ^/.*$ / break; }"
假设您正在使用前端路由,并且所有资产都在/资产中。
这是我使用Terraform进行设置的方式:
resource "kubernetes_ingress_v1" "main-ingress" {
metadata {
name = "main-ingress"
annotations = {
"kubernetes.io/ingress.class" = "nginx"
"certmanager.k8s.io/issuer" = module.infra.cert_issuer_name
"certmanager.k8s.io/acme-challenge-type" = "dns01"
"certmanager.k8s.io/acme-dns01-provider" = "digitalocean"
"kubernetes.io/ingress.allow-http" = false
"kubernetes.io/tls-acme" = true
"nginx.ingress.kubernetes.io/configuration-snippet" = "if ($request_uri !~* ^/(api|assets)) { rewrite ^/.*$ / break; }"
}
}
spec {
tls {
hosts = [local.prod_hostname]
// Needs to be different than "local.certIssuerSecretName"
secret_name = "main-ingress-auth-tls"
}
rule {
host = local.prod_hostname
http {
path {
path = "/api"
path_type = "Prefix"
backend {
service {
name = module.prod.be_service_name
port {
number = local.be_app_port
}
}
}
}
path {
path = "/"
path_type = "Prefix"
backend {
service {
name = module.prod.fe_service_name
port {
number = local.fe_app_port
}
}
}
}
}
}
}
}
我正在使用:
resource "helm_release" "nginx-ingress" {
depends_on = [ kubernetes_manifest.install-cert-manager-issuer ]
name = "nginx"
version = "4.5.2"
chart = "ingress-nginx"
repository = var.nginx_helm_stable_repo
timeout = 10 * 60
# timeout for each k8s action - 10 minutes
set {
name = "controller.publishService.enabled"
value = "true"
}
}