资讯专栏INFORMATION COLUMN

Rancher event机制及其实践指南

hightopo / 758人阅读

摘要:本次分享就介绍一下的机制,由于相关内容文档极其欠缺,本人也只是通过实践和代码阅读分析其原理,如有谬误欢迎指正。能够管理多的同时又拆分出各种服务组件,机制是必不可少的。为实现机制,通常我们会采用等中间件来实现。

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

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

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

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

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

那么监听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表中可以查询到相关信息:

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

https://github.com/rancher/ca...系统级的event定义

https://github.com/rancher/ca... 详细到每种资源(host、volume、instance、stack、service等)的event定义。

此外,一旦我们在UI/CLI/API上的某个操作都会被分解成多个event来执行,每个event信息都会被保存在mysql中,每个event执行成功后会设置成purged状态,所以表中记录并不会真正删除,这就会导致相应的表(container_event表、service_event表、process_instance表)会无限膨胀下去。

Rancher为解决此问题提供了周期性清理机制

events.purge.after.seconds 可以清理container_event和service_event,每两周清理一次;process_instance.purge.after.seconds可以清理process_instance,每天清理一次。这两个配置我们都可以在 http://

下面我们来实践一下,看看如何在程序中实现对Rancher event的监听。

Rancher提供了resource.change事件,这个事件是不用reply的,就是说不会影响Rancher系统的运行,它是专门开放给开发者用来实现一些自己的定制功能,所以我们就以resource.change作为例子实践一下。

Rancher的组件大部分都是基于Golang编写,所以我们也采用相同的语言。

为了能够快速实现这个程序,我们需要了解一些辅助快速开发的小工具。

Trash,Golang package管理的小工具,可以帮助我们定义依赖包的路径和版本,非常轻量且方便

Dapper,这个是基于容器实现Golang编译的工具,主要是可以帮助我们统一编译环境

go-skel,它可以帮我们快速创建一个Rancher式的微服务程序,可以为我们省去很多的基本代码,同时还集成了Trash和Dapper这两个实用的小工具

使用详情可以参考我之前写的一篇内容:

扒一扒Rancher社区中的小工具

回到本文的主题,首先我们基于go-skel创建一个工程名为 scale-subscriber (名字很随意),执行过程需要耐心的等待:

执行完毕后,我们把工程放到GOPATH中,开始添加相关的逻辑代码。

在这之前我们可以考虑添加一个healthcheck的服务端口,其实纵观Rancher所有的微服务组件,基本上除了主程序之外都会添加healthcheck port,这个主要是为了与Rancher中的healthcheck功能配合,通过设定对这个端口的检查机制来保证微服务的可靠性。

我们利用Golang的goroutine机制,分别添加主服务和healthcheck服务:

主服务的核心就是监听resource.change的信息,同时注册handler来获取event的payload信息,从而可以定制扩展自己的逻辑,这里需要利用Rancher提供的 https://github.com/rancher/ev... 库来快速实现。

如下图,在 reventhandlers.NewResourceChangeHandler().Handler 中就可以实现自己的逻辑:

这里我们只是演示监听event的机制,所以我们就不做过多的业务逻辑处理,打印输出event信息即可。

然后在项目根目录下执行make,make会自动调用dapper,在bin目录下生成scale-subscriber,我们执行scale-subscriber就可以监听resource.change的信息:

这里我们可以看到分别启动了healthcheck功能和event listener。然后可以在UI上随意删除一个stack,scale-subsciber就可以获取event信息:

如要将其部署在Rancher中,那就可以将scale-subsciber执行程序打包放到镜像中,通过compose来启动。

但是我们知道scale-subsciber启动需要指定CATTLE_URL、CATTLE_ACCESS_KEY、CATTLE_SECRET_KEY,正常的做法就是我们需要先生成好apikey,然后启动service的时候设置对应的环境变量。

这样做就会有弊端,就是apikey这种私密的信息不得不对外暴露,而且还要手动维护这些apikey,非常不方便。

Rancher提供了一个非常方便的做法,就是在service中添加两个label,

io.rancher.container.create_agent: true
io.rancher.container.agent.role: environment

设定这两个label后,Rancher引擎会自动创建apikey,并把相应的值设置到容器的ENV中,只要你的程序通过系统环境变量来读取这些值,就会非常顺利的运行起来。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/27965.html

相关文章

  • 关于Subscribe Rancher Events的思考

    摘要:年月日社区技术支持计划全面启动,本文是研发人员在社区答疑过程中关于的一些心得和思考。初识基于的消息总线可以很好的与前端兼容,让消息的传递不再是后端的专利。 2016年2月14日「Rancher社区技术支持计划」全面启动,本文是Rancher研发人员在社区答疑过程中关于Subscribe Rancher Events的一些心得和思考。 引言 几乎每个大型的分布式的集群软件,都离不开一样东...

    yuxue 评论0 收藏0
  • Rancher v1.2基础设施引擎整体架构分析

    摘要:官方于月日发布了其容器部署与管理平台的最新版本,。架构总览在版本的整体架构图如下图所示上,引擎向下深入演化成了基础设施引擎,这一点上在时代也早有体现。基础设施引擎初次安装版本,会发现多了如下图所示的明显标识,默认的引擎需要安装等服务。 Rancher Labs官方于12月1日发布了其容器部署与管理平台Rancher的最新版本,Rancher v1.2。Rancher v1.2可以说是一...

    Sike 评论0 收藏0
  • Rancher v1.2基础设施引擎整体架构分析

    摘要:官方于月日发布了其容器部署与管理平台的最新版本,。架构总览在版本的整体架构图如下图所示上,引擎向下深入演化成了基础设施引擎,这一点上在时代也早有体现。基础设施引擎初次安装版本,会发现多了如下图所示的明显标识,默认的引擎需要安装等服务。 Rancher Labs官方于12月1日发布了其容器部署与管理平台Rancher的最新版本,Rancher v1.2。Rancher v1.2可以说是一...

    tianhang 评论0 收藏0
  • 微服务运行指南——For Cattle

    摘要:微服务基础层主要是为容器提供计算存储网络等基础资源。微服务访问层,目前服务对外暴露访问主要以绑定或是负载均衡方式。除此之外,内置的负载均衡是基于实现的,支持。私有云场景中,很多行业用户在内部都使用硬件负载均衡来暴露服务访问地址。 站在微服务的角度看容器的基础设施服务可以分为三层: 微服务基础层 微服务构建层 微服务访问层 showImg(https://segmentfault.c...

    wzyplus 评论0 收藏0
  • 实践指南-快速解锁Rancher v1.2

    摘要:引言已经发布,相信众多容器江湖的伙伴们正魔拳擦准备好好体验一番。为了更好的体验的完整特性,我们选取了测试比较严格的运行环境。 引言 Rancher v1.2已经发布,相信众多容器江湖的伙伴们正魔拳擦准备好好体验一番。由于Docker能够落地的操作系统众多,各种Docker版本不同的Graph driver,所以通常大版本的第一个release都会在兼容性上有一些小问题。为了更好的体验R...

    KavenFan 评论0 收藏0

发表评论

0条评论

hightopo

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<