如何封装CI专用的基础镜像

前言

本文将介绍基于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发送指定消息给指定人的需求了。

比如:

扫描二维码关注公众号,回复: 15633422 查看本文章
curl -d '{"msg":"消息内容", "to":"[email protected]", "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 <[email protected]>"

# 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

这样整个流程就走通了。

猜你喜欢

转载自blog.csdn.net/mevicky/article/details/118496828
ci