成都网站建设设计

将想法与焦点和您一起共享

如何用faas实现issueops

这篇文章主要讲解了“如何用faas实现issueops”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何用faas实现issueops”吧!

创新互联公司主营东港网站建设的网络公司,主营网站建设方案,重庆APP开发,东港h5微信小程序搭建,东港网站营销推广欢迎东港等地区企业咨询

issueops?

听过chatops,gitops还没听过issueops,顾名思义issueops就是在讨论issue的时候把ops的事给干了,讨论问题就把问题给解决,美哉。

kubernetes项目issue或者PR中会经常看到这样的东西: 如何用faas实现issueops

类似/kind feature 这样的指令是给机器人看的,这里就要介绍一位非常勤奋的小伙伴了:

如何用faas实现issueops

他叫k8s-ci-robot,我想没有谁的贡献有他多了吧,这可不是刷出来的,都是实打实的工作量:

如何用faas实现issueops

收到指令后robot就忙着打标签,验证提问题的有没有cla认证,分配review代码的人等:

如何用faas实现issueops

然后懒汉们review完代码就又吩咐机器人测试:

如何用faas实现issueops

小伙伴就一顿操作梦如虎的干了好多事情还不拿年终奖:

如何用faas实现issueops

以上,企业是不是发现养一个robot胜似招10个员工,是不是比疫情期间面向周报编程程序员靠谱多了~

Prow

Prow 就是robot的实现,原理非常简单,就是通过github webhook去监听github产生的事件,分析里面的指令去执行对应的job,它能干的几个重点的事:

  • 执行任务,特别是测试任务

  • 合并代码,你可能觉得这不就是点个按钮的事吗?其实不是,比如一个bug的修复可能要合并到很多个版本中,做起来枯燥且恶心,而且很多时候还是希望合并代码时能做些额外的事,如通知,打标签等等

  • 解析并执行类似/foo的指令,这很重要基本想干啥都行

  • 一个前端用于显示merge状态,任务等

Prow部署步骤大概如下:

  1. 申请一个github账户,给机器人用,推荐用独立的账号

  2. 有个k8s集群

  3. 配置权限,以及创建secret用于存储github账户的token,调用github SDK需要用

  4. 启动prow,就会得到一个http的地址

  5. 在你的github仓库里配置,webhook指向prow地址

别忘了我们很穷,在家隔离马上都要失业了服务器都买不起哪来的k8s集群?所以讨论这么多prow有啥用!

接下来白嫖模式开启

我们需要解决两个问题:

  1. 免费的计算资源跑http服务,给github webhook调用

  2. 一个免费跑job的平台

免费的httpserver

怎么去找一个免费的http服务?我们自然把恶毒的目光投向函数计算:

如何用faas实现issueops 阿里云腾讯云都有免费额度,而且这个量对于我这种小任务完全够用了,这个羊毛不薅一把我简直良心不安。

FaaS

很遗憾阿里云没有默认的golang的函数模板,但是支持自定义环境,只要监听9000端口就行。

对于鄙视UI的我来说在页面上创建函数丢不起这人,命令行工具fun必须要用:

函数配置信息

template.yml:

