关于腾讯云:腾讯游戏-K8s-应用实践|更贴近业务场景的-K8s-工作负载GameDeployment-GameStatefulSet

38次阅读

共计 12883 个字符,预计需要花费 33 分钟才能阅读完成。

引言

蓝鲸容器服务(Blueking Container Service,以下简称 BCS)是腾讯 IEG 互动娱乐事业群的容器上云平台,底层基于腾讯云容器服务(Tencent Kubernetes Engine, TKE),为 IEG 的自研游戏业务上云提供容器化和微服务化的建设工作。区别于个别互联网业务,腾讯游戏业务具备大规模、低时延、网络敏感、超高可靠性要求等一系列泛滥特点,大量应用共享内存通信等技术,对云原生上云是一个微小的挑战。BCS 在服务于各游戏业务的容器上云过程中,联合业务需要与社区计划,开发了两个增强版的 Kubernetes 工作负载 operator:GameStatefulSet 和 GameDeployment,更贴近业务场景,满足简单多样的容器上云需要。

游戏业务个性的复杂性

游戏类业务具备多种类型,如房间类游戏、MMO 游戏。无论是哪种类型的游戏,都有诸如大规模的在线玩家、对网络时延和抖动异样敏感、多区多服等特点,游戏后盾服务在设计时为了满足这些需要,人造地会谋求实时高速通信、性能最大化,大量地应用了过程间共享内存通信、数据预加载进内存、跨主机 TCP 通信等技术,极少应用近程数据、RPC,这其实与微服务的要求有点南辕北辙。
联合容器化上云的需要,总结来说,游戏类服务个别具备以下个性:

  • 大量地应用共享内存技术,偏有状态服务。
  • 超大规模,分辨别服,须要能做到分批灰度公布,为缩小运维难度,最好能实现智能式管制,管制公布规模、速度、步骤。
  • 实例扩缩容或更新时须要进行数据搬迁,不能马上退出服务。
  • 缩容一个实例前,须要先实现路由变更。如微服务名字通信网格,在缩容一个实例前先要跟名字通信网格的 controller 进行交互,确认是否已实现路由变更,再决定是否删除实例。
  • 开房间对局类游戏在缩容或更新前,须要期待实例上的所有对局完结后,再退出服务。
  • 为了保障平滑降级,有些游戏后盾服务应用了过程 reload 技术,reload 过程中新版本的过程接替旧版本的过程提供服务,内存数据不失落,降级过程中玩家无感知。

所有这些特点,对于 Kubernetes 和云原生上云都是微小的挑战。Kubernetes 原生适宜微服务架构,把所有实例当作家畜而不是宠物。即使是推出了 StatefulSet(最开始起名为 PetSet) 来反对有状态服务,也只是给每个实例设定一个网络和存储的编号,即便实例挂了,拉起一个雷同编号的实例代替即可,并不波及到共享内存失落、数据搬迁、路由变更等简单的流程。这也是起初 PetSet 被改名为 StatefulSet 的起因。
要反对游戏这类简单业务的上云,咱们须要更进一步,开发更贴合业务场景的 workload,升高业务接入的门槛和老本。

BCS New Workload: GameDeployment & GameStatefulSet

BCS 在服务于腾讯 IEG 泛滥不同类型的包含但不限于游戏业务的容器上云过程中,与各游戏业务及平台探讨业务场景,形象业务共性和需要,同时踊跃学习和借鉴云原生社区的优良开源我的项目如 OpenKruise,argo-rollouts,flagger 等,在 Kubernetes 原生及其它开源我的项目的根底上,研发了 bcs-gamedeployment-operator 和 bcs-gamestatefulset-operator 两个 operator,别离对应 GameDeployment 和 GameStatefulSet 两个增强版的 Kubernetes 工作负载,在原生的 Deployment 和 StatefulSet 根底上实现了一系列加强的个性和性能晋升,以满足简单业务的云原生上云需要。
GameDeployment 和 GameStatefulSet 尽管是在服务于游戏业务的的场景中产生,但咱们为其形象进去的个性,其实能符合大多数类型业务特地是简单业务的需要,更强的可控性,更贴近业务的研发和运维公布场景,能极大晋升云原生上云的能力。

