妈妈再也不用担心我业务上线啦~ Nginx与K8s Ingress运维常见问题

真成运维 2026-1-13 52 1/13

在项目/业务运维工作中,配置Nginx和K8s Ingress,可以说是常打交道的必备技能。Nginx作为经典的反向代理、负载均衡工具,K8S Ingress作为集群外部流量接入的核心组件,二者常搭配使用。

在实际工作场景中,跨域、文件上传下载限制、IP访问控制、网速管控、连接超时等场景常常出现,可以说这是项目/业务运维必不可少的工作,同时如不配置会直接影响业务可用性。

本文将针对上述核心场景,梳理了Nginx与K8S Ingress的常见问题、原因及解决方案,同时提供Nginx和Ingress两种方式的常见配置,为你运维之路提供参考。

有帮助请点赞+收藏!文章有疑问的地方可以在评论区留言,我会在第一时间回你解答~

一、跨域问题

跨域问题源于浏览器“同源策略”,当客户端页面与后端服务的协议、域名、端口不一致时,浏览器会拦截请求,表现为浏览器控制台报“Access to XMLHttpRequest at ... from origin ... has been blocked by CORS policy”错误,如图。Nginx与Ingress可通过配置响应头解决跨域,无需修改后端服务代码。

妈妈再也不用担心我业务上线啦~ Nginx与K8s Ingress运维常见问题

意思是,源 http://machine-copy-dev.zcyw.cn 访问 http://iot-test.zcyw.com 域名时被浏览器拦截了,需要在iot-test.zcyw.com域名中配置跨域。

1. Nginx 跨域配置

核心思路:通过添加CORS相关响应头,允许指定源、方法、请求头访问,同时处理预检请求(OPTIONS请求,复杂跨域请求会先发送该请求验证权限)。

完整配置示例

location /api {
  # 允许的源(*表示允许所有源,生产环境建议指定具体域名,如https://example.com)
  add_header Access-Control-Allow-Origin *;
  # 允许的请求方法
  add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
  # 允许的请求头
  add_header Access-Control-Allow-Headers 'Content-Type, Authorization';
  # 允许携带Cookie(需同时将Origin设为具体域名,不可为*)
  add_header Access-Control-Allow-Credentials 'true';
  # 预检请求缓存时间(秒),减少OPTIONS请求次数
  add_header Access-Control-Max-Age 86400;

  # 处理预检请求,直接返回204
  if ($request_method = 'OPTIONS') {
    return 204;
  }

  proxy_pass http://backend-service;
}

常见问题排查

  • 响应头重复:若后端服务已返回CORS头,Nginx再添加会导致重复,需关闭后端CORS配置或在Nginx中用proxy_hide_header隐藏后端CORS头。
  • 带Credentials的跨域:Origin不可设为*,需指定具体域名,否则浏览器会拒绝接收响应。(这一点在下方Ingress配置nginx.ingress.kubernetes.io/cors-allow-origin: $http_origin时也有介绍)

2. K8S Ingress 跨域配置

解决方案:通过Ingress注解配置CORS响应头,主流注解支持全局或局部跨域,适配不同场景。

场景1:简单跨域(仅允许指定源、方法)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: cors-ingress
  annotations:
    # 允许的源(生产环境指定具体域名)
    nginx.ingress.kubernetes.io/cors-allow-origin: "*" # 运行所有域名
    # 允许的方法
    nginx.ingress.kubernetes.io/cors-allow-methods: "*" # 或写其他具体GET, POST, OPTIONS等代替
    # 允许的请求头
    nginx.ingress.kubernetes.io/cors-allow-headers: "Content-Type"
    # 启用跨域
    nginx.ingress.kubernetes.io/enable-cors: "true"
spec:
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80

场景2:复杂跨域(带Credentials、自定义请求头)

annotations:
  nginx.ingress.kubernetes.io/cors-allow-origin: "https://example.com" # 具体域名
  nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, OPTIONS"
  nginx.ingress.kubernetes.io/cors-allow-headers: "Content-Type, Authorization, X-Token"
  nginx.ingress.kubernetes.io/cors-allow-credentials: "true" # 允许携带Cookie
  nginx.ingress.kubernetes.io/cors-max-age: "86400" # 预检请求缓存时间
  nginx.ingress.kubernetes.io/enable-cors: "true"

