伪静态规则在k8s中不持久化,因pod无状态且配置未固化;必须通过configmap挂载nginx配置并启用fastcgi_split_path_info和path_info传递,否则thinkphp路由必404。

伪静态规则在 Kubernetes 里不“持久化”——它根本不在 Pod 里存,而必须落在 Web 服务器配置中,且每次容器重建都会丢失,除非你把规则固化进镜像或挂载为 ConfigMap。
为什么Nginx配置在K8s里一重启就失效
ThinkPHP 的伪静态依赖 Nginx 的 try_files 或 fastcgi_split_path_info 行为,但默认的 PHP-FPM 官方镜像(如 php:8.2-fpm-alpine)根本不带任何 ThinkPHP 专用配置。Kubernetes 中的 Pod 是无状态的,/etc/nginx/conf.d/default.conf 这类文件若没通过 ConfigMap 或 initContainer 注入,每次调度新 Pod 都会回到原始空配置。
- Nginx 容器启动时不会自动读取项目目录下的
.htaccess(Nginx 根本不支持) - 直接用
kubectl exec -it pod-name -- sed -i ...改配置,下次 Pod 重建就清零 - 宝塔、AMH 等面板工具在 K8s 里完全不可用,别指望“点一下开启”
- 如果你用了
location ~ \.php$块但漏了fastcgi_param PATH_INFO $fastcgi_path_info;,$_SERVER['PATH_INFO']就是空的,路由必然 404
ConfigMap + volumeMount 是最稳的落地方式
把 Nginx 配置抽成 ConfigMap,再挂载进容器覆盖默认配置,才能确保每次 Pod 启动都加载同一套规则。注意路径和权限:
- ConfigMap 的 key 名必须匹配挂载路径中的文件名,例如
nginx.conf→ 挂载到/etc/nginx/nginx.conf - 不要覆盖整个
/etc/nginx/,只替换/etc/nginx/conf.d/default.conf更安全 - 挂载后检查权限:
ls -l /etc/nginx/conf.d/,确保 Nginx 主进程能读(非 root 用户需fsGroup配合) - 典型 ConfigMap 内容必须含
fastcgi_split_path_info ^(.+\.php)(/.*)$;,否则/index.php/user/info解析失败
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-thinkphp-conf
data:
default.conf: |
server {
listen 80;
root /var/www/html/public;
index index.php;
<pre class="brush:php;toolbar:false;"> location / {
try_files $uri $uri/ /index.php?s=$uri&$args;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
include fastcgi_params;
}
}
Apache方案在K8s里要格外小心模块加载
用 httpd:2.4 镜像跑 ThinkPHP?Apache 必须显式启用 mod_rewrite,且容器内默认不加载——光靠 .htaccess 文件存在毫无作用。
- Dockerfile 中必须加:
RUN a2enmod rewrite && a2enmod headers -
<directory></directory>块里必须设AllowOverride All,不能只写FileInfo - 挂载
.htaccess到容器内时,路径必须和DocumentRoot对齐,否则RewriteBase会错位 - K8s 的
emptyDir或hostPath挂载无法保证.htaccess权限为 644,Apache 可能因权限拒绝读取
别忽略 Ingress 层的干扰
很多团队在 K8s 里配了 Nginx Ingress Controller,结果发现伪静态 URL 在 Ingress 外部能访问,进到 Pod 就 404——问题往往出在 Ingress 的 rewrite-target 或 use-regex 上。
- Ingress annotation
nginx.ingress.kubernetes.io/rewrite-target: /$2若正则写成/(.*)/(.*),会吃掉第一级路径,导致/user/profile变成/profile - 如果 Ingress 开了
nginx.ingress.kubernetes.io/use-regex: "true",但后端 Service 没做 path 透传,$args就丢了 - 更稳妥的做法是:Ingress 不做重写,把所有路径原样透传给 Service,让 Pod 内 Nginx 自己处理
try_files - 验证方法:直接
kubectl port-forward service/thinkphp-service 8080:80,用curl -v http://localhost:8080/user/profile绕过 Ingress 测试
真正容易被忽略的点是:K8s 里没有“重启 Nginx”这个操作,只有滚动更新 Pod;所以改完 ConfigMap 后,必须触发 Deployment 重建(比如加个 annotation),否则旧 Pod 里的 Nginx 进程永远读不到新配置。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











