K8s部署Nginx+PHP环境实战与优化指南
1. 为什么选择K8s部署Web环境十年前我刚入行时部署PHP网站还是用FTP上传文件到虚拟主机的方式。后来演进到用Ansible批量管理服务器直到三年前开始全面转向容器化部署。这个转变过程让我深刻体会到当你的网站需要应对突发流量、需要快速回滚版本、需要保证开发测试环境一致性时Kubernetes简称K8s确实是当前最靠谱的解决方案。这次要搭建的NginxPHP环境是绝大多数Web项目的标配组合。传统部署方式需要在每台服务器上手工安装配置而用K8s部署可以实现一键扩缩容流量激增时30秒内新增容器实例版本秒级回滚发现BUG立即退回上个稳定版本配置集中管理不用再逐台服务器修改nginx.conf资源精确控制给PHP容器分配刚好够用的CPU/内存下面我会结合生产环境踩坑经验手把手演示从零开始的过程。即使你刚接触K8s跟着操作也能在1小时内完成部署。2. 环境准备与工具选型2.1 基础环境配置我推荐使用以下组合这也是大多数中小企业的标配方案K8s集群Minikube本地开发或kubeadm搭建的生产集群容器运行时Docker 20.10 或 containerd操作系统Ubuntu 22.04 LTS兼容性最好硬件配置至少2核CPU/4GB内存PHP很吃内存重要提示生产环境务必禁用Swap分区否则K8s调度器会出问题。执行sudo swapoff -a并注释掉/etc/fstab中的swap行。2.2 容器镜像选择对于Web环境镜像选择直接影响性能和安全性# Nginx选用官方alpine版本体积小安全性高 docker pull nginx:1.23-alpine # PHP选择fpm版本注意要匹配你的代码版本 docker pull php:8.1-fpm为什么不用latest标签我在去年吃过亏——某次自动更新导致PHP8.2不兼容老代码。现在固定版本号更新前先在测试环境验证。3. 核心配置实战3.1 Nginx配置优化创建nginx.conf配置文件时这几个参数必须调整# 在http块中添加 keepalive_timeout 65; client_max_body_size 100M; gzip on; # 在server块中配置PHP转发 location ~ \.php$ { fastcgi_pass php-service:9000; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }把这份配置保存为ConfigMapkubectl create configmap nginx-config --from-filenginx.conf3.2 PHP-FPM调优php-fpm.conf需要重点关注这些参数[www] pm dynamic pm.max_children 50 # 根据内存计算内存总量/单个进程消耗 pm.start_servers 5 pm.min_spare_servers 2 pm.max_spare_servers 8计算max_children的公式假设容器内存限制2GB单个PHP进程占用80MB则 2000/80 ≈ 25建议留20%余量。3.3 Deployment编排示例完整的deployment.yaml应该包含apiVersion: apps/v1 kind: Deployment metadata: name: web-deployment spec: replicas: 3 selector: matchLabels: app: web template: metadata: labels: app: web spec: containers: - name: nginx image: nginx:1.23-alpine ports: - containerPort: 80 volumeMounts: - name: nginx-config mountPath: /etc/nginx/nginx.conf subPath: nginx.conf - name: php image: php:8.1-fpm resources: limits: memory: 2Gi cpu: 1 volumeMounts: - name: php-code mountPath: /var/www/html volumes: - name: nginx-config configMap: name: nginx-config - name: php-code persistentVolumeClaim: claimName: web-code-pvc4. 存储与网络方案4.1 代码持久化方案我对比过三种存储方案HostPath简单但无法跨节点NFS适合已有NAS环境PVCStorageClass云环境首选阿里云SSD云盘的StorageClass示例kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: alicloud-ssd provisioner: diskplugin.csi.alibabacloud.com parameters: type: cloud_ssd fsType: ext44.2 网络策略配置必须限制PHP容器的外网访问apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: php-network-policy spec: podSelector: matchLabels: app: web name: php policyTypes: - Egress egress: - to: - podSelector: matchLabels: app: web name: nginx ports: - protocol: TCP port: 90005. 运维监控要点5.1 健康检查配置PHP容器的livenessProbe应该这样配livenessProbe: exec: command: - sh - -c - SCRIPT_NAME/ping SCRIPT_FILENAME/ping REQUEST_METHODGET cgi-fcgi -bind -connect 127.0.0.1:9000 initialDelaySeconds: 30 periodSeconds: 105.2 日志收集方案建议使用Sidecar模式收集Nginx日志- name: log-collector image: fluent/fluentd:v1.14-debian-1 volumeMounts: - name: nginx-log mountPath: /var/log/nginx6. 常见故障排查6.1 502 Bad Gateway按这个顺序检查执行kubectl logs [php-pod]看PHP是否崩溃检查Service的selector是否匹配Pod标签验证网络策略是否放行9000端口6.2 文件上传失败八成是这三个原因Nginx的client_max_body_size太小PHP的upload_max_filesize限制/tmp目录没有写入权限7. 性能优化实战7.1 OPcache配置在php.ini中加入opcache.enable1 opcache.memory_consumption128 opcache.interned_strings_buffer8 opcache.max_accelerated_files4000 opcache.revalidate_freq607.2 Nginx缓存策略对于静态资源添加Headerlocation ~* \.(jpg|css|js)$ { expires 30d; add_header Cache-Control public; }把PHP容器升级到8.1版本后配合OPcache使我们的API响应时间从120ms降到了65ms。这个案例告诉我与其无脑扩容服务器不如先做好基础优化。