常见问题排查:

  • 注解不生效:检查Ingress Controller版本,部分旧版本不支持CORS专属注解,需升级Controller或通过全局ConfigMap配置跨域头。
  • 预检请求失败:确保启用CORS注解,Ingress会自动处理OPTIONS请求,无需额外配置路由。

如果nginx.ingress.kubernetes.io/cors-allow-origin,不能使用*通配符,需要使用$http_origin

妈妈再也不用担心我业务上线啦~ Nginx与K8s Ingress运维常见问题
妈妈再也不用担心我业务上线啦~ Nginx与K8s Ingress运维常见问题

使用$http_origin之后跨域验证方式,需要给一个请求来源地址。

curl -D - -H "Origin: https://itlottery-mg-test.zcyw.cn" https://parktest.zcyw.cn/upload/
妈妈再也不用担心我业务上线啦~ Nginx与K8s Ingress运维常见问题

二、文件上传限制

文件上传场景中,最常见的问题是“上传大文件失败”,表现为请求被拦截、返回413 Request Entity Too Large错误,本质是默认配置对上传文件大小存在限制,且Nginx与Ingress的限制逻辑需联动适配。

1. Nginx 上传文件限制

问题成因:Nginx默认通过client_max_body_size参数限制客户端请求体大小(默认值通常为1M),当上传文件超过该值时,Nginx会直接拒绝请求,不会将请求转发至后端服务。此外,若后端服务(如Tomcat、Spring Boot、Gateway)自身也配置了文件大小限制,即使Nginx放行,后端仍可能拦截。

解决方案

  • 调整client_max_body_size参数:根据业务需求设置合理值,可在http、server、location层级配置(优先级:location > server > http)。例如允许100M文件上传:
location /upload {
  client_max_body_size 100m; # 允许上传文件最大100M
  proxy_pass http://backend;
}
  • 联动后端服务配置:确保后端服务的文件上传限制不小于Nginx配置值。例如Spring Boot需调整spring.servlet.multipart.max-file-sizespring.servlet.multipart.max-request-size参数。
  • 补充超时配置:大文件上传耗时较长,需同步调整上传相关超时参数,避免请求中途被断开(具体超时参数见下文“超时问题”部分)。

2. K8S Ingress 上传文件限制

问题成因:K8S Ingress(主流为Nginx Ingress Controller)本质是基于Nginx实现,默认继承了Nginx的client_max_body_size限制(默认1M)。同时,Ingress的配置优先级为:Ingress资源注解 > Ingress Controller全局ConfigMap > 默认配置,若未通过注解或全局配置覆盖默认值,会导致大文件上传失败。

解决方案

  • 通过Ingress注解局部配置:针对单个Ingress资源设置,仅作用于该Ingress路由的路径,示例:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: upload-ingress
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: "100m" # 允许100M文件上传
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /upload
        pathType: Prefix
        backend:
          service:
            name: upload-service
            port:
              number: 80
  • 通过ConfigMap全局配置:适用于集群内所有Ingress资源,修改Ingress Controller的全局配置文件,如下(配置后需重启Ingress Controller Pod使配置生效):
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
data:
  proxy-body-size: "100m" # 全局允许100M文件上传

注意事项:若Ingress路由中同时配置了client-max-body-size和后端服务限制,需确保三者(Ingress注解、全局ConfigMap、后端服务)取值一致,避免层级限制冲突。

一般绝大多数情况情况下,都通过Ingress的注解配置。

三、文件下载限制相关问题

文件下载场景的问题主要集中在“并发下载数过多导致服务过载”“下载大文件中途断开”,Nginx与Ingress无直接的“下载数量限制”参数,需通过并发控制、超时配置间接实现。

1. Nginx 下载限制

常见问题1:并发下载数过多,服务器CPU/带宽耗尽

解决方案:通过limit_conn模块限制单IP或全局并发连接数(下载请求本质是HTTP连接):

http {
  limit_conn_zone $binary_remote_addr zone=perip:10m; # 按IP划分连接池,容量10M
  limit_conn_zone $server_name zone=perserver:10m; # 按服务名划分连接池

  server {
    listen 80;
    server_name example.com;

    location /download {
      limit_conn perip 5; # 单IP最大并发下载连接数5
      limit_conn perserver 100; # 该服务全局最大并发下载连接数100
      proxy_pass http://backend;
    }
  }
}

常见问题2:下载大文件中途断开,返回504/499错误

