本文目录导读:

- 基础架构与集群安全
- 容器镜像安全 (PHP 专用)
- Pod 安全上下文与资源限制
- PHP 应用层安全策略
- 运行时安全与监控
- 特殊场景:Composer 依赖与 Session
- 一个简化的安全 Deployment 示例
- 总结建议
在 Kubernetes 中运行 PHP 应用时,安全策略需要覆盖集群层面、Pod/容器层面以及应用代码层面,以下是一份针对 PHP 项目的 Kubernetes 安全策略指南。
基础架构与集群安全
- 最小权限的 ServiceAccount:避免使用
defaultServiceAccount,为每个 PHP 微服务创建专用的 ServiceAccount,并仅授予其执行任务所需的最小 RBAC 权限,一个只读数据库查询的 PHP 服务不应拥有创建 Pod 的权限。 - 网络策略:实现零信任网络模型,使用 NetworkPolicy 限制 Pod 之间的通信,PHP 前端 Pod 只能通过特定端口与 PHP API Pod 通信,PHP API Pod 只能与数据库 Pod 通信,禁止直接访问其他命名空间。
- Pod 安全标准:启用 Pod Security Admission 并设置为
restricted模式(对于 PHP 应用通常可行),这会强制要求: - 禁止以 root 用户运行容器。
- 禁止特权容器。
- 禁止
hostPath卷挂载(除非必要且明确允许)。 - 限制
capabilities(PHP 应用通常不需要NET_RAW)。 - Secret 管理:绝对不要在环境变量或 ConfigMap 中明文存储数据库密码、API 密钥等敏感数据,使用 Kubernetes Secret,并考虑启用加密(EncryptionConfiguration)或集成外部密钥管理系统(如 HashiCorp Vault、AWS Secrets Manager)。
容器镜像安全 (PHP 专用)
这是 PHP 项目最容易出问题的环节。
-
选择轻量级基础镜像:优先使用
php:8.2-fpm-alpine或php:8.2-cli-alpine,Alpine 基础镜像体积小,攻击面少。除非绝对必要,避免使用-slim或-bullseye等包含不必要工具的镜像。 -
移除不必要组件:在 Dockerfile 中构建 PHP 应用后,应删除编译依赖(如
gcc,make,autoconf)和包管理器缓存。# 多阶段构建示例 FROM php:8.2-fpm-alpine AS builder RUN apk add --no-cache $PHPIZE_DEPS \ && pecl install redis \ && docker-php-ext-install pdo_mysql \ && pecl clear-cache \ && apk del $PHPIZE_DEPS FROM php:8.2-fpm-alpine COPY --from=builder /usr/local/lib/php/extensions /usr/local/lib/php/extensions # 只保留运行时需要的依赖(如 libzip, libpq) RUN apk add --no-cache libzip libpq -
扫描镜像漏洞:强制使用
snyk,trivy或grype扫描所有构建的 PHP 镜像,在 CI/CD 流程中,禁止推送严重 (CRITICAL) 或高危 (HIGH) 漏洞的镜像至仓库。 -
非 root 用户运行:PHP-FPM 镜像默认以
www-data用户运行,但最好在 Dockerfile 中显式创建低权限用户。RUN addgroup -g 1001 -S appgroup && \ adduser -u 1001 -S appuser -G appgroup USER appuser -
只读文件系统:在容器运行时,将文件系统设置为只读(
readOnlyRootFilesystem: true),PHP 应用通常不需要写入var/www/html(除了日志或上传文件夹,这些应挂载为emptyDir或 PV)。securityContext: readOnlyRootFilesystem: true runAsNonRoot: true runAsUser: 1001 capabilities: drop: ["ALL"]
Pod 安全上下文与资源限制
在 Deployment/Pod 的 YAML 中明确设置:
- securityContext:
runAsUser: 1001 (对应 Dockerfile 中的用户)runAsGroup: 1001fsGroup: 1001 (确保挂载卷可读)runAsNonRoot: trueseccompProfile: type: RuntimeDefault(限制系统调用)allowPrivilegeEscalation: false
- 资源限制:设置
resources.limits和resources.requests防止资源耗尽攻击或影响其他 Pod。resources: requests: memory: "128Mi" cpu: "100m" limits: memory: "256Mi" cpu: "200m"
PHP 应用层安全策略
Kubernetes 无法解决代码漏洞,但可以配置环境以辅助防范:
- 禁用危险函数:在
php.ini中禁用exec(),system(),shell_exec(),passthru(),popen,proc_open等函数(除非业务确实需要,且做了严格限制)。disable_functions = exec, system, shell_exec, passthru, popen, proc_open, show_source, phpinfo
- 限制文件上传:在
php.ini中设置upload_max_filesize,post_max_size,max_file_uploads。 - 配置文件权限:通过 ConfigMap 注入自定义
php.ini,但不要在镜像中硬编码。 - 日志注入防御:PHP 日志(如错误日志)可能包含用户输入,在日志收集(如 Fluentd, Loki)之前,确保进行适当的转义或结构化日志记录(如 Monolog)。
运行时安全与监控
- 使用 Distroless 镜像:进一步减少攻击面,使用
gcr.io/distroless/php:8.2-debug或chainguard/php:8.2(Chainguard 提供的无 CVE 镜像),这些镜像没有 shell, 包管理器, 甚至没有ls命令。 - 禁止调试模式:确保
APP_DEBUG=false和APP_ENV=production环境变量始终设置,且可通过 ConfigMap 管理。 - 实现 Helm Chart 模板检查:在 CI 中运行
helm lint和helm template,并配合kubeval或polaris检查生成的 YAML 是否符合安全最佳实践。 - 运行时安全工具:在集群中安装 Falco 或 KubeArmor,它们可以监控 PHP 进程的异常行为:
- PHP 进程尝试读取
/etc/shadow→ 告警。 - PHP 进程创建子进程 → 告警。
- PHP 进程写入非预期的路径 → 告警。
- PHP 进程尝试读取
特殊场景:Composer 依赖与 Session
- Session 存储:默认的 PHP Session 文件存储在
/tmp,在多副本 Pod 中,使用 Redis 或 Memcached 作为 Session 存储(且连接加密),避免卷冲突和 Session 劫持。 - Composer 依赖:在构建时运行
composer install --no-dev --optimize-autoloader并移除composer.lock和 vendor 目录中的测试文件,确保第三方包来源可信(不使用--prefer-dist从不可信源下载)。
一个简化的安全 Deployment 示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: php-app
spec:
replicas: 2
selector:
matchLabels:
app: php-app
template:
metadata:
labels:
app: php-app
spec:
serviceAccountName: php-app-sa # 专用服务账号
securityContext: # Pod 级安全上下文
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: php
image: myregistry/php-app:latest
imagePullPolicy: Always
securityContext:
runAsUser: 1001
runAsGroup: 1001
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
readOnlyRootFilesystem: true
runAsNonRoot: true
env:
- name: APP_ENV
value: "production"
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
volumeMounts:
- name: tmp
mountPath: /tmp
readOnly: false # 允许写入临时文件
- name: php-config
mountPath: /usr/local/etc/php/conf.d/overrides.ini
subPath: overrides.ini
readOnly: true
volumes:
- name: tmp
emptyDir: {}
- name: php-config
configMap:
name: php-ini-config
总结建议
- 拒绝 root:绝不使用 root 用户运行容器。
- 最小化:镜像越小,漏洞越少;权限越小,风险越低。
- 只读:除了明确的写入目录(如 /tmp, uploads),文件系统设为只读。
- 扫描:所有镜像构建必须通过 CVE 扫描。
- 监控:部署 Falco 或 OPA Gatekeeper 来强制执行安全策略。
Kubernetes 提供了安全框架,但 PHP 应用自身的代码安全(防 SQL 注入、XSS、CSRF 等)仍然由开发者负责,做好这两端才能构建真正安全的系统。