GameDeployment

Kubernetes 原生的 Deployment 是面向无状态服务的工作负载,其底层是基于 ReplicaSet 来实现,一个 Deployment 通过管制底层多个版本的 ReplicaSet 的版本数量来实现利用的滚动更新和回滚。
尽管是无状态服务,大多数利用仍有 pod 原地降级、pod 镜像热更新 (下文独自) 等其它一些需要,而原生的 Deployment 因为是基于多个版本的 ReplicaSet 迭代来实现,实现较为简单,想要在其中增加原地降级等性能比拟艰难。
咱们在借鉴原生的 Deployment 和 StatefulSet 的代码实现的根底上,参考了其它开源我的项目,研发实现了一个增强版的 Deployment: GameDeployment,以满足简单的无状态利用的更多高阶需要。
相比 Deployment,GameDeployment 具备以下一些外围个性:

  • 反对滚动更新 RollingUpdate。
  • 反对 pod 原地降级
  • 反对 pod 容器镜像热更新
  • 反对 partition 灰度公布
  • 反对智能式分步骤灰度公布,可在灰度公布步骤中退出 hook 校验
  • 反对删除或更新 pod 前的 hook 校验,以实现优雅的 pod 退出
  • 反对原地重启前的镜像预拉取,以放慢原地重启的速度
apiVersion: tkex.tencent.com/v1alpha1
kind: GameDeployment
metadata:
  name: test-gamedeployment
  labels:
    app: test-gamedeployment
spec:
  replicas: 5
  selector:
    matchLabels:
      app: test-gamedeployment
  template:
    metadata:
      labels:
        app: test-gamedeployment
    spec:
      containers:
      - name: python
        image: python:3.5
        imagePullPolicy: IfNotPresent
        command: ["python"]
        args: ["-m", "http.server", "8000"]
        ports:
        - name: http
          containerPort: 8000
  preDeleteUpdateStrategy:
    hook:
      templateName: test
  updateStrategy:
    type: InplaceUpdate
    partition: 1
    maxUnavailable: 2
    canary:
      steps:
        - partition: 3
        - pause: {}
        - partition: 1
        - pause: {duration: 60}
        - hook:
            templateName: test
        - pause: {}
    inPlaceUpdateStrategy:
      gracePeriodSeconds: 30

以上是一个示例的 GameDeployment yaml 配置,与 Deployment 的配置差异不大,大部分继承 Deployment 的参数含意。咱们将一一介绍不同或新增之处:

  • updateStrategy/type
    更新类型,反对 RollingUpdate(滚动更新),InplaceUpdate(原地降级),HotPatchUpdate(镜像热更新)三种更新策略。RollingUpdate 与 Deployment 的定义雷同,下文咱们将独自介绍 InplaceUpdate 和 HotPatchUpdate。
  • updateStrategy/partition
    相比 Deployment 新增的参数,用于实现灰度公布,含意同 StatefulSet 的 partition。
  • updateStrategy/maxUnavailable
    指在更新过程中每批执行更新的实例数量,在更新过程中这批实例是不可用的。比方一共有 8 个实例,maxUnavailable 设置为 2,那么每批滚动或原地重启 2 个实例,等这 2 个实例更新实现后,再进行下一批更新。可设置为整数值或百分比,默认值为 25%。
  • updateStrategy/maxSurge
    在滚动更新过程中,如果每批都是先删除 maxUnavailable 数量的旧版本 pod 数,再新建新版本的 pod 数,那么在整个更新过程中,总共只有 replicas – maxUnavailable 数量的实例数可能提供服务。在总实例数较小的状况下,会影响利用的服务能力。设置 maxSurge 后,会在滚动更新前先多创立 maxSurge 数量的 pod,而后再逐批进行更新,所有实例更新完后再删掉 maxSurge 数量的 pod,这样就能保障整个更新过程中可服务的总实例数量。
    maxSurge 默认值为 0。
    因 InplaceUpdate 和 HotPatchUpdate 不会重启 pod,因而倡议在这两种更新策略的状况下无需设置 maxSurge 参数,只在 RollingUpdate 更新时设置。
  • updateStrategy/inPlaceUpdateStrategy
    原地降级时的 gracePeriodSeconds 工夫,详见下文“InplaceUpdate 原地降级”的介绍。
  • updateStrategy/canary
    定义分批灰度公布的步骤,详见下文“自动化分步骤灰度公布”。
  • preDeleteUpdateStrategy
    删除或更新前 pod 前的 hook 策略,实现优雅地退出 pod。详见下文“PreDeleteHook:优雅地删除和更新 Pod”。