问题原因:下载大文件耗时较长,若Nginx的读取超时、连接超时参数设置过短,会主动断开与后端服务或客户端的连接。

解决方案:调整下载相关超时参数(具体参数见下文“超时问题”部分),同时关闭Nginx的sendfiletcp_nopush参数(大文件下载时易导致连接不稳定):

location /download {
  sendfile off;
  tcp_nopush off;
  proxy_read_timeout 3600s; # 读取后端响应超时1小时
  proxy_send_timeout 3600s; # 向客户端发送响应超时1小时
  proxy_connect_timeout 60s; # 与后端建立连接超时60秒
}

2. K8S Ingress 下载限制

问题成因:与Nginx类似,Ingress的下载限制需通过注解配置并发控制和超时参数,若未配置,默认并发数无限制,超时时间较短(通常为60s),易导致大文件下载中断。

解决方案

  • 并发下载控制:通过Ingress注解配置limit_conn相关参数,示例:
metadata:
  annotations:
    nginx.ingress.kubernetes.io/limit-connections: "5" # 单IP最大并发连接数
    nginx.ingress.kubernetes.io/limit-connection-rate: "10240" # 单连接速率限制(字节/秒)
  • 大文件下载超时配置:通过注解调整超时参数,覆盖默认值:
metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "60"

注意事项:Ingress的并发限制依赖Nginx Ingress Controller的limit_conn模块,需确保Controller镜像已启用该模块(主流镜像默认启用)。

四、IP访问限制相关问题

IP限制用于禁止或允许特定IP/网段访问服务,常见问题为“IP限制不生效”“误拦截合法IP”,核心是配置层级冲突或网段格式错误。

1. Nginx IP限制

解决方案:通过allowdeny指令配置,支持单IP、网段,配置层级为http、server、location(优先级从高到低),示例:

location /admin {
  # 允许192.168.1.0/24网段和127.0.0.1访问,拒绝其他所有IP
  allow 192.168.1.0/24;
  allow 127.0.0.1;
  deny all;
}

常见问题排查

  • 若配置不生效,检查是否存在多层级配置冲突(如location层级的配置覆盖server层级)。
  • 若使用反向代理,客户端真实IP会被代理IP覆盖,需配置real_ip_header X-Forwarded-For;set_real_ip_from参数,获取真实客户端IP后再做限制。

2. K8S Ingress IP限制

解决方案:Ingress支持通过注解配置IP白名单/黑名单,主流注解如下:

1)白名单配置(仅允许指定IP/网段访问):

metadata:
  annotations:
    nginx.ingress.kubernetes.io/whitelist-source-range: "192.168.1.0/24,127.0.0.1"

2)黑名单配置(需结合全局ConfigMap启用):

先在全局ConfigMap中启用黑名单模块

data:
  enable-ip-whitelist: "true"

再通过注解配置黑名单

metadata:
  annotations:
    nginx.ingress.kubernetes.io/blacklist-source-range: "10.0.0.0/8"

常见问题排查

  • IP网段格式错误:需使用CIDR格式(如192.168.1.0/24),多个IP/网段用逗号分隔,不可加空格。
  • 若Ingress位于多层代理之后(如前端有CDN、Waf、负载等),需配置nginx.ingress.kubernetes.io/real-ip-header: "X-Forwarded-For",确保获取客户端真实IP。

五、网速限制相关问题

网速限制用于控制单客户端或全局的访问带宽,避免个别客户端占用过多带宽导致服务不可用,常见问题为“网速限制不生效”“限制后带宽不稳定”。

1. Nginx 网速限制

问题成因:Nginx通过limit_ratelimit_rate_after参数控制网速,默认无限制,需手动配置,且仅对单连接生效。

解决方案

location /download {
  limit_rate_after 10m; # 下载前10M不限速,超过后开始限速
  limit_rate 1024k; # 限速1MB/s(单连接速率)
  limit_conn perip 5; # 结合并发限制,避免多连接突破限速
}

注意事项limit_rate针对单连接,若客户端开启多线程下载,需配合limit_conn限制并发连接数,才能实现整体网速控制。

2. K8S Ingress 网速限制

解决方案:通过Ingress注解配置网速限制,依赖Nginx的limit_rate模块,示例:

metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-rate-limit: "1024k" # 单连接限速1MB/s
    nginx.ingress.kubernetes.io/proxy-rate-limit-after: "10m" # 前10M不限速

