前言
本文将介绍基于docker、gitlab CI、k8s、rancher的构建部署生态下,如果通过封装一个基础镜像来完成对发布者的通知触达。
整体思路
首先需要理清表现形式,由于基于gitlab CI,所以肯定是在CI过程中的某些Job或者stage中,通过shell来发送信息给开发者。
shell的封装可以通过node来提供一个cli命令行工具,发送信息的渠道可以选择邮件、微信等等具有api的通信,由于我们是网易,所以就选择popo,对应不同的任务应该发送给不同的目标,所以具体发送命令的表现形式应该如下:
yktci notify popo -l "发布完成" -m "$MSG 镜像地址:$IMAGE_URL" -t $NOTIFY_TO
yktci notify popo -l "构建完成" -m "$MSG 分支为 $CI_COMMIT_REF_SAFE_NAME" -t $GITLAB_USER_EMAIL
整个待解决项就明确了:
1、走通和popo的通信,将消息触达到某个人或者某个群;
2、封装一个yktci的node命令行工具;
3、封装一个镜像,其还有这个yktci的node cli,方便gitlab image去使用。
popo通信
一般来说所有的通信平台都有自己的开发平台,微信想必大家都知道。针对popo,如果想要完全自建,可以参考官方说明,搞accesstoken、openid那一套,类似微信平台一样。
当然也可以取消,基于一些内部已有的proxy来完成,秉着不重复造轮子的精神,这里我使用有道统一的通知服务。
可以理解为申请权限后,就可以一个接口解决popo发送指定消息给指定人的需求了。
比如:
curl -d '{"msg":"消息内容", "to":"brizer@163.com", "type":"3", "sub": "测试"}' -H "Content-Type: application/json" -H "TOKEN:xxxxxx" -X POST http://tellus.inner.youdao.com/api/v1/send
# 正常的响应内容如下:
{"code":0,"msg":"","data":null}
封装一个yktci的node命令行工具
封装一个命令行工具的方式,在node生态中是百花齐放。笔者也尝试过各种方式,比如类似自己接commander/yargs、inquirer等轮子来拼接的流派;又或者是类似egg-bin生态里common-bin的那种规约式挂载的方案;也体验过类似nest-cli、angular-cli那种通过依赖注入来解耦command和action的方式。
但是以上各种方式而言,都需要自己去搭建一些基础的骨架,其实的common-bin这种约定优于配置的方案比较符合企业级,但是其又是基于generator的语法。
只到我发现oclif,一个类似common-bin又远比common-bin强大的规约式命令行工具骨架。
通过一系列配置就可以解析入参、帮助描述、功能函数等等。比如上面的notify命令:
const { Command, flags } = require("@oclif/command");
const Popo = require("../actions/popo");
class NotifyCommand extends Command {
constructor(argv, config) {
super(argv, config);
this.popoAction = new Popo();
}
async run() {
const { args, flags } = this.parse(NotifyCommand);
const type = args.type;
const { to, title, msg } = flags;
let result;
if (type === "popo") {
result = await this.popoAction.sendMsgToGroup({
to,
title,
msg,
});
}
if (result.code == 0) {
this.log("发送成功");
} else {
this.error("发送失败");
}
this.exit(1);
}
}
NotifyCommand.description = `发送泡泡通知`;
NotifyCommand.flags = {
help: flags.help({ char: "h" }),
to: flags.string({ char: "t", description: "接收人或群id", required: true }),
title: flags.string({ char: "l", description: "标题", required: true }),
msg: flags.string({ char: "m", description: "具体信息", required: true }),
};
NotifyCommand.args = [{ name: "type", require: true }];
NotifyCommand.examples = ["yktci notify popo -l=标题 -m=信息来了 -t=2222206"];
module.exports = NotifyCommand;
提供一个这样的class就好了。非常快速的就可以完成一个命令行工具,聚焦于run的流程,而不再是参数设置等等。
封装一个镜像
如何将一个node命令行工具封装为一个镜像并提供给gitlab使用呢?这里我们可以参考下pm2,其实非常简单。
FROM node:14-alpine
LABEL maintainer="Keymetrics <contact@keymetrics.io>"
# Install pm2
RUN npm install pm2 -g
# Expose ports needed to use Keymetrics.io
EXPOSE 80 443 43554
# Start pm2.json process file
CMD ["pm2-runtime", "start", "pm2.json"]
依赖一个基础node镜像,然后直接从npm安装封装好的命令行工具包即可。
但是由于我们是在gitlab中使用,而且还需要使用docker cli,所以基于node镜像是不行的了,我们需要基于docker镜像,所以就如下:
# FROM node:14
FROM docker:18.06
LABEL maintainer="ykt"
# Install node and yktci
RUN apk add bash \
&& apk add curl \
&& apk add --update nodejs npm \
&& apk add git \
&& node -v \
&& npm -v \
&& npm install yktci -g \
&& yktci -v
CMD ["yktci"]
这个镜像怎么给gitlab ci使用呢?
gitlab ci有一个image字段,用来指定执行环境的镜像,我们将自己的镜像打包到私有服上再去引用就好了:
image: harbor.org/kef2e/docker_yktci:1.0.1
这样整个流程就走通了。
