BCS GameStatefulSet 与 GameDeployment:游戏工作负载编排对比

腾讯蓝鲸容器管理平台 BCS 提供了两种面向游戏服务器的自定义 Kubernetes 工作负载:GameDeployment 管理无状态实例,GameStatefulSet 管理有状态实例。它们都采用 CRD + Operator 模式,在原生 Deployment 或 StatefulSet 能力之上扩展原地更新、镜像热更新、灰度发布和实例退出控制。

本文依据 2026-07-27 查阅的 bk-bcs master 分支 README。文档描述的 API 为 tkex.tencent.com/v1alpha1,部分能力依赖 BCS 其他组件或定制运行时;本文不把 README 中的能力声明等同于任意版本和任意 Kubernetes 环境都已验证可用。

一、为什么需要自定义游戏工作负载

游戏服务器发布经常要求缩短实例不可用时间、保留 Pod 身份或节点位置、分批灰度、在删除前等待对局结束,以及在节点异常后快速重建。原生 Deployment 和 StatefulSet 提供通用副本管理,但不能直接表达所有游戏生命周期语义。

BCS 的思路不是只给原生对象增加几个注解,而是定义两个新的 workload:

无状态游戏实例 → GameDeployment → 直接管理可替换的 Pod
有状态游戏实例 → GameStatefulSet → 保留 StatefulSet 的身份与顺序语义

这两个项目的 README 都将其描述为 CRD + Operator 实现。它们遵循的扩展思路可以结合 Kubebuilder 理解,但 README 没有声明这两个 Operator 使用 Kubebuilder 构建,因此不能据此推断其具体脚手架或 controller-runtime 版本。

二、GameDeployment

GameDeployment 是面向游戏无状态应用的增强工作负载。README 说明它基于 Kubernetes ReplicaSet Controller 改造,并参考了 OpenKruise 的部分实现。与原生 Deployment 通过多个 ReplicaSet 完成发布不同,GameDeployment 直接控制 Pod 的新增、删除和更新,以支持更细粒度的实例生命周期操作。^[来源:BCS GameDeployment README]

它提供的主要能力包括:

  • RollingUpdate:直接增删 Pod 完成滚动发布;
  • InplaceUpdate:保留 Pod,不重新调度,只重启并更新一个或多个容器;
  • HotPatchUpdate:保持 Pod 和容器生命周期,更新容器镜像版本;
  • partition:保留部分旧版本实例,实现灰度发布;
  • maxUnavailable:控制每批允许不可用的实例数量,默认值为 25%;
  • maxSurge:滚动更新前额外创建实例,降低发布期间的容量损失,默认值为 0;
  • 自动化分步骤灰度:支持调整 partition、永久暂停、定时暂停和外部 Hook;
  • PreDeleteHook:删除、缩容或更新 Pod 前等待业务确认;
  • HPA 和 Operator 高可用部署。

GameDeployment 的 Pod 没有 StatefulSet 式的固定序号和稳定身份,更适合实例之间可以互相替换、状态保存在外部系统中的服务。

三、GameStatefulSet

GameStatefulSet 是原生 StatefulSet 的增强实现,目标是在兼容 StatefulSet 特性的同时,补充游戏有状态实例需要的更新与故障恢复策略。其示例保留了 serviceNamepodManagementPolicy、稳定序号、partition 和 Pod Template 等 StatefulSet 风格字段。^[来源:BCS GameStatefulSet README]

它提供的主要能力包括:

  • 兼容 StatefulSet 的有序身份和副本管理;
  • RollingUpdateOnDelete
  • 新增 InplaceUpdateHotPatchUpdate
  • OrderedReadyParallel 两种 Pod 管理方式;
  • Parallel 模式下并行创建、删除和更新实例;
  • 使用 partition 控制滚动、原地更新和热更新的灰度范围;
  • 自动化分步骤灰度和外部 Hook 校验;
  • PreDeleteHook;
  • HPA;
  • NodeLost 时允许配置强制删除 Terminating Pod,使替代 Pod 更快创建;
  • README 的功能列表还记录了腾讯云 CLB 有状态端口段动态转发。

与原生 StatefulSet 相比,GameStatefulSet 特别强化了并行发布、节点失联后的实例漂移,以及保持 Pod 身份时的容器级更新。

四、共同的更新机制

InplaceUpdate

InplaceUpdate 保持 Pod 生命周期和调度位置不变,只重启需要更新的容器。它适合多容器 Pod 中只更新一个容器,或希望保留 IPC 共享内存、Pod IP 和节点位置的场景。

原地更新过快时,Service Endpoints 可能还没移除 Pod,容器就已开始重启。两个 README 都使用 gracePeriodSeconds 解决这个窗口:Operator 先把 Pod 设置为 NotReady,等待 Endpoints 更新,再重启容器;完成后恢复 Ready。默认值为 0,未配置时会立即执行。