常见问题:若限速不生效,检查Ingress Controller是否启用limit_rate模块,可通过查看Controller日志或执行kubectl exec -it <ingress-pod> -- nginx -V验证模块是否加载。

六、超时相关问题

超时问题是运维中高频场景,表现为请求超时返回504 Gateway Timeout499 Client Closed Request,核心是Nginx/Ingress与后端服务的超时参数不匹配,或网络延迟导致请求未及时响应。

1. Nginx 超时配置

Nginx的超时参数主要分为四类,需根据业务场景合理配置:

  1. 连接超时
  • client_body_timeout 60s;(等待客户端发送请求体的超时时间,默认60s);
  • client_header_timeout 60s;(等待客户端发送请求头的超时时间,默认60s)。
  1. 与后端交互超时
  • proxy_connect_timeout 60s;(与后端服务建立连接的超时时间,默认60s);
  • proxy_read_timeout 120s;(读取后端服务响应的超时时间,默认60s);
  • proxy_send_timeout 120s;(向后端服务发送请求的超时时间,默认60s)。
  1. 长连接超时
  • keepalive_timeout 65s;(客户端与Nginx长连接的超时时间,默认75s)。
  1. 大文件/慢请求超时
  • 针对上传下载、批量处理等慢请求,需延长proxy_read_timeoutproxy_send_timeout至3600s(1小时)以上。

2. K8S Ingress 超时配置

Ingress通过注解覆盖默认超时参数,对应Nginx的超时参数,示例:

metadata:
  annotations:
    # 与后端建立连接超时
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "60"
    # 读取后端响应超时
    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
    # 向客户端发送响应超时
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
    # 等待客户端发送请求头/体超时
    nginx.ingress.kubernetes.io/client-header-timeout: "60"
    nginx.ingress.kubernetes.io/client-body-timeout: "60"

常见问题排查

  • 504错误:通常是proxy_read_timeout过短,后端服务处理耗时超过限制,需延长该参数并排查后端服务性能。
  • 499错误:客户端主动断开连接,可能是客户端超时设置短于Ingress配置,或网络波动导致,需协调客户端调整超时时间,同时优化网络稳定性。

七、其他常见问题及通用排查方法

1. 配置生效问题

  • Nginx:修改配置后需执行nginx -t验证配置语法,再执行nginx -s reload重载配置,避免语法错误导致服务中断。
  • K8S Ingress:注解或ConfigMap修改后,Ingress Controller会自动重载配置(通常耗时10-30秒),可通过kubectl logs <ingress-pod>查看配置重载日志,确认是否生效。

2. 日志排查方法

Nginx:默认日志路径为/var/log/nginx/access.log(访问日志)和error.log(错误日志),可通过日志中的状态码、IP、请求时间定位问题(如413对应文件过大,504对应超时)。

K8S Ingress:通过kubectl logs -f <ingress-pod> -n ingress-nginx查看实时日志,同时可开启Ingress的访问日志,在ConfigMap中配置:

data:
  enable-access-log: "true"
  access-log-path: "/var/log/nginx/access.log"

3. 配置优先级问题

无论是Nginx还是Ingress,配置优先级均遵循“局部覆盖全局”“精准路径覆盖模糊路径”原则,运维时需明确配置层级,避免冲突。例如Ingress中,单个Ingress资源的注解优先级高于全局ConfigMap,location层级的Nginx配置优先级高于server层级。

总结

Nginx与K8S Ingress的运维问题核心集中在“配置适配”和“参数联动”,文件上传下载、IP限制、网速限制、超时等场景的问题,本质是对默认配置的不合理性和业务场景的适配不足。

运维时需结合业务需求(如文件大小、并发量、响应耗时),针对性调整配置参数,同时建立日志监控和配置验证机制,快速定位并解决问题。此外,需注意Nginx与Ingress的配置联动,避免层级冲突,确保整体服务的稳定性和可用性。


有帮助请点赞+收藏!文章有疑问的地方可以在评论区留言,我会在第一时间回你解答~

这篇文章有用吗?

点击星号为它评分!

平均评分 0 / 5. 投票数: 0

到目前为止还没有投票!成为第一位评论此文章。

很抱歉,这篇文章对您没有用!

让我们改善这篇文章!

告诉我们我们如何改善这篇文章?

- THE END -

真成运维

1月13日23:50

最后修改:2026年1月13日
0

非特殊说明,本博所有文章均为博主原创。