hyperf在k8s上蓝绿部署需手动维护两套deployment并切换service selector,滚动更新则直接使用rollingupdate策略,通过调优maxsurge、maxunavailable和minreadyseconds参数实现零中断升级。

Hyperf 项目在 K8s 上做蓝绿部署,本质是绕过原生限制的手动编排;而滚动更新直接用 RollingUpdate 策略即可生效,无需额外工具。 不要指望 Kubernetes 自带 “蓝绿” 类型字段——它没有,所有蓝绿都是靠两个 Deployment + 切换 Service selector 或 Ingress 路由实现的。
滚动更新:直接改镜像触发 RollingUpdate 就够了
Hyperf 应用只要定义了标准 Deployment,默认就是 RollingUpdate 策略。你不需要显式写 strategy.type: RollingUpdate(K8s 1.19+ 默认值),但建议显式声明并调优参数:
-
maxSurge控制最多多出几个 Pod(比如25%或1),避免资源突增压垮节点 -
maxUnavailable控制最多几个旧 Pod 同时不可用(比如0表示零中断,但要求资源充足) -
minReadySeconds强制新 Pod 启动后必须就绪至少 X 秒才被视为“可用”,防止健康检查通过太早(Hyperf 的/health接口可能返回 200 但协程池还没热起来)
示例片段:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
minReadySeconds: 30
执行更新只需改 image 并 kubectl apply -f deploy.yaml。K8s 会自动拉新镜像、起新 Pod、等就绪、删旧 Pod。注意:Hyperf 容器启动慢(尤其首次加载注解),minReadySeconds 设太小会导致流量切过去但服务没真正 ready。
蓝绿部署:必须维护两套 Deployment + 动态切 Service
Kubernetes 没有内置蓝绿资源类型,所谓“蓝绿”只是人为约定命名(比如 hyperf-app-blue 和 hyperf-app-green),核心在于让 Service 的 selector 只匹配其中一套:
- 蓝色环境上线时,
Service的selector是app: hyperf-app, env: blue - 绿色环境部署完成并通过测试后,只改
Service的selector为env: green,K8s 会秒级重刷Endpoints - 旧蓝色 Pod 不会立即销毁,可保留用于快速回滚(改回 selector 即可)
关键点:两个 Deployment 必须用完全相同的 containerPort 和健康检查路径(如 /health),否则 Service 无法统一转发。别在 YAML 里写死 IP 或端口——K8s Service 抽象层就是干这个的。
Hyperf 特有的坑:健康检查与协程热身
滚动更新或蓝绿切换后,新 Pod 经常出现短暂 5xx,不是配置问题,而是 Hyperf 自身行为:
-
livenessProbe和readinessProbe若只用httpGet到/health,可能返回 200 但实际协程池/DB 连接池未初始化完毕 - 多阶段构建镜像中若没开启
SCAN_CACHEABLE,每次启动都要全量扫描注解,冷启动耗时可能超initialDelaySeconds - 建议在
readinessProbe中加简单业务逻辑(比如查一次 Redis ping),确保真实依赖就绪
示例探测配置:
readinessProbe:
httpGet:
path: /health?ready=1
port: 9501
initialDelaySeconds: 20
periodSeconds: 5
timeoutSeconds: 3
并在 Hyperf 的 HealthCheck 中判断是否已建立 DB/Redis 连接,而非只返回固定 JSON。
蓝绿 vs 滚动:选哪个取决于你的风险承受力和资源
滚动更新适合大多数场景——省资源、配置简洁、K8s 原生支持;但它存在短暂新老版本共存期(比如旧 Pod 还在处理长连接,新 Pod 已开始接流量)。蓝绿部署能彻底隔离版本,但代价是双倍资源占用、需人工或脚本管理两套 YAML、且切换瞬间若新环境有缺陷会全量影响用户。对 Hyperf 这类常驻内存框架,蓝绿更适合重大重构或协议升级,日常小迭代用滚动更新更务实。别为了“蓝绿”概念硬上,先确认你真需要那几秒的绝对隔离。











