ConfigMap 热更新滚动策略

解读

在国内一线互联网公司的 PHP 面试里,这道题表面问的是 Kubernetes 的 ConfigMap 更新机制,实则考察候选人“PHP 业务代码 + 容器化”全链路落地的能力。
面试官想确认三件事:

  1. 你是否知道 ConfigMap 变更后,Pod 内文件不会实时同步,必须配合滚动策略才能“无中断”生效;
  2. 你是否能把 PHP 的 OPcache、Laravel 配置缓存、Yii2 配置缓存等运行时缓存与 ConfigMap 热更新结合起来,给出可落地的灰度方案;
  3. 你是否熟悉国内云厂商(阿里云 ACK、腾讯云 TKE、华为云 CCE)的“配置中心”与“无损滚动”最佳实践,能回答出“秒级生效”“零请求失败”的量化指标。

知识点

  1. ConfigMap 的三种挂载方式:volume subPath、volume 覆盖目录、env 注入;只有 volume 方式支持热更新,但默认需要 60~90s 的 kubelet 同步周期。
  2. PHP 运行时缓存:
    • OPcache 把文件内容缓存在共享内存,inode 不变时不会重新编译;
    • Laravel 的 php artisan config:cache 把配置序列化到 /bootstrap/cache/config.php,文件不变则不复载;
    • Swoole、RoadRunner 这类常驻进程会把配置读进内存,重启 Worker 才生效。
  3. 滚动策略核心字段:
    • strategy.type=RollingUpdate
    • maxUnavailable=0(国内高并发场景强制要求零中断)
    • maxSurge=30%(按峰值 QPS 换算,保证双倍副本数可扛 5 分钟)
  4. 国内灰度套路:
    • 阿里云 ACK 的“配置热发布”插件,利用 inotify 秒级触发容器内脚本;
    • 腾讯云 TKE 的“配置版本”标签,配合 Helm pre-upgrade hook 做金丝雀;
    • 自研 sidecar:用 inotifywait 监听 /config,变更后执行 kill -USR2 php-fpm 平滑重载。
  5. 量化验收标准:
    • 配置变更到生效 P99 ≤ 3s;
    • 滚动期间 5xx 比例 ≤ 0.01%;
    • Pod 原地重启次数 0,必须走滚动而不是重建。

答案

“ConfigMap 热更新滚动策略”在国内 PHP 生产环境落地,我采用三步闭环:
第一步,挂载方式必须选 volume 且不用 subPath,让 kubelet 同步周期把新配置写进 Pod;同时把 PHP 的 OPcache 校验间隔调到 2s(opcache.revalidate_freq=2),保证文件变更后 2s 内重新编译。
第二步,在 Dockerfile 里引入一套 sidecar 脚本:

#!/bin/bash
inotifywait -m /config -e moved_to,close_write |
while read path action file; do
    # 清除 Laravel 配置缓存
    php /var/www/artisan config:clear
    # 平滑重载 php-fpm
    kill -USR2 1
done

这样 ConfigMap 一旦更新,sidecar 秒级触发,PHP 进程无中断加载新配置。
第三步,Deployment 滚动策略设为:

strategy:
  type: RollingUpdate
  rollingUpdate:
    maxUnavailable: 0
    maxSurge: 30%

配合 readinessProbe 检测 /readyz 接口,确保新副本配置生效后再上线;同时用 HPA 提前扩容 30%,防止滚动期间 CPU 突刺。
上线流程:

  1. 研发在 GitLab 提交 MR,修改 ConfigMap;
  2. CI 自动打标签 config-version=20240618-143022,触发 ArgoCD 同步;
  3. 集群内 sidecar 3s 内完成重载,Prometheus 监控 5xx 比例 < 0.01% 即判定成功;
  4. 若 30s 内异常,自动回滚 ConfigMap 并重新滚动。
    该方案已在公司电商大促核心接口验证,配置变更 P99 延迟 2.7s,零请求失败,符合国内“618”“双11”无损发布要求。

拓展思考

  1. 如果 PHP 应用使用 Swoole 常驻进程,上述 kill -USR2 方案无效,需要把配置放进 Redis/APCu,利用 Swoole 的 onWorkerStart 定时 reload(),或者使用腾讯 TKE 的 “TSF 配置中心” 做长连接推送。
  2. 当 ConfigMap 大于 1MiB(etcd 默认限制)时,必须拆分成多个 ConfigMap 或改用阿里云 OOS、腾讯云 TCS 等外部配置中心,此时热更新策略要加上版本号校验和 MD5 签名,防止部分节点拉取失败导致配置漂移。
  3. 对金融级业务,监管要求“可审计”,需要把每次 ConfigMap 变更记录到 ElasticSearch,并接入钉钉、飞书 webhook 二次审批;滚动策略再加 partition 做灰度,先更新 10% Pod,观察 5 分钟无告警再继续,实现“人审 + 机审”双保险。