Rewrite官网说明

现在大部分应用都是前后端分离的架构,也就是前端用某个域名的根路径进行访问,后端接口采用/api进行访问,用来区分前端和后端。或者同时具有很多个后端,需要使用/api-a到A服务,/api-b到B服务,但是由于A和B服务可能并没有/api-a和/api-b的路径,会出现404的报错。

Ingress Nginx前后端分离Rewrite-错误访问

此时需要将/api-x重写为“/”,才可以正常到A或者B服务

Ingress Nginx前后端分离Rewrite-重定向访问

下面通过Rewrite功能达到上述效果

1.创建一个应用模拟后端服务:

[root@k8s-master01 ~]#  kubectl create deploy backend-api --image=registry.cn-hangzhou.aliyuncs.com/abroad_images/nginx:backend-api -n study-ingress

2.查看后端服务是否启动

[root@k8s-master01 ~]# kubectl get po -n study-ingress

3.创建Service暴露该应用:

[root@k8s-master01 ~]# kubectl expose deploy backend-api --port 80 -n study-ingress

4.查看该 Service 的地址,并且通过/api-a 访问测试,发现访问失败

[root@k8s-master01 ~]# kubectl get svc -n study-ingress
NAME          TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
backend-api   ClusterIP   10.0.1.207    <none>        80/TCP    7s
nginx         ClusterIP   10.0.33.180   <none>        80/TCP    159m

[root@k8s-master01 ~]# curl 10.0.1.207/api-a
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.15.12</center>
</body>
</html>

5.测试直接访问根路径,发现是可以的

[root@k8s-master01 ~]# curl 10.0.1.207
<h1> backend for ingress rewrite </h1>

<h2> Path: /api-a </h2>

<a href="http://gaoxin.kubeasy.com"> Kubeasy </a>

6.通过 Ingress Nginx 的 Rewrite 功能,将/api-a 重写为"/"

[root@k8s-master01 ~]# vim rewrite.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  name: backend-api
  namespace: study-ingress
spec:
  rules:
  - host: nginx.test.com
    http:
      paths:
      - backend:
          service:
            name: backend-api
            port:
              number: 80
        path: /api-a(/|$)(.*)
        pathType: ImplementationSpecific

上面参数说明:

(1)apiVersion: networking.k8s.io/v1: 指定使用的Kubernetes API版本,这里是Networking API的版本

(2)kind: Ingress: 表示这是一个Ingress资源对象

(3)metadata: 包含Ingress资源的元数据信息,包括名称和所属的命名空间。

  • annotations: 为Ingress资源添加注解,用于配置Ingress控制器的行为

  • nginx.ingress.kubernetes.io/rewrite-target: /$2: 这个注解指示nginx-ingress控制器对请求进行重写。具体来说,它将会重写请求路径为/$2。这里的$2是一个正则表达式中的反向引用,表示匹配到的第二个括号中的内容。

  • name: backend-api: Ingress资源的名称,这里命名为backend-api
  • namespace: study-ingress: Ingress资源所属的命名空间,这里是study-ingress

(4)spec: 指定了Ingress资源的规则和配置

(5)rules: 定义了Ingress资源的规则列表。每个规则指定了如何将请求路由到后端服务

  • - host: nginx.test.com: 这个规则适用于主机名为nginx.test.com的请求。
  • http:: 表示这个规则适用于HTTP流量。
  • paths:: 定义了路径规则列表,允许将特定路径的请求转发到后端Service
  • backend: 路径规则的后端定义。指定了后端Service的信息。
  • service:: 后端Service的名称为backend-api
  • port:: Service的端口号为80。
  • path: /api-a(/|$)(.*): 定义了将匹配的请求转发到后端Service的路径规则。这里的路径规则使用了正则表达式。/api-a: 匹配请求路径以/api-a开头;(/|$): 这是一个正则表达式,它匹配路径中的/或者空字符串(即路径结尾)。这样,请求可以匹配/api-a后直接以/结尾,也可以匹配/api-a/,甚至是/api-a/<任意路径>(.*): 这也是一个正则表达式,它匹配路径中的任意字符,这样可以捕获请求路径中/api-a之后的内容。
  • pathType: ImplementationSpecific: 定义了路径类型,表示Kubernetes根据实现来选择路径类型。在这里设置为ImplementationSpecific,由Ingress控制器特定的实现来决定路径类型

需要添加一个key为nginx.ingress.kubernetes.io/rewrite-target的annotation,并且value是$2,此时访问/api-a就会被重写为“/”,访问/api-a/xxx会被重写为/xxx。

7.创建该Ingress

[root@k8s-master01 ~]# kubectl create -f rewrite.yaml

8.在windows主机上修改hosts文件,文件路径为:C:\Windows\System32\drivers\etc\hosts

192.168.1.35 nginx.test.com

9.打开浏览器,输入nginx.test.com/api-a查看页面正常跳转,不会报404

Ingress Nginx前后端分离Rewrite

如果不生效,可能DNS解析未缓存。可参考以下步骤:

按Win键+R,打开cmd视图,执行ipconfig /flushdns命令进行刷新 DNS 解析缓存

C:\Users\ASUS>ipconfig /flushdns

Windows IP 配置

已成功刷新 DNS 解析缓存。