本文目录导读:

- 核心架构:PHP-FPM + Nginx 分离
- PHP 容器镜像最佳实践
- 配置管理:ConfigMap + Secret
- 有状态部分:Session 和 文件存储
- 水平伸缩与监控
- CI/CD 流水线建议
- 常见坑与优化
- 完整项目结构示例
在Kubernetes中编排管理PHP容器,核心思路是将PHP应用无状态化,并利用K8s的调度、伸缩、服务发现和配置管理能力,以下是具体的编排方案和最佳实践。
核心架构:PHP-FPM + Nginx 分离
这是最标准、最高效的K8s PHP部署模式。PHP-FPM 处理PHP代码逻辑,Nginx 作为反向代理静态文件和请求转发。
部署文件示例(Deployment + Service)
(1) PHP-FPM Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: php-fpm
spec:
replicas: 3
selector:
matchLabels:
app: php-backend
template:
metadata:
labels:
app: php-backend
spec:
# 可选:使用私有仓库拉取镜像
# imagePullSecrets:
# - name: my-registry-key
containers:
- name: php-fpm
image: your-registry/php-fpm:8.2 # 或使用官方镜像加自定义
ports:
- containerPort: 9000
env:
- name: APP_ENV
value: "production"
- name: DB_HOST
valueFrom:
secretKeyRef:
name: db-secret
key: host
livenessProbe:
tcpSocket:
port: 9000
initialDelaySeconds: 10
periodSeconds: 15
readinessProbe:
tcpSocket:
port: 9000
initialDelaySeconds: 5
periodSeconds: 5
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
volumeMounts:
- name: php-code
mountPath: /var/www/html
# 可选:挂载配置文件
- name: php-config
mountPath: /usr/local/etc/php/conf.d/custom.ini
subPath: custom.ini
volumes:
- name: php-code
emptyDir: {} # 或使用PVC共享代码
- name: php-config
configMap:
name: php-config
(2) Nginx Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx-proxy
template:
metadata:
labels:
app: nginx-proxy
spec:
volumes:
- name: php-code
emptyDir: {}
- name: nginx-config
configMap:
name: nginx-config
initContainers:
- name: copy-php-code
image: busybox
command: ['sh', '-c', 'cp -r /src/* /dest/']
volumeMounts:
- name: php-code
mountPath: /dest
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: php-code
mountPath: /var/www/html
readOnly: true
- name: nginx-config
mountPath: /etc/nginx/conf.d/default.conf
subPath: default.conf
livenessProbe:
httpGet:
path: /health.php # 需要有一个健康检查文件
port: 80
initialDelaySeconds: 10
periodSeconds: 10
(3) 共享代码卷
通常使用 PVC(PersistentVolumeClaim) 或 InitContainer 来同步代码:
- PVC方式:
ReadWriteMany模式(如NFS、CephFS) - InitContainer方式:用
emptyDir+ InitContainer从代码仓库拉取,适合代码定期更新场景
(4) 服务发现 Service
---
apiVersion: v1
kind: Service
metadata:
name: php-fpm-service
spec:
selector:
app: php-backend
ports:
- port: 9000
targetPort: 9000
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: ClusterIP # 外部访问用Ingress
selector:
app: nginx-proxy
ports:
- port: 80
targetPort: 80
(5) Ingress 暴露外部访问
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: php-app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: app.yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
tls: # 可选HTTPS
- hosts:
- app.yourdomain.com
secretName: tls-secret
PHP 容器镜像最佳实践
# 多阶段构建,减小镜像体积
FROM composer:2.5 as build
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader
FROM php:8.2-fpm-alpine
WORKDIR /var/www/html
# 安装必要扩展
RUN docker-php-ext-install pdo_mysql opcache redis bcmath
# 复制依赖(从第一阶段)
COPY --from=build /app/vendor /var/www/html/vendor
# 复制应用代码
COPY . /var/www/html
# 设置权限
RUN chown -R www-data:www-data /var/www/html \
&& chmod -R 755 /var/www/html/storage /var/www/html/bootstrap/cache
# 挂载点声明
VOLUME ["/var/www/html/storage", "/var/www/html/public/uploads"]
USER www-data
EXPOSE 9000
CMD ["php-fpm"]
配置管理:ConfigMap + Secret
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: php-config
data:
custom.ini: |
memory_limit = 256M
max_execution_time = 120
post_max_size = 50M
upload_max_filesize = 20M
---
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
stringData:
host: "mysql-service.default.svc.cluster.local"
database: "myapp"
username: "app_user"
password: "your_secure_password"
在PHP代码中,通过环境变量读取配置:
$dbHost = $_ENV['DB_HOST'] ?? 'localhost'; // 或使用 dotenv 库
有状态部分:Session 和 文件存储
PHP应用通常需要处理 Session 和 上传文件,在K8s中必须外部化:
- Session存储 → 使用 Redis 或 Memcached
- 上传文件存储 → 使用 对象存储 (AWS S3 / MinIO) 或 共享PVC (NFS)
- 日志集中化 → 使用
Filebeat+ELK或 直接输出到stdout/stderr由容器运行时处理
Session 配置示例(Redis):
session.save_handler = redis session.save_path = "tcp://redis-service:6379?auth=yourpass"
水平伸缩与监控
自动伸缩 (HPA)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: php-fpm-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-fpm
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
Pod 资源请求/限制
- PHP-FPM:通常每个Pod建议 200m CPU / 256Mi 内存(请求),500m / 512Mi(限制)
- Nginx:更轻量,100m / 128Mi 即可
监控集成
- K8s自带的dashboard、Prometheus + Grafana 或 Datadog。
- 提示:可以暴露PHP-FPM的状态页(
pm.status_path = /status)给监控组件。
CI/CD 流水线建议
- 代码提交 → 触发GitLab CI / GitHub Actions
- 构建镜像 → 将PHP应用编译到镜像中(包含所有依赖)
- 推送到仓库 → 带版本标签(如
v1.2.3或commit hash) - 更新K8s → 执行
kubectl set image deployment/php-fpm app=your-registry/php-app:v1.2.3 - 滚动更新 → K8s自动处理,零停机
常见坑与优化
| 问题 | 解决方案 |
|---|---|
| PHP代码文件需要频繁更新 | 用InitContainer或sidecar同步代码,或把代码放入镜像重建 |
| 上传文件丢失 | 必须用PVC (ReadWriteMany) 或 S3 代替本地存储 |
| Session丢失 | 迁移到 Redis/数据库存储 |
| PHP-FPM进程数不合适 | 调整 pm.max_children, pm.start_servers,使用 HPA |
| Nginx缓存问题 | 清理opcache,使用CDN |
| 数据库连接过多 | 配置数据库最大连接数,使用连接池 |
完整项目结构示例
php-k8s/
├── k8s/
│ ├── namespace.yaml
│ ├── configmap.yaml
│ ├── secret.yaml
│ ├── php-fpm-deployment.yaml
│ ├── nginx-deployment.yaml
│ ├── services.yaml
│ ├── ingress.yaml
│ └── hpa.yaml
├── docker/
│ ├── php.Dockerfile
│ └── nginx.Dockerfile
├── src/
│ ├── public/
│ ├── app/
│ ├── config/
│ └── composer.json
└── .gitlab-ci.yml
K8s编排PHP的核心原则:无状态 + 外部化存储 + 合理资源控制,推荐采用 PHP-FPM + Nginx 分离架构,用 ConfigMap 管理配置,Secret 管理敏感信息,Redis 管理Session,对象存储 管理文件,配合HPA实现弹性伸缩。
这样既发挥了K8s的弹性优势,又避免了PHP传统部署中的状态管理难题。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播