容器发布的分组调度实现

背景

分组发布,分组发完会暂停

Etcd 关键路径

cmdKey /cronsun/cmd/NODEID/JOBID:

原始发布信息

groupKey /cronsun/containergroup/NODEID/JOBID/GROUPSTRING

分组的调度,GROUPSTRING 命名格式:包含 GROUPID-IDC-NUM,数据是状态

stageKey /cronsun/containerdeploy/NODEID/JOBID/HOSTNAME:

整体发布和每台机器的调度,/cronsun/containerdeploy/NODEID/JOBID 保存整体任务状态,HOSTNAME 保存每个容器状态

logKey /cronsun/containerlog/NODEID/JOBID/HOSTNAME

记录日志

过程

1、监听 cmdKey;

2、从 cmdKey 获取发布信息,修改 stageKey 整体发布和 groupKey 的一个分组设置成 Running,开始发布;

3、监听 groupKey,(通过内部 channel 传递)获取 Running 的分组,写入分组机器 Running 状态到 stageKey(有机房间并发和机房内并发控制);

4、客户端监听 stageKey,获取本机 Running 状态,开始执行。

5、客户端执行完成,上报 stageKey;

6、监听 stageKey,分组是否执行成功;

7、如果执行成功,设置 stageKey 整体发布为 Pause;

8、等待 continue 的指令;

9、通过修改 stageKey 和 groupKey 实现继续的指令(stageKey 整体发布和 groupKey 的一个分组设置成 Running);

10、回到 3。

核心逻辑描述

/cronsun/containerdeploy/NODEID/JOBID 和 /cronsun/containercmd/NODEID/JOBID/GROUPSTRING 被设置成 Running 状态后,调用 K8S 分布分组,当分组容器被发布完成后,回调 API,写入 /cronsun/containerdeploy/NODEID/JOBID/HOSTNAME,调度器判断成功的数量是否等于分组的数量,如果是,则设置暂停,如果不是,则标记失败。

发布一个分组的逻辑:
创建一个新的 Deployment,命名格式:ServiceName-timestamp,并获取当前以 ServiceName 开头的 Deployment:[ServiceName-t1、ServiceName-t2],ServiceName-timestamp 每发布一个分组,就从 [ServiceName-t1、ServiceName-t2] 减去这个分组的数量,最终删除 [ServiceName-t1、ServiceName-t2]。

k8s 分组发布的实现

分组发布的实现:

1、创建新的 Deployment,实例数量是第一个分组的数量,apply;

2、修改当前的 Deployment,实例数量减去第一个分组的数量,apply;

3、修改新的 Deployment ,加上第二个分组的数量,apply;

4、修改当前的 Deployment,减去第二个分组的数量,apply;

5、剩下的分组依次进行;

6、最终新的 Deployment 为线上,删掉之前的 Deployment。

因为 Deployment 名称不让修改,无法一直保持一个名称,可以把名称带上时间戳后缀。

通用集群发布设计

核心概念

1、服务:我们把相同程序(二进制)产生的进程集合叫做服务,是一个比较大的概念;
2、模板:发布用的通用配置,包括:运行目录、包构建信息、目标目录、前置命令、停止命令、启动命令、后置命令、并发度、超时时间等等;
3、集群:就是普通集群的概念,比如 etcd 集群、ES 集群、pxc 集群等;
4、实例:集群中的一个进程;
5、机房:机器所属的机房;
6、分组:包含若干个实例,用于分批发布;
7、KV:Key-Value 对,用于渲染配置文件;
8、配置:特指 ansible yml 文件,用于配置环境,包括创建目录、渲染配置文件到目标目录等。

关联关系

1、一个服务的程序可以发布出 N 个集群;
2、服务的模板应用于服务关联的所有集群;
3、一个服务可以定义若干个 KV 和配置,并被应用于所有集群的所有实例;
4、对于每个集群,可以自定义 KV 和配置,优先级高于服务级别的 KV 和配置;
5、对于每个实例,可以自定义 KV 和配置,优先级高于集群级别的 KV 和配置;
6、对于每个集群,可以定义分组,比如 0、1、2;
7、发布时一个分组发布完成后,会暂停;
8、机房是用于控制并发度的:同时发布的机房数量;
9、关于并发度,发布一个服务,服务对应多个集群,集群对应多个实例,所以支持:
1)、集群间并发度:同时发布几个集群;
2)、对于一个集群,一个一个分组发,串行;
3)、机房间并发度:对于一个分组,同时发布几个机房(中的实例),如果并发度是 1,就一个机房一个机房发;
4)、服务器并发度:对于一个分组里每个机房里的机器设置的并发度。

其他

1、模板里面有启动命令,但是每个集群的进程名不能一样,这个问题怎么解决?
模板支持使用 {{ process_name }} 这种语法,启动前先渲染成真正的命令。
process_name 则可以在集群 KV 中定义。