targetPort必须严格匹配containerPort的名称或数值:若用字符串(如http),则containerPort需声明name: http且port为80;若用数字(如80),则containerPort的port值必须为80;混用或不一致将导致Endpoint为空、流量无法转发。

Service 的 targetPort 必须匹配容器的 containerPort 名称或数值
在 Kubernetes 中,targetPort 是 Service 转发流量到 Pod 容器的“落点”,它必须能准确指向容器实际监听的端口。FrankenPHP 默认同时暴露两个端口:80(HTTP 服务)和 9001(FPM 接口),但绝大多数场景只用 80。
常见错误是把 targetPort: http 写成 targetPort: 80 却没在容器 ports 里声明 name: http,或者反过来——用了名字却没对齐。Kubernetes 不会自动猜,它严格按声明匹配。
- 若用字符串引用(推荐):Service 的
targetPort: http→ Pod 的containerPort必须带name: http,且port值为80 - 若用数字引用:Service 的
targetPort: 80→ Pod 的containerPort可以不写name,但port值必须是80 - 混用会失败:比如 Pod 声明了
name: http,但 Service 写targetPort: 80,Kubernetes 仍会尝试匹配数字;但如果 FrankenPHP 启动时被参数覆盖监听:8080,而 Service 没同步改,就彻底断连
containerPort 不是宿主机端口,也不触发 NAT
containerPort 在 Kubernetes 里纯粹是“文档性+校验性”字段:它不绑定宿主机端口,不开启 iptables 规则,也不影响容器内进程的实际监听行为。FrankenPHP 进程能不能收到流量,取决于它自己是否监听了 0.0.0.0:80(而非 127.0.0.1:80),以及 Service/Ingress 是否正确路由。
容易踩的坑:
立即学习“PHP免费学习笔记(深入)”;
- 误以为写了
containerPort: 80就等于容器在监听:80—— 实际监听地址由 FrankenPHP 启动参数决定,比如-- -listen :80或环境变量SERVER_NAME=:80 - 在 hostNetwork 模式下还写
containerPort—— 此时该字段完全被忽略,纯属冗余 - 给
targetPort写了不存在的名称(如targetPort: fpm),但容器没声明name: fpm,Service 创建会成功,但 Endpoint 永远为空
FrankenPHP 的 FPM 端口 9001 很少需要暴露给 Service
除非你有其他 Pod(比如独立的 Nginx)要直连 FrankenPHP 的 FPM 接口,否则 containerPort: 9001 和对应 targetPort 完全没必要出现在 Service 中。FrankenPHP 的 HTTP 模式(80)和 FPM 模式(9001)是互斥的运行方式:启用 php_server 就走内置 HTTP 服务;禁用它并配 fastcgi_pass 才走 FPM。生产中几乎都选前者。
如果你真要暴露 9001:
- 必须在容器
ports中显式声明name: fpm和port: 9001 - Service 的
targetPort必须用fpm(字符串)或9001(数字),且确保调用方连接的是 Pod IP + 9001,不是 ClusterIP - FPM 模式下 FrankenPHP 不处理 HTTPS 终结、静态文件、HTTP/3 等特性,这些得由前置代理承担,失去主要优势
验证 targetPort 是否生效最直接的方法
别只看 Service YAML 是否创建成功。真正要确认的是 Endpoint 是否有地址:
kubectl get endpoints <service-name>
如果输出里 ENDPOINTS 列为空,说明 Service 没找到后端 Pod 的目标端口 —— 大概率是 targetPort 和容器实际监听端口不一致,或者容器根本没在监听那个端口(比如 FrankenPHP 默认监听 :8080,但你配了 targetPort: 80)。
进一步排查:
- 进 Pod 查 FrankenPHP 进程监听状态:
ss -tlnp | grep :80(确认是否绑定了0.0.0.0:80) - 检查 Pod 的
containerPort声明和 Service 的targetPort类型(数字 or 字符串)是否严格对齐 - 留意 FrankenPHP 日志是否报错
listen tcp :80: bind: permission denied—— 非 root 容器绑定:80会失败,得换高权限端口或加securityContext
端口对齐这事看着简单,但 FrankenPHP 启动参数、环境变量、Kubernetes 声明、云厂商安全组四层之间稍有错位,流量就静默消失。建议把监听地址、containerPort、targetPort、安全组放行端口这四个值写在一张纸上对照着检查。



















