牧场主事件机制及其实践指南

我们的牧场主官方技术社区已经创立些许时日了,相信通过我们的线下聚会和线上布道工作,很多朋友对农场主的使用已经掌握得很纯熟了。一些高级用户开始真正把自己的业务进行微服务化并向牧场主迁移,在迁移的过程中,由于业务本身的复杂性特殊性,可能需要利用牧场主的一些高级特性甚至要对牧场主进行一定的扩展,这就需要对牧场的一些组件的实现机制有些许了解。

,

本次分享就介绍一下牧场主的事件机制,由于相关内容文档极其欠缺,本人也只是通过实践和代码阅读分析其原理,如有谬误欢迎指正。

,

在大规模系统架构中,事件机制通常采用消息驱动,它对提升分布式架构的容错性灵活性有很大帮助,同时也是各个组件之间解耦的利器.Rancher能够管理N多的代理同时又拆分出各种服务组件,事件机制是必不可少的。为实现事件机制,通常我们会采用RabbitMQ, ActiveMQ, ZeroMQ等中间件来实现。而牧场主则采用了基于websocket协议的一种非常轻量级的实现方式,它的好处就是极大程度的精简了牧场主的部署,牧场主无需额外维护一个MQ集群,毕竟websocket的消息收发实现是非常简单的,各种语言库均可以支持。

,

这里我们会考虑一个问题,websocket毕竟不是真正工业级MQ的实现,消息不能持久化,一旦某个事件的处理出现问题,或者发生消息丢失,牧场主如何保证各个资源的原子性一致性?牧场主中有一个processpool的概念,它可以看做一个所有事件的执行池,当API/UI/CLI有操作时,农场主会把操作分解成多个事件并放入processpool中。比如删除一个容器时会把compute.instance。删除放入processpool中,这个事件会发送到对应的主机代理上,特工处理完成后会发送回复给rancher-server。如果在这个过程中,由于网络问题消息丢失,或者代理上执行出现问题,rancher-server没有收到回复信息,牛会把这个事件重新放到processpool中再次重复上面的过程,直到compute.instance。remove 完成操作,这个容器的状态才会在DB中更新,否则该容器状态会一直处于lock不能被其他服务更新。当然cattle不会把这些event不停的重复执行下去,通常会设置一下TIMEOUT超出后便不再执行(有些资源没有TIMEOUT机制)。

 

上面的表述,我们其实可以在UI上看到这个过程,RancherUI上的Processes的Running Tab页上就能实时得看到这些信息,Processes 在排查一些Rancher的相关问题是非常有用的,大家可以养成 ”查问题先查Processes“的好习惯:


Rancher event机制及其实践指南


那么监听event的URL怎么设定呢?非常简单:

 

ws://:8080/v1/projects//subscribe?eventNames=xxxx

 

除此之外还需要加上basic-auth的header信息

 

Authorization: Basic +base64encode(:)

 

如果是Host上的agent组件,还需要添加agentId参数

 

ws://:8080/v1/projects//subscribe?eventNames=xxxx&agentId=xxxx

 

agentId 是注册Host时生成的,如果没有agentId参数,任何有关无关的event都会发送到所有的Host agent上,这样就会发生类似“广播风暴”的效果。

 

Host agent上运行很多组件,其中python-agent是负责接收和回执event信息的,其运行日志可以在Host上的/var/log/rancher/agent.log文件中查看。

 

细心的朋友可能会有疑问,我们在添加Host时执行agent容器时并没有指定cattle-access-key和cattle-secret-key,也就是说python-agent运行时如何获取这两个秘钥信息呢?

 

其实Rancher有两种apikey:一种是我们熟知的在UI上手动创建的apikey;另外一种就是agentApikey,它是系统级的,专门为agent设定,添加Host时会先把agentApikey发送到Host上。在cattle的credential表中可以查询到相关信息:


Rancher event机制及其实践指南


eventNames都定义了哪些呢?下面两个文件可以参考:

 

https://github.com/rancher/cattle/blob/master/code/iaas/events/src/main/java/io/cattle/platform/iaas/event/IaasEvents.java 系统级的event定义

 

https://github.com/rancher/cattle/blob/master/code/packaging/app-config/src/main/resources/META-INF/cattle/process/spring-process-context.xml 详细到每种资源(host、volume、instance、stack、service等)的event定义。

牧场主事件机制及其实践指南