php应用在kubernetes稳定运行的关键在于镜像构建规范、探针配置合理、service与ingress标签严格对齐、containerport匹配实际监听端口,以及configmap/secret挂载时机正确,避免500/404、crashloopbackoff和流量不通等问题。

PHP 应用在 Kubernetes 上稳定运行,关键不在“能不能跑”,而在“怎么扛住真实流量、怎么快速恢复、怎么不让配置错一个字母就全挂”。它不是把 docker run 搬进 YAML 就完事——镜像构建方式、探针路径、Service 标签匹配、Ingress 路由规则,每个环节都卡得死死的。
怎么写一个不踩坑的 PHP 镜像 Dockerfile
本地能跑的 Laravel 或 ThinkPHP,放进容器就 500 或 404,90% 出在镜像层。别抄 Apache 官方默认配置,也别用 php:8.2-apache 硬塞静态文件和 PHP 逻辑到一块儿。
- 优先用多阶段构建:前端用
nginx:alpine,后端用php:8.2-fpm-alpine,减小体积、分离关注点 -
COPY . /var/www/html/后必须加RUN chown -R www-data:www-data /var/www/html/,否则 Nginx 或 PHP-FPM 进程无权读取 - Laravel 项目要
RUN cp .env.example .env && php artisan key:generate,否则容器启动直接报Application key not set - 别在 Dockerfile 里写
EXPOSE 80当“开放端口”——这只是元数据,真正生效靠的是 Deployment 中的containerPort - 安装扩展用
docker-php-ext-install,比如pdo_mysql mbstring opcache,别漏opcache,否则每次请求都重编译
Deployment 中 containerPort 写多少才对
写错 containerPort 是 CrashLoopBackOff 和 curl: connection refused 的高频原因。它不是你本地开发时习惯的 8080,而是容器内进程实际监听的端口。
- 用
php:8.2-apache镜像?Apache 默认监听0.0.0.0:80→containerPort: 80 - 用
php:8.2-fpm镜像?PHP-FPM 默认监听0.0.0.0:9000→containerPort: 9000 - 用 Nginx + PHP-FPM 双容器?Nginx 容器的
containerPort是80;PHP-FPM 容器的containerPort是9000,且两者需通过emptyDir共享/var/www/html - 如果用了自定义
www.conf改了listen地址(比如改成127.0.0.1:9000),那 Nginx 就连不上它——必须是0.0.0.0:9000
livenessProbe 和 readinessProbe 怎么配才不误杀
探针配错,不是服务没起来就被干掉,就是流量导进来才发现 PHP 还在加载 autoload —— 健康检查不是摆设,得反映真实就绪状态。
- 别用
/healthz或/readyz:PHP 项目默认没有这些路由,会一直返回 404,导致探针失败 - 简单项目可用
GET /index.php,但注意:如果index.php里有数据库连接逻辑,而 DB 还没就绪,就会误判为失败 - 推荐加一个轻量
/ping路由:Laravel 里Route::get('/ping', fn() => response('OK', 200));,ThinkPHP 类似,返回纯 200 即可 -
initialDelaySeconds至少设为 10:Composer autoload、OPcache warmup、.env 加载都需要时间 - PHP-FPM 容器的
livenessProbe可用exec检查进程:command: ["sh", "-c", "kill -0 $(cat /var/run/php-fpm.pid) 2>/dev/null"]
Service selector 和 Ingress rule 怎么对齐才不出问题
90% 的“部署成功但 curl 不通”,根源不在 PHP,而在 Service 和 Ingress 的标签没对上,或者 Ingress Controller 根本没运行。
-
Service.spec.selector和Deployment.spec.template.metadata.labels必须**逐字一致**:app: my-php-app≠app: my-phpapp,空格、大小写、连字符都不能错 - 先执行
kubectl get endpoints <service-name></service-name>:如果显示<none></none>,说明 Service 没匹配到任何 Pod,立刻回头查 label - Ingress 的
spec.rules[].host要和你 DNS 解析的域名一致;spec.rules[].http.paths[].backend.service.name必须是 Service 的真实名字,不是 Deployment 名 - 确认 Ingress Controller 已运行:
kubectl get pods -n ingress-nginx(或你装的命名空间),没 Pod 就配再好也没用 - NodePort 类型的 Service,端口范围只能是
30000–32767,写成8080会被 K8s 自动分配,别硬指定
最易被忽略的点:ConfigMap 和 Secret 的挂载时机。PHP 的 php.ini 或 .env 文件如果在容器启动后再挂载,PHP-FPM 进程已经加载完配置,改了也白改——必须用 subPath 或 initContainer 预处理,或者干脆在镜像构建阶段就把配置写死(非敏感项)。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











