一、404(Not Found)报错

404表示访问的路由不存在,通常问题如下:

  • 1) Ingress 路径配置的不正确
  • 2) Ingress 的配置未被Controller 解析
  • 3) 未使用正确的域名和路径访问
  • 4) 代理的服务没有该路径

场景分析:有一个项目包含一个前端,两个后端, 域名为 project.test.com。

其中路径走向为:

  • 路径 / 指向 前端
  • 路径 /userapi 指向 user 服务
  • 路径 /paymentapi 指向 payment 服务

正常部署服务

1、部署服务

# 部署第一个服务
kubectl create deploy user --image=registry.cn-hangzhou.aliyuncs.com/abroad_images/ingress-err:v1  -n study-ingress

# 部署第二个服务
kubectl create deploy payment --image=registry.cn-hangzhou.aliyuncs.com/abroad_images/ingress-err:v1  -n study-ingress

2、配置Service

# 暴露第一个服务
kubectl expose deploy user --port 8080 -n study-ingress

# 暴露第二个服务
kubectl expose deploy payment --port 8080 -n study-ingress

3、配置 Ingress

[root@k8s-master01 ~]# vim user-payment-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: user-payment
  namespace: study-ingress
spec:
  ingressClassName: nginx # for k8s >= 1.22+
  rules:
  - host: project.test.com
    http:
      paths:
      - backend:
          service:
            name: user
            port:
              number: 8080
        path: /user
        pathType: Prefix
      - backend:
          service:
            name: payment
            port:
              number: 8080
        path: /payment
        pathType: Prefix

4、添加域名解析

[root@k8s-master01 ~]# echo "10.0.0.22 project.test.com" >> /etc/hosts

5、创建ingress并测试,观察到此时访问没有任何问题的,但是有可能程序提供的接口/api 或者/user,但是要求的接口并 不是/api 和/user, 比如要求的是 userapi 和 paymentapi,此时直接配置会报 404。

[root@k8s-master01 ~]# kaf user-payment-ingress.yaml

# 指定POST格式进行测试
[root@k8s-master01 day012]# curl -X POST project.test.com/user
{"msg":"登录成功","用户名":"匿名用户"}

# 进行测试
[root@k8s-master01 day012]# curl project.test.com/payment
{"msg":"支付服务","商品名称":"未知商品"}

模拟404场景

1、假设要求的接口路径是/userapi和/paymentapi,重新定义ingress文件

[root@k8s-master01 ~]# vim user-payment-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: user-payment
  namespace: study-ingress
spec:
  ingressClassName: nginx # for k8s >= 1.22+
  rules:
  - host: project.test.com
    http:
      paths:
      - backend:
          service:
            name: user
            port:
              number: 8080
        path: /userapi
        pathType: Prefix
      - backend:
          service:
            name: payment
            port:
              number: 8080
        path: /paymentapi
        pathType: Prefix

2、重新定义ingress

[root@k8s-master01 ~]# kaf user-payment-ingress.yaml

3、重新测试访问,观察到返回404,这里虽然Ingress配置路径为/paymentapi,但是后端的服务并没有/paymentapi这个路径,所以会导致404

