心跳&配置同步流程重构讨论 #1491
Replies: 11 comments 13 replies
-
很好的设计。我有几个想法,可以探讨一下: |
Beta Was this translation helpful? Give feedback.
-
基于这个提案设计的目标来回答
|
Beta Was this translation helpful? Give feedback.
-
第2点配置下发也是agent主动拉取,但这里需要让agent知道他什么时候来拉取配置,这也是心跳返回commands的原因 |
Beta Was this translation helpful? Give feedback.
-
update简化接口为 1. 心跳功能:1. 上报状态;2. 拉取命令 // Method: POST
// Path: /Agent/HeartBeat?agentId=<agentId>
// Header: X-Req-Id:<reqId>
message HeartBeatRequest {}
// Header: X-Req-Id:<reqId>
message HeartBeatResponse {
RespCode code = 1;
string message = 2;
repeated Command custom_commands = 3; // Optional, Agent received commands
}
// Define command
message Command {
string id = 1; // Required, Command id
string type = 2; // Required, Command type
string name = 3; // Optional, Command name
map<string, string> args = 4; // Command's parameter arrays
} 2. 通用命令命令通用接口,便于功能拓展。通过Path中的CommandType值路由到不同接口,比如:上报元信息(ReportMetadata)、同步流水线(SyncPipeline)、请求流水线(FetchPipelineConfig)、上报命令执行结果(ReportCommandResult)等。 // Method: POST
// Path: /Agent/<CommandType>?agentId=<agentId>
// Header: X-Req-Id:<reqId>
message CommandRequest {
bytes request_body = 1; // Optional, Request Body
}
// Header: X-Req-Id:<reqId>
message CommandResponse {
RespCode code = 1;
string message = 2;
bytes response_body = 3; // Optional, Response Body
} 2.1 上报元信息server下发上报(ReportMetadata)命令,agent接收到命令后,上报自身元数据
{
"id": "1",
"type": "ReportMetadata"
}
{
"agent_type":"",
"attributes":{
"version":"",
"category":"",
"ip":"",
"hostname":"",
"region":"",
"zone":"",
"extras":{}
},
"tags":[""],
"startup_time":0,
"interval":10
}
2.2 全量同步流水线server下发全量同步命令(SyncPipeline),agent接收到后上报本地流水线配置,server比较后返回检查结果。
{
"id": "1",
"type": "SyncPipeline"
}
{
"pipeline_configs": [{
"name":"",
"version":"",
"context":""
}]
}
{
"check_results": [{
"name":"",
"old_version":"",
"new_version":"",
"context":"",
"check_status":""
}]
} 2.3 增量同步流水线server下发SyncPipelineChange命令,agent根据类型决定删除/新增/更新流水线
{
"id": "1",
"type": "SyncPipelineChange"
"args":{
"<pipeline_name>": "<new/modified/deleted>",
}
}
2.4 获取流水线详细配置agent接收到新增/修改的流水线命令,会请求服务端获取详细配置
{
"pipeline_configs": [{
"name":"",
"version":"",
"context":""
}]
}
{
"pipeline_configs": [{
"name":"",
"version":"",
"context":"",
"detail":""
}]
} 2.5 同步实例配置server下发同步实例配置命令的同时也会在args中添加实例配置,agent直接同步即可。
{
"id": "1",
"type": "SyncAgentConfig",
"args":{
"name":"",
"version":"",
"context":"",
"detail":""
}
}
2.6 上报命令执行结果理论上所有的命令都应该上报结果,在命令执行失败时可以进行重试并在页面给予展示。
{
"command_results": [{
"command_id":"",
"code":0,
"message":""
}]
}
|
Beta Was this translation helpful? Give feedback.
-
running_status 在 HeartbeatRequest 中,除了表示运行中的状态,还有别的值吗?如果没有,何不把它也去掉? |
Beta Was this translation helpful? Give feedback.
-
在 leveldb 中进行时间范围查询是比较困难的,似乎免不了进行遍历操作,有没有更好办法? |
Beta Was this translation helpful? Give feedback.
-
Agent Group 中的 tags 是 AgentGroupTag 格式,建议也统一一下吧 |
Beta Was this translation helpful? Give feedback.
-
tags 字段是规划用于 Agent 分组的,两边不统一,好像没办法实行 |
Beta Was this translation helpful? Give feedback.
-
建立统一管控协议的意义AMP(Agent Management Protocol)是ConfigProvider和ConfigServer之间的通信协议,与 OneAgent 本身没有耦合关系。但协议中定义的配置能否生效,和OneAgent的能力是有关的。因此统一管控协议的主要目的有2个:
所以协议统一必须包含客户端和服务端的行为定义,而不是只定义字段。 管控协议在社区版当前协议上增强,尽量不破坏 request
response
行为规范根据一开始的讨论,管控协议只谈接口字段不谈行为规范是空谈,虽然对于管控协议来说很多客户端和服务端行为是可选或由具体客户端类型决定,但具体到OneAgent一个Agent,管控协议的行为必须是确定性的。Server端则可以由可选的行为和不同实现,此时对于这些差异OneAgent侧在实现时必须都考虑到且做好兼容。这样,OneAgent只需要实现一个CommonConfigProvider就可以受任意符合此协议规范的ConfigServer管控。 能力报告Client:应当通过capbilitiies上报Agent自身的能力,这样如果老的客户端接入新的ConfigServer,ConfigServer便知道客户端不具备某项能力,从而不会向其发送不支持的配置或命令而得不到状态汇报导致无限循环。 Server:应当通过capbilitiies上报Server自身的能力,这样如果新的客户端接入老的ConfigServer,Agent便知道服务端不具备某项能力,从而不会被其响应所误导,如其不具备记忆Attributes能力,那么Attributes字段无论如何都不应该在心跳中被省略。 注册Client:Agent启动后第一次向Server汇报全量信息,request字段应填尽填。request_id、instance_id、agent_type、startup_time、sequence_num为必填字段。 Server:Server根据上报的信息返回响应。pipeline_check_results、agent_check_results中包含agent需要同步的配置,check_results中必然包含name和new_version,是否包含详情context和detail取决于server端实现。custom_commands包含要求agent执行的命令command中必然包含type、name和expire_time。Server是否保存Client信息也取决于Server实现,如果服务端找不到或保存的sequence_num + 1 ≠ 心跳的sequence_num,那么就立刻返回并且flags中必须设置ReportFullStatus标识位。 Server根据agent_type + attributes 查询进程配置,根据ip和tags查询机器组和关联采集配置。 心跳(心跳压缩)Client:若接收到的响应中没有ReportFullStatus,且client的属性、配置状态、命令状态在上次上报后没有变化,那么可以只填instance_id、sequence_num,sequence_num每次请求+1。若有ReportStatus或任何属性、配置状态变化或Server不支持属性、配置状态记忆能力,则必须完整上报状态。 Server:同注册 允许心跳压缩 不允许心跳压缩 进程配置若Server的注册/心跳响应中有agent_check_results.detail Client:直接从response中获得detail,应用成功后下次心跳需要上报完整状态。 若Server的响应不包含detail Client:根据agent_check_results的信息构造FetchProcessConfigRequest(原FetchAgentConfigRequest) Server:返回FetchProcessConfigResponse(原FetchAgentConfigResponse) Client获取到多个进程配置时,根据层级关系合并,范围越小优先级越高。 采集配置若Server的注册/心跳响应中有pipeline_check_results.detail Client:直接从response中获得detail,应用成功后下次心跳需要上报完整状态。 若Server的响应不包含detail Client:根据agent_check_results的信息构造FetchPipelineConfigRequest Server:返回FetchPipelineConfigResponse 客户端支持以下2种实现 实现1:直接将Detail返回在心跳响应中(FetchConfigDetail flag is unset) 实现2:仅返回配置名和版本,Detail使用单独请求获取(FetchConfigDetail flag is set) 配置状态上报Client:这个版本的配置状态上报中修改了version的定义,-1仍然表示删除,0作为保留值,其他值都是合法version,只要version不同Client都应该视为配置更新。此外参考OpAMP增加了配置应用状态上报的字段,能反应出下发的配置是否生效。 Server:这些信息是Agent状态的一部分,可选保存。与通过Event上报可观测信息不同的是,作为状态信息没有时间属性,用户可通过接口可获取即刻状态,而不需要选择时间窗口合并事件。 预定义命令Client: 通过request的flag传递,尚未定义 Server: 通过response的flag传递,定义了ReportFullStatus 自定义命令Client: 为了防止服务端重复下发命令以及感知命令执行结果,在command expire前,Client始终应具备向服务端上报command执行状态的能力,实际是否上报取决于心跳压缩机制。在expire_time超过后,client不应该再上报超时的command状态。 Server: 如果上报+已知的Agent状态中,缺少应下发的custom_commands(通过name识别),那么server应该在响应中下发缺少的custom_commands。 Config的消费和反馈当前CommonConfigProvider的工作结果仅仅是将配置序列化保存到本地,后续的使用通过ConfigWatcher对配置进行对比然后提供下游消费使用的,此外也没有机制反馈配置的生效情况。在新写一下,前者需要扩展而后者需要新的类来负责。 ConfigWatcherConfigWatcher会比对新老配置并将配置更新通知给后面的PipelineManager。PipelineManager负责实际应用这些配置。 有了ProcessConfig和自定义命令后
故,ConfigWatcher的职责需要扩展:
ConfigFeedbackReceiver新增ConfigFeedbackReceiver类,这个类负责将对应Config或Command的执行结果反馈给对应的Provider。
CommonConfigProvider自定义扩展需求
为实现需求1,新增GetInstanceId可扩展接口,子类可重载。 为实现需求2,新增FetchConfig接口,入参为HbResponse,出参为processConfigs和pipelineConfigs,默认实现为如果响应中没有FetchXxxConfigDetail flag,那么直接从HbResponse中获取processConfigs和pipelineConfigs的detail,如果有,则调用FetchConfig接口从HbResponse中获取信息拼接网络请求,请求后返回出参。FetchConfig也是一个新增可扩展接口,默认实现为向开源版ConfigServer请求。 为实现需求3,新增GetAgentAttributes接口,入参和出参为同一个map,传入上次的attributes。默认实现为填充os/version信息,从本地全局配置加载attributes。 为实现需求4,CommonConfigProvider负责Pb协议字段填充,但预留SendHeartbeat和FetchConfig接口,默认实现为使用curl向开源版ConfigServer发同步请求。 为实现需求5,新增了FeedbackProcessConfigStatus、FeedbackPipelineConfigStatus、FeedbackCommandStatus方法。当配置应用或命令执行结束后,都应该调用ConfigFeedbackReceiver进行反馈,然后ConfigFeedbackReceiver再通过映射反馈给实际Provider。 |
Beta Was this translation helpful? Give feedback.
-
请问配置同步功能是否可以支持在ilogtail agent启动的时候指定一些环境变量的key,然后将key与环境变量的值作为一组label上传到config server,config server可以通过这些key对group进行管控? |
Beta Was this translation helpful? Give feedback.
-
根据最近提交的代码和review意见,发现process_config这个名词歧义很大,可能被理解为进程配置,也可能被理解为流程配置、处理配置,此外和ebpf代码中ProcessConfig结构体混淆。故打算将process_config全部替换为instance_config来减少歧义。 |
Beta Was this translation helpful? Give feedback.
-
背景
基于 #1481 ,对目前的心跳&配置同步流程做了简单设计。
总体设计
计划整体拆分成两个主要的接口:注册与心跳。注册接口用于确认连通性并上报基础元信息;心跳接口用于上报状态与接收命令。后续功能拓展都可以通过命令类型来执行不同的操作。
通信设计
接口设计
1. 注册
注册是agent与server通信的开始。注册会做一次本地配置、本地流水线与server端的全量同步。
2. 心跳
心跳主要功能:1. 上报Agent运行状态;2. 拉取需要执行的命令;
3. 流水线同步
server端会在 1. agent上线;2. 定期同步;时生成全量流水线/实例配置同步的command。通知agent上报本地配置与server做对比。
4. 获取流水线详细配置
保持不变
5. 获取Agent配置
保持不变
6. 命令执行结果上报
agent在执行命令后,需要将结果通知给server。
Command设计
特殊情况
接口兼容
总结
存在问题
欢迎讨论
Beta Was this translation helpful? Give feedback.
All reactions