这减少了更新期间流量进入重启实例的概率,但不代表业务天然实现零损发布。Readiness、连接排空、客户端重试和应用启动行为仍需单独验证。

HotPatchUpdate

HotPatchUpdate 保持 Pod 与容器生命周期不变,替换容器对应的镜像版本;随后应用仍需通过信号、命令、reload 或进程重启加载新内容。

这是一个强环境约束能力:两份 README 都明确说明它需要 BCS 定制的 kubelet 和 dockerd,直接使用官方 Kubernetes 与 Docker 运行时不能生效。因此不能把 HotPatchUpdate 当作标准 Kubernetes 能力,也不应在普通集群中仅通过 CR 字段启用。

分步骤灰度

两个工作负载都允许在 canary.steps 中组合:

  • 更新到某个 partition;
  • 永久暂停,等待人工继续;
  • 暂停指定时间;
  • 调用外部 Hook,根据结果决定是否继续。

这种模型把发布流程从一次性字段变更扩展为可暂停、可验证的状态机,适合需要逐批观察对局、连接或业务指标的游戏服务。

PreDeleteHook

PreDeleteHook 与 bcs-hook-operator 联动,在缩容、更新或删除 Pod 前询问业务是否可以退出。如果 Hook 未返回允许,工作负载会继续等待。

它能表达“对局结束后再停服”等业务条件,但 README 没有在主页面定义 Hook 超时、失败策略和强制绕过机制。生产使用前需要检查对应 Hook 文档和实现版本,避免异常 Hook 让实例长期无法更新或删除。

五、核心差异

维度GameDeploymentGameStatefulSet
目标工作负载无状态、实例可替换有状态、实例需要稳定身份
基础实现基于 ReplicaSet Controller 改造,直接控制 Pod基于原生 StatefulSet 增强
Pod 身份不强调固定名称和顺序保留序号、稳定身份和 serviceName
更新策略Rolling、Inplace、HotPatchRolling、OnDelete、Inplace、HotPatch
批次控制partitionmaxUnavailablemaxSurgepartition 与 Pod 管理策略
并行控制通过批次参数控制Parallel 可并行创建、删除和更新
NodeLost 处理README 未列出专项能力可配置强制删除 Terminating Pod,促进重建
HPA支持支持
分步骤灰度支持支持
PreDeleteHook支持支持
HotPatch 限制依赖 BCS 定制 kubelet 与 dockerd依赖 BCS 定制 kubelet 与 dockerd

六、如何选择

优先选择 GameDeployment 的情况:

  • 实例没有稳定网络身份和本地持久状态;
  • 任一健康实例都能接替另一个实例;
  • 发布时希望使用 maxUnavailablemaxSurge 控制服务容量;
  • 业务形态接近原生 Deployment,但需要游戏灰度与退出 Hook。

优先选择 GameStatefulSet 的情况:

  • 实例需要固定名称、序号、网络身份或存储绑定;
  • 更新期间希望保留 Pod 与节点位置;
  • 业务依赖 StatefulSet 的顺序语义,或明确需要并行更新扩展;
  • 需要针对 NodeLost 的快速替代策略。

“游戏服务器”本身不足以决定选择。真正的判断标准是实例身份和状态是否可替换:房间、分区或 Dedicated Server 也可能把状态外置后采用无状态模型;普通后端服务也可能因本地数据或稳定身份而需要有状态模型。

七、风险与使用边界

  • 两个 API 都是 v1alpha1,升级前需要核对 CRD Schema、转换和兼容策略。
  • README 来自 master 分支,不代表所有已发布版本都包含相同字段和行为。
  • HotPatchUpdate 绑定定制 kubelet 与 dockerd,可能影响 Kubernetes 和容器运行时升级路径。
  • NodeLost 强制删除强调快速重建;如果失联节点上的旧进程仍在运行,需要额外防止同一逻辑实例同时服务。
  • PreDeleteHook、自动灰度和 CLB 联动依赖 BCS 其他组件,不能只安装单个 CRD 就假设完整能力可用。
  • 原地更新减少 Pod 重建,不会自动解决长连接、会话迁移、进程 reload 和应用级兼容问题。

结论

GameDeployment 和 GameStatefulSet 的共同价值,是把游戏业务中的发布、退出和故障处理知识下沉到 Kubernetes 工作负载控制器。两者的分界仍然遵循 Kubernetes 的基本模型:可替换实例使用无状态工作负载,需要稳定身份的实例使用有状态工作负载。

其中,InplaceUpdate、分步骤灰度和 PreDeleteHook 具有较普遍的工程价值;HotPatchUpdate 和 NodeLost 强制重建则带有更强的运行环境与一致性风险。采用之前,应以实际 bk-bcs 版本、依赖组件和故障测试验证 README 中的能力。