[root@k8s-master01 day012]# curl project.test.com/payment -I
HTTP/1.1 404 Not Found
Date: Wed, 19 Mar 2025 10:56:33 GMT
Content-Type: */*
Content-Length: 60
Connection: keep-alive

4、使用 rewrite 进行地址重写把 paymentapi 去除,这样/paymentapi/payment 就被代理到了程序的/payment

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

5、更新ingress后,重新测试访问

[root@k8s-master01 ~]# kaf user-payment-ingress.yaml

[root@k8s-master01 ~]# curl project.test.com/paymentapi/payment
{"msg":"支付服务","商品名称":"未知商品"}

二、413(Request Entity Too Large)报错

有时候需要上传一些大文件给程序, 但是 nginx 默认允许的上传的最大文件大小只有 8M,不足以 满足生产最大上传需求,此时可以通过 nginx.ingress.kubernetes.io/proxy-body-size 参数进行更改(也可以在 ConfigMap 中全局添加)

环境准备

1、创建Namespace

kubectl create ns study-ingress

2、创建一个 Nginx 模拟 Web 服务

k create deploy nginx --image=registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2 -n study-ingress

3、创建service

kubectl expose deploy nginx --port 80 -n study-ingress

添加proxy-body-size 参数

1、创建ingress

[root@k8s-master01 ~]# vim ingress-413.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: 50m
  name: nginx-ingress
  namespace: study-ingress
spec:
  ingressClassName: nginx # for k8s >= 1.22+
  rules:
  - host: nginx.test.com
    http:
      paths:
      - backend:
          service:
            name: nginx
            port:
              number: 80
        path: /
        pathType: ImplementationSpecific

[root@k8s-master01 ~]# kaf ingress-413.yaml

2、验证配置是否添加,观察到配置已经成功添加

[root@k8s-master01 day012]# k exec -it ingress-nginx-controller-2rvw6 -n ingress-nginx -- bash
k8s-node02:/etc/nginx$ cat nginx.conf | grep 50m
            client_max_body_size                    50m;

3、环境复原

[root@k8s-master01 ~]# k delete -f ingress-413.yaml

三、503(Service Unavailable)报错

503 一般是代理的服务不可用导致的,通常问题如下:

  • 1)Ingress 代理配置错误, 比如 Service 名字或端口写错
  • 2)Ingress 代理的 Service 不存在
  • 3)Ingress 代理的 Service 后端 Pod 不正常

正常部署服务

1、部署服务

# 部署第一个服务
kubectl create deploy user --image=registry.cn-hangzhou.aliyuncs.com/abroad_images/ingress-err:v1  -n study-ingress

# 部署第二个服务
kubectl create deploy payment --image=registry.cn-hangzhou.aliyuncs.com/abroad_images/ingress-err:v1  -n study-ingress

2、配置Service

# 暴露第一个服务
kubectl expose deploy user --port 8080 -n study-ingress

# 暴露第二个服务
kubectl expose deploy payment --port 8080 -n study-ingress

3、配置 Ingress

[root@k8s-master01 ~]# vim user-payment-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: user-payment
  namespace: study-ingress
spec:
  ingressClassName: nginx # for k8s >= 1.22+
  rules:
  - host: project.test.com
    http:
      paths:
      - backend:
          service:
            name: user
            port:
              number: 8080
        path: /user
        pathType: Prefix
      - backend:
          service:
            name: payment
            port:
              number: 8080
        path: /payment
        pathType: Prefix

4、添加域名解析

[root@k8s-master01 ~]# echo "10.0.0.22 project.test.com" >> /etc/hosts

5、创建ingress并测试,观察到此时访问没有任何问题的,但是有可能程序提供的接口/api 或者/user,但是要求的接口并 不是/api 和/user, 比如要求的是 userapi 和 paymentapi,此时直接配置会报 404。

[root@k8s-master01 ~]# kaf user-payment-ingress.yaml

# 指定POST格式进行测试
[root@k8s-master01 day012]# curl -X POST project.test.com/user
{"msg":"登录成功","用户名":"匿名用户"}

# 进行测试
[root@k8s-master01 day012]# curl project.test.com/payment
{"msg":"支付服务","商品名称":"未知商品"}

模拟503场景

Ingress 代理的 Service 不存在

1、假设这块Service写错,重新定义ingress文件

[root@k8s-master01 ~]# vim user-payment-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: user-payment
  namespace: study-ingress
spec:
  ingressClassName: nginx # for k8s >= 1.22+
  rules:
  - host: project.test.com
    http:
      paths:
      - backend:
          service:
            name: user
            port:
              number: 8080
        path: /user
        pathType: Prefix
      - backend:
          service:
            name: paymentxxx
            port:
              number: 8080
        path: /payment
        pathType: Prefix

2、重新定义ingress

[root@k8s-master01 ~]# kaf user-payment-ingress.yaml

3、重新测试访问,观察到返回404,这里虽然Ingress配置路径为/paymentapi,但是后端的服务并没有/paymentapi这个路径,所以会导致404

[root@k8s-master01 day012]# curl project.test.com/payment -I
HTTP/1.1 503 Service Unavailable
Date: Wed, 19 Mar 2025 13:35:28 GMT
Content-Type: */*
Content-Length: 8
Connection: keep-alive

4、环境复原

[root@k8s-master01 ~]# k delete -f  user-payment-ingress.yaml

Ingress 代理的 Service 后端 Pod 不正常

1、假设Ingress这块部署在default命名空间下,但是相关服务在study-ingress命名空间,重新定义ingress文件

[root@k8s-master01 ~]# vim user-payment-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: user-payment
spec:
  ingressClassName: nginx # for k8s >= 1.22+
  rules:
  - host: project.test.com
    http:
      paths:
      - backend:
          service:
            name: user
            port:
              number: 8080
        path: /user
        pathType: Prefix
      - backend:
          service:
            name: payment
            port:
              number: 8080
        path: /payment
        pathType: Prefix

2、重新定义ingress

[root@k8s-master01 ~]# kaf user-payment-ingress.yaml

3、重新测试访问,观察到返回404,这里虽然Ingress配置路径为/paymentapi,但是后端的服务并没有/paymentapi这个路径,所以会导致404

