You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

K8s Ingress中PHP静态资源Nginx配置失效问题

K8s Ingress部署PHP应用静态资源及FPM访问问题

我通过K8s Ingress部署了PHP应用,原本能正常访问index.php和面板,PHP-FPM执行也没问题,但静态资源一直无法访问。本地Docker Compose里用的Nginx服务器片段配置能正常工作,但放到Ingress里就失效了。之前还能看到Ingress发往FPM的请求,但静态资源链接始终返回404;修改配置后更糟,现在连FPM都访问不了,请求直接被Ingress拦截返回404。我查了大量文档试了各种配置都解决不了,不想在FPM Pod里加Nginx容器,觉得这不是最佳实践,而且Ingress早就支持直接转发请求到FPM的场景。

相关配置如下:

apiVersion: v1
kind: ConfigMap
metadata:
  name: ingress-cm
data:
  SCRIPT_FILENAME: "/var/www/index.php"
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: letsencrypt
    nginx.ingress.kubernetes.io/proxy-read-timeout: "1800"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "1800"
    nginx.ingress.kubernetes.io/fastcgi_send_timeout: "1800"
    nginx.ingress.kubernetes.io/fastcgi_read_timeout: "1800"
    nginx.ingress.kubernetes.io/backend-protocol: "FCGI"
    nginx.ingress.kubernetes.io/fastcgi-index: "index.php"
    nginx.ingress.kubernetes.io/fastcgi-params-configmap: "ingress-cm"
    nginx.ingress.kubernetes.io/server-snippet: |
      ...
      location ~ ^/themes/.*/assets { try_files $uri 404; }
      location ~ ^/themes/.*/bundles { try_files $uri 404; }
      location ~ ^/themes/.*/resources { try_files $uri 404; }
  name: app-ingress
spec:
  tls:
    - hosts:
        - {url}
      secretName: letsencrypt
  rules:
    - host: {url}
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app-service
                port:
                  number: 9000 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
  labels:
    app: app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app
  template:
    metadata:
      labels:
        app: app
    spec:
      imagePullSecrets:
        - name: {reg}
      containers:
      - name: app
        image: {image}
        ports:
        - containerPort: 9000
---
apiVersion: v1
kind: Service
metadata:
  name: app-service
  labels:
    run: app-service
spec:
  ports:
  - port: 9000
    protocol: TCP
  selector:
    app: app

问题核心分析

  1. 静态资源访问失败:Ingress Controller是独立Pod,无法直接读取FPM Pod内的静态文件。之前的配置要么把静态请求转发给FPM(FPM无法处理静态资源返回404),要么Ingress自身找不到文件返回404。
  2. FPM突然无法访问:修改配置后,server-snippet中的location规则覆盖了默认的FCGI转发逻辑,导致动态请求没有被发送到FPM服务。

解决方案

方案1:通过共享存储让Ingress直接访问静态资源

这种方案让Ingress Controller和FPM Pod共享静态资源存储,Ingress直接返回静态文件,动态请求转发给FPM。

  1. 修改ConfigMap参数:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: ingress-cm
    data:
      SCRIPT_FILENAME: "/var/www/$fastcgi_script_name"
      PATH_INFO: "$fastcgi_path_info"
    

    把固定的index.php改为$fastcgi_script_name,确保动态请求能正确对应到PHP文件路径。

  2. 调整Ingress配置:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
        kubernetes.io/ingress.class: "nginx"
        cert-manager.io/cluster-issuer: letsencrypt
        nginx.ingress.kubernetes.io/proxy-read-timeout: "1800"
        nginx.ingress.kubernetes.io/proxy-send-timeout: "1800"
        nginx.ingress.kubernetes.io/fastcgi_send_timeout: "1800"
        nginx.ingress.kubernetes.io/fastcgi_read_timeout: "1800"
        nginx.ingress.kubernetes.io/backend-protocol: "FCGI"
        nginx.ingress.kubernetes.io/fastcgi-index: "index.php"
        nginx.ingress.kubernetes.io/fastcgi-params-configmap: "ingress-cm"
        nginx.ingress.kubernetes.io/server-snippet: |
          root /var/www;
          # 优先处理静态资源
          location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg)$ {
              try_files $uri =404;
              expires 1y;
              add_header Cache-Control "public, immutable";
          }
          location ~ ^/themes/.*/(assets|bundles|resources) {
              try_files $uri =404;
          }
      name: app-ingress
    spec:
      tls:
        - hosts:
            - {url}
          secretName: letsencrypt
      rules:
        - host: {url}
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: app-service
                    port:
                      number: 9000 
    
  3. 挂载共享存储:创建PVC存储静态资源,同时挂载到Ingress Controller Pod和FPM Pod(需修改Ingress Controller的Deployment配置添加挂载)。


方案2:拆分静态资源到独立服务(更推荐)

将静态资源部署为独立的Nginx服务,Ingress根据路径转发请求,彻底解耦动态和静态服务。

  1. 部署静态资源服务:创建一个Nginx Deployment和Service,挂载包含静态资源的PVC或使用内置静态资源的镜像。
  2. 修改Ingress配置:
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
        kubernetes.io/ingress.class: "nginx"
        cert-manager.io/cluster-issuer: letsencrypt
        nginx.ingress.kubernetes.io/proxy-read-timeout: "1800"
        nginx.ingress.kubernetes.io/proxy-send-timeout: "1800"
        nginx.ingress.kubernetes.io/fastcgi_send_timeout: "1800"
        nginx.ingress.kubernetes.io/fastcgi_read_timeout: "1800"
        nginx.ingress.kubernetes.io/backend-protocol: "FCGI"
        nginx.ingress.kubernetes.io/fastcgi-index: "index.php"
        nginx.ingress.kubernetes.io/fastcgi-params-configmap: "ingress-cm"
      name: app-ingress
    spec:
      tls:
        - hosts:
            - {url}
          secretName: letsencrypt
      rules:
        - host: {url}
          http:
            paths:
              # 静态资源路径转发到静态服务
              - path: /themes
                pathType: Prefix
                backend:
                  service:
                    name: static-service
                    port:
                      number: 80
              - path: /css
                pathType: Prefix
                backend:
                  service:
                    name: static-service
                    port:
                      number: 80
              - path: /js
                pathType: Prefix
                backend:
                  service:
                    name: static-service
                    port:
                      number: 80
              # 其余请求转发到FPM
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: app-service
                    port:
                      number: 9000 
    

关键注意事项

  • 不要用固定的SCRIPT_FILENAME,必须使用$fastcgi_script_name确保动态请求路径正确。
  • 静态资源的location规则优先级高于默认的Prefix路径,确保静态请求先被处理。
  • 若使用共享存储,需确保Ingress Controller和FPM Pod的挂载路径一致,且文件权限正确。

内容的提问来源于stack exchange,提问作者muhammed ikinci

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 03:17:04