GameStatefulSet

Kubernetes 原生的 StatefulSet 是面向有状态利用的工作负载,每个利用实例都有一个独自的网络和存储编号,实例在更新和缩容时是有序进行的。StatefulSet
为了面对上文形容的一些更为简单的有状态利用的需要,咱们在原生的 StatefulSet 的根底上,开发实现了加强版本:GameStatefulSet。
相比 StatefulSet, GameStatefulSet 次要蕴含以下新增个性:

  • 反对 pod 原地降级
  • 反对 pod 容器镜像热更新
  • 反对并行更新,以晋升更新 (包含滚动更新、原地降级和镜像热更新) 速度
  • 反对智能式分步骤灰度公布,可在灰度公布步骤中退出 hook 校验
  • 反对删除或更新 pod 前的 hook 校验,以实现优雅的 pod 退出
  • 反对原地重启前的镜像预拉取,以放慢原地重启的速度
apiVersion: tkex.tencent.com/v1alpha1
kind: GameStatefulSet
metadata:
  name: test-gamestatefulset
spec:
  serviceName: "test"
  podManagementPolicy: Parallel
  replicas: 5
  selector:
    matchLabels:
      app: test
  preDeleteUpdateStrategy:
    hook:
      templateName: test
  updateStrategy:
    type: InplaceUpdate
    rollingUpdate:
      partition: 1
    inPlaceUpdateStrategy:
      gracePeriodSeconds: 30
    canary:
      steps:
      - partition: 3
      - pause: {}
      - partition: 1
      - pause: {duration: 60}
      - hook:
          templateName: test
      - pause: {}
  template:
    metadata:
      labels:
        app: test
    spec:
      containers:
      - name: python
        image: python:latest
        imagePullPolicy: IfNotPresent
        command: ["python"]
        args: ["-m", "http.server", "8000"]
        ports:
        - name: http
          containerPort: 8000

以上是一个 GameStatefulSet 的 yaml 示例,相干参数介绍如下:

  • podManagementPolicy
    反对 “OrderedReady” 和 “Parallel” 两种形式,定义和 StatefulSet 统一,默认为 OrderedReady。与 StatefulSet 不同的是,如果配置为 Parallel,
    那么不仅实例扩缩容是并行的,实例更新也是并行的,即主动并行更新。
  • updateStrategy/type
    反对 RollingUpdate, OnDelete, InplaceUpdate, HotPatchUpdate 四种更新形式,相比原生 StatefulSet, 新增 InplaceUpdate, HotPatchUpdate 两种更新模式。
  • updateStrategy/rollingUpdate/partition
    管制灰度公布的数量,与 StatefulSet 含意统一。为了兼容,InplaceUpdate 和 HotPatchUpdate 的灰度公布数量也由这个参数配置。
  • updateStrategy/inPlaceUpdateStrategy
    原地降级时的 gracePeriodSeconds 工夫,详见下文“InplaceUpdate 原地降级”的介绍。
  • updateStrategy/canary
    定义分批灰度公布的步骤,详见下文“智能式分步骤灰度公布”。
  • preDeleteUpdateStrategy
    删除或更新前 pod 前的 hook 策略,实现优雅地退出 pod。详见下文“PreDeleteHook:优雅地删除和更新 Pod”。

性能个性与场景笼罩