[root@k8s-master01 day012]# curl project.test.com/payment -I
HTTP/1.1 503 Service Unavailable
Date: Wed, 19 Mar 2025 13:35:28 GMT
Content-Type: */*
Content-Length: 8
Connection: keep-alive

4、环境复原

[root@k8s-master01 ~]# k delete -f  user-payment-ingress.yaml

四、504(Gateway Timeout)报错

504 一般是代理的服务处理请求的时间过长,导致 Nginx 等待超时,此时需要确认服务的处理时长, 或者查看服务是否有问题。

1、部署后端程序模拟报错

创建deploy

kubectl create deploy ingress-err --image=registry.cn-hangzhou.aliyuncs.com/abroad_images/ingress-err:v1  -n study-ingress

暴露服务

kubectl expose deploy ingress-err --port 8080 -n study-ingress

2、手动请求接口,观察到返回时间比较长

# 查看svc地址
[root@k8s-master01 day012]# kg svc -n study-ingress | grep ingress-err
ingress-err   ClusterIP   10.108.119.235   <none>        8080/TCP   103s

# 手动请求接口
curl 10.108.119.235:8080/longtime
{"msg":"任务处理成功","处理时间":53}

3、配置Ingress

[root@k8s-master01 ~]# vim longtime.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: longtime
  namespace: study-ingress
spec:
  ingressClassName: nginx # for k8s >= 1.22+
  rules:
  - host: longtime.test.com
    http:
      paths:
      - backend:
          service:
            name: ingress-err
            port:
              number: 8080
        path: /
        pathType: Prefix

# 创建ingress
[root@k8s-master01 ~]# kaf longtime.yaml

4、通过域名测试访问

[root@k8s-master01 ~]# echo "10.0.0.22 longtime.test.com" >> /etc/hosts

[root@k8s-master01 ~]# curl http://longtime.test.com/longtime
{"msg":"任务处理成功","处理时间":50}

5、配置合适的超时时间

[root@k8s-master01 ~]# vim longtime.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "120"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "120"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "120"
  name: longtime
  namespace: study-ingress
spec:
  ingressClassName: nginx # for k8s >= 1.22+
  rules:
  - host: longtime.test.com
    http:
      paths:
      - backend:
          service:
            name: ingress-err
            port:
              number: 8080
        path: /
        pathType: Prefix

# 创建ingress
[root@k8s-master01 ~]# kaf longtime.yaml

关于超时时间配置的参数说明:

  • nginx.ingress.kubernetes.io/proxy-connect-timeout:设置 Nginx与后端服务建立 TCP 连接 的最大允许时间(单位:秒),默认时间为60s
  • nginx.ingress.kubernetes.io/proxy-send-timeout:设置 Nginx向后端服务发送请求数据的超时时间(单位:秒),默认时间为60s
  • nginx.ingress.kubernetes.io/proxy-read-timeout:设置 Nginx从后端服务读取响应数据的超时时间(单位:秒),默认时间为60s

6、通过域名再次测试访问

[root@k8s-master01 ~]# curl http://longtime.test.com/longtime
{"msg":"任务处理成功","处理时间":50}

五、CORS 跨域报错

如果浏览器中存在如下报错,说明被跨域给拦截了,可以添加跨域配置。

image-20250319222450337

1、部署后端程序模拟报错

创建deploy

kubectl create deploy ingress-err --image=registry.cn-hangzhou.aliyuncs.com/abroad_images/ingress-err:v1  -n study-ingress

暴露服务

kubectl expose deploy ingress-err --port 8080 -n study-ingress

2、配置Ingress,其中添加允许跨域

[root@k8s-master01 ~]# vim longtime.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    # 启用 CORS
    nginx.ingress.kubernetes.io/enable-cors: "true"
    # 允许的 HTTP 方法
    nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS, DELETE"
    # 允许的请求头
    nginx.ingress.kubernetes.io/cors-allow-headers: "X-Forwarded-For, X-App123-XPTO, Content-Type, Authorization"
    # 限制允许的来源域名
    nginx.ingress.kubernetes.io/cors-allow-origin: "*"
  name: longtime
  namespace: study-ingress
spec:
  ingressClassName: nginx # for k8s >= 1.22+
  rules:
  - host: longtime.test.com
    http:
      paths:
      - backend:
          service:
            name: ingress-err
            port:
              number: 8080
        path: /
        pathType: Prefix

# 创建ingress
[root@k8s-master01 ~]# kaf longtime.yaml

3、在win主机上修改hosts文件,文件路径为:C:\Windows\System32\drivers\etc\hosts

10.0.0.20 longtime.test.com

4、打开浏览器,输入http://longtime.test.com/longtime进行访问,观察到在响应头信息可以看到之前的配置信息

image-20250319223550420

六、环境清理

清理命名空间和命名空间下的所有资源

kubectl delete ns study-ingress
kubectl delete ns production canary

4、