ROSTemplateFormatVersion: '2015-09-01'  
Transform: 'Aliyun::Serverless-2018-04-03'  
Resources:  
  CRService:  
    Type: 'Aliyun::Serverless::Service'  
  Properties:  
      Description: 'custom runtime demo'  
  LogConfig:  # 日志配置,需要与日志服务打通,这块对新手体验不是太好
        Project: 'sealyun'  
        Logstore: 'robot'  
  Policies:  
        - AliyunLogFullAccess  
    robot:  
      Type: 'Aliyun::Serverless::Function'  
  Properties:  
        Handler: index.handler  
        CodeUri: ./code.zip  
        Description: 'demo with custom runtime'  
  Runtime: custom  
      Events:  
        http_t:  
          Type: HTTP  
          Properties:  
            AuthType: ANONYMOUS  
            Methods: ['GET', 'POST', 'PUT', 'DELETE', 'HEAD'

代码框架,body里就是github传过来的events信息了:

func handler(w http.ResponseWriter, req *http.Request) {  
   b,err := ioutil.ReadAll(req.Body)  
   event := &issue.IssueCommentEvent{}  
   ...
}  

func main() {  
   fmt.Println("FunctionCompute go runtime inited.")  
   http.HandleFunc("/", handler)  
   port := os.Getenv("FC_SERVER_PORT")  
   if port == "" {  
      port = "9000"  
  }  
   http.ListenAndServe(":" + port, nil)  
}

写个简单脚本去部署函数:

函数启动时只认bootstrap二进制文件,用zip格式打包,fun deploy时会提示一些accesskey相关的配置

go build -o bootstrap faas.go  
zip code.zip bootstrap  
fun deploy

部署完你的触发器里就有个地址了:

如何用faas实现issueops

把这个地址配置到github webhook中 如何用faas实现issueops

这基本问题就解决了,要注意函数计算日志配置有点小绕,这里不细提了

执行任务

如果函数计算的自定义环境足够强大,那我们可以直接在函数里去执行一些任务,如编译,测试等,但是这不太友好也不太现实,不友好的地方是自定义环境的方式过于简陋,比如你需要函数中调用git命令,那你只能放zip里一起打包,没有像Dockerfile那样灵活,也没发现哪家能兼容Dockerfile的标准。 还有就是打包的东西太多可能函数的冷启动会很慢。

同样我还希望实现一些功能时不需要对机器人的代码进行变更,只需要修改一些外部配置或者脚本就可以实现不同的任务的处理。如此,drone来也

drone promote事件

先介绍一下drone promote事件,允许我们通过http触发pipeline中的一个动作。这个使用场景非常广泛,典型的一个场景:我们的项目编译发布结束之后需要上线,有两个环境,开发环境,测试环境

pipeline配置中:

- name: dev
 image: golang:1.12
 commands:
 - echo "部署到开发环境"
 when:
    event:
    - promote
    target:
    - dev
    
- name: test
 image: golang:1.12
 commands:
 - echo "部署到测试环境"
 when:
    event:
    - promote
    target:
    - test

这样我们想先只在开发环境中部署,那么就执行下面命令:

# drone build promote 项目 build编号 目标
drone build promote fanux/sealos 42 dev

这样dev这个步骤就会被执行,而test不会.

如果你是开源项目,那可以免费的使用drone提供的公有服务,又薅得一手好羊毛 cloud.drone.io

drone promote对接FaaS

既然是触发promote事件那下载下drone命令行就是了,何必又监听事件,又调用SDK绕一圈? 这就回到最开始的议题:我希望在讨论问题时把问题解决。

我也喜欢把所有东西放在云端,压根不想本地安装drone客户端,而且很多时候我可以在手机上发号施令。而且还希望执行完后能回覆issue执行结果等等

这里使用drone官方sdk即可:

// 创建client
config := new(oauth3.Config)  
auther := config.Client(  
   context.Background(),  
  &oauth3.Token{  
      AccessToken: d.DroneToken,  
  },  
)   
client := drone.NewClient(d.DroneServer, auther)

// 触发promote事件
_,err := client.Promote(namespace,name,cmd.Build,cmd.Target,cmd.Params)

namespace就是github用户名或者组名,name是仓库名,如 drone/drone-go 项目 drone就是namespace drone-go就是name Params是一个key value的参数,会注入到pipeline的环境变量中,也是非常有用的。

把以上东西写到FaaS中雏形就有了。

最终效果: 回复一下issue

如何用faas实现issueops

pipeline被执行 如何用faas实现issueops

robot框架

当然我希望robot的功能扩展性尽可能好,而且不仅仅能对接drone还可以对接其它的系统,以及扩展别的指令。所以我已经写好了一个框架:robot

只需要写一个特定命令的特定处理器,然后注册到框架中即可:

type Robot interface {
    Process(event IssueEvent) error
}

注意要想Processor生效必须要注册处理器 issue.Regist(命令,处理器)

以drone promote处理器为例:

// 结构体包含drone服务器地址和token
type DronePromote struct {  
   DroneServer string  
   DroneToken  string  
}
// 实现一下处理器接口
func (d *DronePromote) Process(event issue.IssueEvent) error {
...
}

这里event会把issue中的命令解析好丢给你的处理器处理:

type IssueEvent struct {  
  *IssueCommentEvent  
  Command *Command  
  Client  *github.Client  
}

你只需要关心你的处理器要处理啥指令就行,比如使用promote处理器时:

// github 把事件数据以json格式发送过来,已经被解析到event结构体中
func promote(ctx context.Context, event issue.IssueCommentEvent) (string, error) {
    // or using env: GITHUB_USER GITHUB_PASSWD
    // github 账户名和密码,因为机器人可能还要回复issue什么的操作,这里建议单独给机器人申请个账号
    // 不传参数就会从环境变量中读取
    config := issue.NewConfig("sealrobot", "xxx")
    // regist what robot your need, and the robot config
    // 注册一下你希望哪个机器人处理,因为一条issue中可能会有很做指令,我们只关心/promote即可
    // Drone的处理器需要知道drone的地址和token是什么
    issue.Regist("/promote", &drone_promote.DronePromote{"https://cloud.drone.io", "QS3SmhZVpJAmb7tWPuWIOh4BhuI"})
    // 处理issue
    err := issue.Process(config, event)
    return fmt.Sprintf("goversionecho %s", err), nil
}

使用Regist注册你的处理器,这样这个处理器只会处理issue中"/promote ..."的指令:

issue.Regist("/promote", &drone_promote.DronePromote{"https://cloud.drone.io", "QS3SmhZVpJAmb7tWPuWIOh4BhuI"})

感谢各位的阅读,以上就是“如何用faas实现issueops”的内容了,经过本文的学习后,相信大家对如何用faas实现issueops这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是创新互联,小编将为大家推送更多相关知识点的文章,欢迎关注!


本文题目:如何用faas实现issueops
URL链接:http://chengdu.cdxwcx.cn/article/jeigji.html