原地降级 InplaceUpdate

GameDeployment 和 GameStatefulSet 都反对 InplaceUpdate 更新策略。
原地降级是指,在更新 pod 版本时,放弃 pod 的生命周期不变,只重启 pod 中的一个或多个容器,因此在降级期间,pod 的共享内存 IPC 等能放弃不失落。应用原地降级的实例更新形式,有以下收益:

  • pod 中有多个容器,容器之间通过共享内存通信。降级期间望放弃 pod 生命周期,只更新其中局部容器,IPC 共享内存不失落,更新实现后 pod 持续提供服务。
  • 原生的滚动降级更新策略须要一一或分批的删掉旧版本实例,再创立新版本实例,效率很低。应用原地降级的形式,不须要重建 pod 实例,能大为晋升公布更新的速度。

Kubernetes 原生的 Deployment 和 StatefulSet 等工作负载都没有间接反对原地降级的更新形式,但 kubelet 组件暗藏地反对了这一能力。针对一个处于 running 状态的 Pod,咱们只须要通过 patch 的形式更新 pod spec 中的 image 版本,kubelet 监控到了这一变动后,就会主动地杀掉对应的旧版本镜像的容器并拉起一个新版本镜像的容器,即实现了 Pod 的原地降级。
咱们通过 ReadinessGate 和 inPlaceUpdateStrategy/gracePeriodSeconds 的联合,来实现原地降级当中的流量服务的平滑切换。

原地降级的更新策略下,能够配置 spec/updateStrategy/inPlaceUpdateStrategy/gracePeriodSeconds 参数,假如配置为 30 秒,那么 GameStatefulSet/GameDeployment 在原地更新一个 pod 前,会通过 ReadinessGate 先把这个 pod 设置为 unready 状态,30 秒过后才会真正去原地重启 pod 中的容器。这样,在这 30 秒的工夫内因为 pod 变为 unready 状态,k8s 会把该 pod 实例从 service 的 endpoints 中剔除。等原地降级胜利后,GameStatefulSet/GameDeployment 再把该 pod 设为 ready 状态,之后 k8s 才会从新把该 pod
实例退出到 service 的 endpoints 当中。
通过这样的逻辑,在整个原地降级过程中,能保障服务流量的无损。
gracePeriodSeconds 的默认值为 0,当为 0 时,GameStatefulSet/GameDeployment 会立即原地降级 pod 中的容器,可能会导致服务流量的失落。
InplaceUpdate 同样反对灰度公布 partition 配置,用于配置灰度公布的比例。

GameDeployment InplaceUpdate 应用示例
GameStatefulSet InplaceUpdate 应用示例

容器镜像热更新 HotPatchUpdate

原地降级更新策略尽管能放弃 pod 的生命周期和 IPC 共享内存,但始终是要重启容器的。对于游戏对局类的 GameServer 容器,如有玩家正在进行对局服务,原地降级 GameServer 容器会中断玩家的服务。
有些业务为了实现不停服更新,应用了服务过程 reload 技术,reload 过程中新版本的过程接替旧版本的过程提供服务,内存数据不失落,降级过程中玩家无感知。
为了满足这类业务的容器上云需要,咱们调研了 docker 镜像 merge 的增量更新策略,批改 docker 源码减少了一个容器镜像热更新的接口。在对一个运行着的容器调用镜像热更新接口进行镜像版本的更新时,容器的生命周期不变,容器内的过程也放弃不变,但容器的根底镜像会替换为新的版本。
通过对 docker 的这种改变,对一个运行状态的容器进行镜像热更新后,容器状态不变,但其根底镜像的版本及数据已实现了增量更新。如果容器中的过程实现了 reload 性能,而根底镜像中的 so 文件或配置都已更新为新版本,此时只须要往容器中的过程发送 reload 信号,就能实现服务过程的热更新,实现不停服降级。
为了在 Kubernetes 中实现容器镜像热更新的能力,咱们批改了 kubelet 的代码,在 kubelet 原地降级能力的根底上,当 pod 中加了指定的 annotation 时,kubelet 对 pod 的更新就会从原地降级操作变为容器镜像热更新操作,调用 docker 的镜像热更新接口实现容器的镜像热更新。
对于在 docker 和 kubelet 上对容器镜像热更新的具体实现,咱们后续将在另外的文章中具体论述。

