在某些情况下,后端服务中的公开URI与Ingress规则中的指定路径不同。如果没有rewrite,任何请求都将返回404,可以将Ingress里annotations设置nginx.ingress.kubernetes.io/rewrite-target为服务所需的路径。

通过annotations做rewrite基本配置:

以下操作在k8s 1.13.2版本;ingress-nginx控制器0.24.1版本上进行。

 

示例一

  •  
apiVersion: extensions/v1beta1kind: Ingressmetadata:  annotations:    nginx.ingress.kubernetes.io/rewrite-target: https://www.jianshu.com/u/33c582f040ae  name: nginx-ingress-1  namespace: defaultspec:  rules:  - host: bb.test.com    http:      paths:      - backend:          serviceName: nginx-svc          servicePort: 8080        path: /aaa

当访问http://bb.test.com:8088/aaa时,会被重定向到简书主页https://www.jianshu.com/u/33c582f040ae,如果有多个path,每个都会被rewrite,所以如果只需要替换单个path(也就是location)的时候单独使用一个ingress写。

 

这里没有配置kubernetes.io/ingress.class将会使用启动参数中没有加--ingress-class的ingress-nginx(同一k8s集群中可能会有多个负载ingress-nginx,这个启动参数用于标识标记了kubernetes.io/ingress.class的ingress将会被哪个ingress-nginx处理)

 

k8s负载均衡器配置请求重定向_k8s


 

创建该ingress后,可以在ingress-nginx容器内nginx.conf中看到,location中多了rewrite配置

  •  
server {    server_name bb.test.com ;        listen 80;        set $proxy_upstream_name "-";    set $pass_access_scheme $scheme;    set $pass_server_port $server_port;    set $best_http_host $http_host;    set $pass_port $pass_server_port;        location ~* "^/aaa" {            set $namespace      "default";      set $ingress_name   "nginx-ingress-1";      set $service_name   "nginx-svc";      set $service_port   "80";      set $location_path  "/aaa";            rewrite_by_lua_block {        lua_ingress.rewrite({          force_ssl_redirect = false,          use_port_in_redirects = false,        })        balancer.rewrite()        plugins.run()      }                        ##此处省略            rewrite "(?i)/aaa" https://www.jianshu.com/u/33c582f040ae break;      proxy_pass http://upstream_balancer;            proxy_redirect                          off;          }        location ~* "^/" {            set $namespace      "";      set $ingress_name   "";      set $service_name   "";      set $service_port   "0";      set $location_path  "/";            rewrite_by_lua_block {        lua_ingress.rewrite({          force_ssl_redirect = false,          use_port_in_redirects = false,        })        balancer.rewrite()        plugins.run()      }            header_filter_by_lua_block {                plugins.run()      }      body_filter_by_lua_block {              }            log_by_lua_block {                balancer.log()                monitor.call()                plugins.run()      }                  ##此处省略            rewrite "(?i)/" https://www.jianshu.com/u/33c582f040ae break;      proxy_pass http://upstream_balancer;            proxy_redirect                          off;          }      }

 

访问

配置hosts文件:

192.168.1.103为负载均衡器IP;bb.test.com为上面ingress中配置的host

 

k8s负载均衡器配置请求重定向_k8s_02

以上软件为switchhost(方便管理,灵活切换hosts的一款开源软件)

 

当访问http://bb.test.com:8088/aaa时,会被重定向到简书主页:

其中8088为ingress-nginx的http端口(hostPort方式暴露)

k8s负载均衡器配置请求重定向_k8s_03

 

 

 

示例二

 

从版本0.22.0开始,使用注释的入口定义nginx.ingress.kubernetes.io/rewrite-target不向后兼容以前的版本。在版本0.22.0及更高版本中,必须在捕获组中

(https://www.regular-expressions.info/refcapture.html)

明确定义需要传递到重写路径的请求URI中的任何子字符串。

 

捕获组保存在编号占位符,按时间顺序,形式$1,$2... $n。这些占位符可用作rewrite-target注释中的参数。

 

创建以下ingress:

  •  
$ echo 'apiVersion: extensions/v1beta1kind: Ingressmetadata:  annotations:    nginx.ingress.kubernetes.io/rewrite-target: /$2  name: rewrite  namespace: defaultspec:  rules:  - host: rewrite.bar.com    http:      paths:      - backend:          serviceName: http-svc          servicePort: 80        path: /something(/|$)(.*)' | kubectl create -f -

在此入口定义中,(.*)将捕获的任何字符都将分配给占位符$2,然后将其用作rewrite-target注释中的参数。

生成的nginx.conf内容如下:

  •  
server {    server_name rewrite.bar.com ;        listen 80;        set $proxy_upstream_name "-";    set $pass_access_scheme $scheme;    set $pass_server_port $server_port;    set $best_http_host $http_host;    set $pass_port $pass_server_port;        location ~* "^/something(/|$)(.*)" {            set $namespace      "default";      set $ingress_name   "rewrite";      set $service_name   "http-svc";      set $service_port   "80";      set $location_path  "/something(/|${literal_dollar})(.*)";            rewrite_by_lua_block {        lua_ingress.rewrite({          force_ssl_redirect = false,          use_port_in_redirects = false,        })        balancer.rewrite()        plugins.run()      }            header_filter_by_lua_block {                plugins.run()      }      body_filter_by_lua_block {              }            log_by_lua_block {                balancer.log()                monitor.call()                plugins.run()      }      ## 此处省略            rewrite "(?i)/something(/|$)(.*)" /$2 break;      proxy_pass http://upstream_balancer;            proxy_redirect                          off;          }        location ~* "^/" {            set $namespace      "";      set $ingress_name   "";      set $service_name   "";      set $service_port   "0";      set $location_path  "/";            rewrite_by_lua_block {        lua_ingress.rewrite({          force_ssl_redirect = false,          use_port_in_redirects = false,        })        balancer.rewrite()        plugins.run()      }            header_filter_by_lua_block {                plugins.run()      }      body_filter_by_lua_block {              }            log_by_lua_block {                balancer.log()                monitor.call()                plugins.run()      }                  ## 此处省略            rewrite "(?i)/" /$2 break;      proxy_pass http://upstream_balancer;            proxy_redirect                          off;          }      }

上面的ingress定义结果将会是如下结果:

- rewrite.bar.com/something重写为rewrite.bar.com/ 

- rewrite.bar.com/something/重写为rewrite.bar.com/ 

- rewrite.bar.com/something/new重写为rewrite.bar.com/new

 

k8s负载均衡器配置请求重定向_k8s_04