GameStatefulSet/GameDeployment 集成了容器镜像热更新的性能,当把 spec/updateStrategy/type 配置为 HotPatchUpdate 时,就会通过更新 pod 中的容器镜像版本并增加 annotation 的形式,联动 kubelet 和 docker 实现容器镜像热更新的性能。在整个过程中,pod 及其容器的生命周期都是没有变动的,尔后,用户能够通过向容器中过程发送信号的形式,实现业务过程的 reload,保障服务的不中断。
HotPatchUpdate 同样反对灰度公布 partition 配置,用于配置灰度公布的比例。

HotPatchUpdate 的更新策略须要联合咱们定制化的 kubelet 和 docker 版本能力失效。
GameDeployment HotPatchUpdate 应用示例
GameStatefulSet HotPatchUpdate 应用示例

基于 hook 的利用交互式公布

上文中咱们提到,少数简单类利用在公布更新过程中有许多内部依赖或利用自身的数据指标依赖,如下面咱们提到的:实例扩缩容或更新前须要进行数据搬迁;缩容一个实例前须要先实现路由变更;实例缩容或更新前须要期待游戏对局完结。此外,在灰度公布时,有时咱们须要从 Prometheus 监控数据中查看指标是否合乎预期,以决定是否持续灰度更多的实例。
这其实能够看作为利用公布过程中的各种 hook 勾子,通过 hook 的后果来判断是否能够持续下一步的公布流程。无论是面向无状态利用的 GameDeployment 还是面向有状态利用的 GameStatefulSet,都有这种公布需要。
咱们在粗浅开掘业务需要和调研解决方案后,在 Kubernetes 层面形象出了一个通用的 operator: bcs-hook-operator。
bcs-hook-operator 主要职责是依据 hook 模板执行 hook 操作并记录 hook 的状态,GameDeployment 或 GameStatefulSet watch hook 的最终状态,依据 hook 后果来决定下一步执行何种操作。

bcs-hook-operator 定义了两种 CRD:

  • HookTemplate
apiVersion: tkex.tencent.com/v1alpha1
kind: HookTemplate
metadata:
  name: test
spec:
  args:  
    - name: service-name
      value: test-gamedeployment-svc.default.svc.cluster.local
    - name: PodName
  metrics:
  - name: webtest
    count: 2
    interval: 60s
    failureLimit: 0
    successCondition: "asInt(result) < 30"
    provider:
      web:
        url: http://1.1.1.1:9091
        jsonPath: "{$.age}"

HookTemplate 用来定义一个 hook 的模板。在一个 HookTemplate 中能够定义多个 metric,每个 metric 都是须要执行的一个 hook。在 metric 中能够定义 hook 的次数、两次之间的距离、胜利的条件、provider 等等多个参数。provider 定义的是 hook 的类型,目前反对两种类型的 hook:webhook 和 prometheus。

  • HookRun
apiVersion: tkex.tencent.com/v1alpha1
kind: HookRun
metadata:
  name: test-gamedeployment-67864c6f65-4-test
  namespace: default
spec:
  metrics:
  - name: webtest
    provider:
      web:
        jsonPath: '{$.age}'
        url: http://1.1.1.1:9091
    successCondition: asInt(result) < 30
  terminate: true
status:
  metricResults:
  - count: 1
    failed: 1
    measurements:
    - finishedAt: "2020-11-09T10:08:49Z"
      phase: Failed
      startedAt: "2020-11-09T10:08:49Z"
      value: "32"
    name: webtest
    phase: Failed
  phase: Failed
  startedAt: "2020-11-09T10:08:49Z"

HookRun 是依据模板 HookTemplate 创立的一个理论运行的 hook CRD,bcs-hook-operator 监测并管制 HookRun 的运行状态和生命周期,依据其 metrics 中的定义来执行 hook 操作,并实时记录 hook 调用的后果。
对于 bcs-hook-operator 的更具体介绍可参考:bcs-hook-operator

GameDeployment/GameStatefulSet 与 bcs-hook-operator 在利用公布过程中应用 hook 时的交互架构图:

自动化分步骤灰度公布

GameDeployment & GameStatefulSet 反对智能化的分步骤分批灰度公布性能,容许用户配置灰度公布的自动化步骤,通过配置多个灰度公布步骤,达到分批公布的目标,主动监测公布的成果,实现灰度公布的智能化管制。
以后,能够在灰度公布步骤中配置以下 4 种步骤:

  • 灰度的实例个数,用 partition 来指定
  • 永恒暂停灰度,除非用户手动触发持续后续步骤
  • 暂停指定的工夫后再持续后续步骤
  • Hook 调用,templateName 指定要应用的 HookTemplate,该 HookTemplate 必须曾经在集群中创立。
    GameDeployment&GameStatefulSet 会依据 HookTemplate 创立 HookRun,bcs-hook-operator 操纵并执行 HookRun。GameDeployment&GameStatefulSet watch HookRun 的状态,如果后果满足预期,则继续执行后续的灰度步骤,如果返回后果不满足预期,则暂停灰度公布,必须由人工染指来决定是持续后续灰度步骤还是进行回滚操作。
    上面的示例中,定义了灰度公布的 6 个步骤:
...
spec:
  ...
  updateStrategy:
    type: InplaceUpdate
    rollingUpdate:
      partition: 1
    inPlaceUpdateStrategy:
      gracePeriodSeconds: 30
    canary:
      steps:
      - partition: 3            # 该批灰度公布的个数
      - pause: {}               # 暂停公布 
      - partition: 1            # 该批灰度公布的个数
      - pause: {duration: 60}   # 暂停 60 秒后再持续公布
      - hook:                   # 定义 hook 步骤
          templateName: test    # 应用名为 test 的 HookTemplate 
      - pause: {}               # 暂停公布
 ...

在 GameDeployment 和 GameStatefulSet 上进行智能式分步骤灰度公布的配置和应用形式基本一致,具体应用教程可参考:智能式分步骤灰度公布教程

PreDeleteHook:优雅地删除和更新 Pod

在上文“基于 hook 的利用交互式公布”章节咱们提到,利用在公布更新过程中有许多内部依赖或利用自身的数据指标依赖。特地是在缩容实例或降级实例版本时,须要删掉旧版本的实例,但往往实例上依然有服务不能中断,如有玩家在进行游戏对战。此时,实例的缩容或更新是有依赖的,不能马上进行缩容或更新,须要查问条件,当条件满足后再进行缩容或更新。
咱们依据 bcs-hook-operator 的形象,在 GameDeployment 和 GameStatefulSet 上开发了 PreDeleteHook 的性能,实现优雅地删除和更新利用 Pod 实例。

apiVersion: tkex.tencent.com/v1alpha1
...
spec:
  preDeleteUpdateStrategy:     
    hook:
      templateName: test        # 应用的 HookTemplate
  updateStrategy:
    ...
    inPlaceUpdateStrategy:
      gracePeriodSeconds: 30

在 GameDeployment/GameStatefulSet 的 spec/preDeleteUpdateStrategy 中指定 HookTemplate,那么当缩容或更新 Pod 实例时,针对每一个待删除或更新的 Pod,GameDeployment/GameStatefulSet 都会依据 HookTemplate 模板创立一个 HookRun,而后 watch 这个 HookRun 的状态。bcs-hook-operator 管制 HookRun 的运行并实时记录其状态。当 HookRun 运行实现后,GameDeployment/GameStatefulSet watch 到其最终状态,根据其最终状态来决定是否能失常删除或更新 Pod。

更进一步地,咱们在 HookTemplate 和 HookRun 中反对了一些常见参数的主动渲染,如 PodName, PodNamespace, PodIP 等。
例如,假如 PreDeleteHook 中须要运行的 hook 是利用实例自身的一个 http 接口,裸露在容器的 8080 端口,那么咱们能够定义这样一个 HookTemplate:

apiVersion: tkex.tencent.com/v1alpha1
kind: HookTemplate
metadata:
  name: test
spec:
  args:
    - name: PodIP
  metrics:
    - name: webtest
      count: 3
      interval: 60s
      failureLimit: 2
      successCondition: "asInt(result) > 30"
      provider:
        web:
          url: http://{{args.PodIP}}:8080
          jsonPath: "{$.age}"

这样,GameDeployment/GameStatefulSet 在针对待删除或更新的 Pod 创立 HookRun 时,会把 Pod IP 渲染进 webhook url 中,最终创立和执行的是对利用 Pod 自身提供的 http 接口的 webhook 调用。

在 GameDeployment 和 GameStatefulSet 上进行 PreDeleteHook 的配置和应用形式基本一致,具体应用教程可参考:PreDeleteHook:优雅地删除和更新 Pod

镜像预热

应用 Pod 原地降级是为了最大水平上晋升公布的效率,并缩小服务中断的工夫。但一个 Pod 的原地降级过程中,最大的工夫耗费在于拉取新版本镜像的工夫,特地是当镜像很大的时候。
因而,业务在应用原地降级的过程中,向咱们反馈的最多的问题就是原地降级的速度依然过慢,与现实中的速度有差距。
基于此,咱们与欢畅游戏工作室的公共反对团队单干共建了 GameStatefulSet&GameDeployment 的原地降级镜像预热计划。
以 GameDeployment 为例,镜像预热计划的流程架构如下图所示:

  • 1 . 用户触发 GameDeployment 原地降级。
  • 2 . kube-apiserver 通过 admission webhook 拦挡到申请,交由 bcs-webhook-server 解决。
  • 3 . bcs-webhook-server 判断为用户触发原地降级,批改 GameDeployment 的内容,把镜像版本 patch 为原来版本,并在 annotations 中减少一个新版本镜像的 patch。
  • 4 . bcs-webhook-server 应用新版本的镜像在所有运行有这个利用实例的节点上创立一个 Job,并 watch 这些 Job 的状态。Job 运行时就会拉取新版本的镜像。
  • 5 . bcs-webhook-server 监测到所有 Job 运行后果后,批改 GameDeployment 的内容,把 annotations 中的新版本镜像的 patch 删除,并把镜像版本 patch 为新版本的镜像,触发真正的原地降级。而后,革除掉运行实现的 Job。
  • 6 . bcs-gamedeployment-operator watch 到真正的原地降级后,执行原地降级的更新策略。

应用这个计划,能保障 Kubernetes 工作负载 GameDeployment&GameStatefulSet 与镜像预热计划的解耦,假如要反对更多的 Kubernetes 工作负载的镜像预热,只须要在 bcs-webhook-server 上增加对这个工作负载 CRD 的反对即可。
基于此,咱们重构开发了 bcs-webhook-server,反对以插件化的形式增加 webhook:

镜像预热计划及 bcs-webhook-server 的更多实现细节,请参考:bcs-webhook-server

总结

BCS 团队在基于 TKE 构建云原生上云平台的过程中,与不同业务团队进行探讨,开掘业务需要,形象需要共性,并联合社区的开源计划,研发了 GameDeployment 和 GameStatefulSet 这两个 Kubernetes 工作负载。这两个工作负载及其个性尽管是为简单的游戏业务上云而产生,但根本能笼罩大多数互联网业务的需要,更贴近各种业务的运维和公布场景。
后续,咱们也将持续与各业务团队进行探讨和单干,形象更多需要个性,一直迭代,继续加强 GameStatefulSet 和 GameDeployment 的能力。
蓝鲸容器服务 BCS 曾经开源,更多容器上云计划和细节请参考咱们的开源我的项目:BK-BCS

感激以下合作开发者 Committer

  • stonewesley
  • pang1567

【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!

正文完
 0