自己没有一个镜像仓库,只有一个Gitlab代码仓库,经常会有一些自动化部署项目的需求,一般镜像会保存在阿里云容器镜像服务里。有点小小的鸡肋,只能推镜像和拉镜像,不能做更多的东西了。
一直注意到阿里云镜像服务有一个触发器的东西,今天就来想办法使用它,一个简单的容器镜像的CI/CD。
在阿里云容器镜像服务新建一个镜像仓库
绑定一个Git仓库,GitHub,Gitlab都行
这里不做真实创建,只展示一个简单的流程,接下就是可以看到这个仓库下有一个自动构建的规则
它的意思会捕获在Git仓库中tag的变化,每一个新的Tag就会自动触发镜像构建任务,镜像服务就会拉取这个tag的代码自动根据Dockerfile构建镜像
接下来创建触发器
触发器URL为自己要搭建的HTTP服务器具体地址,镜像构建完成后会往这个地址发送消息,里面包含具体的自动触发构建的镜像信息。
接下来查看镜像服务触发器的文档,看看发送的内容:
请求内容:
{ "push_data":{ "digest":"sha256:457f4aa83fc9a6663ab9d1b0a6e2dce25a12a943ed5bf2c1747c58d48bbb4917", "pushed_at":"2016-11-29 12:25:46", "tag":"latest" }, "repository":{ "date_created":"2016-10-28 21:31:42", "name":"repoTest", "namespace":"namespace", "region":"cn-hangzhou", "repo_authentication_type":"NO_CERTIFIED", "repo_full_name":"namespace/repoTest", "repo_origin_type":"NO_CERTIFIED", "repo_type":"PUBLIC" } } 复制代码
最终要是获取请求内容中['push_data']['tag']的信息
搭建一个HTTP服务器接受这个信息,目前想到最快的办法就是做一个基于Python 的Flask框架服务器。看看主要的,仅仅需要一个单文件就能启动一个服务器:
# encoding=utf-8 from flask import Flask,request import json import os app = Flask(__name__) @app.route('/') def index(): return '阿里云Docker触发' @app.route('/docker/*******',methods=['POST']) def my_applet(): shell_path = '/****/******/******/update.sh' data = request.get_data() data = json.loads(data) tag = data['push_data']['tag'] print(tag) if 'CACHE' not in tag: shell = shell_path +' '+tag print(shell) os.system(shell) return data if __name__ == '__main__': app.run(host='0.0.0.0', debug=True, port=35555) # 部署 gunicorn app:app -b 0.0.0.0:35555 -w 2 -D 复制代码
这个单文件的HTTP服务器的功能就是接受镜像服务在完成镜像构建完成发送的消息,获取消息的中的镜像tag信息,然后调用shell命令进行任务部署。
#!/bin/bash if [ "$EUID" -ne 0 ] then echo "Please run as root" exit fi cd /******/*******/*******/ sed "s/[0-9]\.[0-9]\.[0-9]/$1/" -i docker-compose.yml rm -rf runtime/container/ echo -e "已删除缓存文件" docker-compose up -d --force-recreate sleep 1s echo "服务已启动" docker-compose logs -ft 复制代码
shell 脚本这里需要着重说一下,使用 $EUID
检测当前运行的系统权限,不是root权限会直接报错返回停止运行,然后使用sed命令替换 docker-compose.yml
(docker-compose配置文件)文件中的镜像tag,然后清除需要部署应用的缓存,强制更新docker-compose服务,这里sed命令中使用了 $1
读取了shell命令 后面的第一个参数,也就是tag的版本信息。
接下来参考一下最简单的docker-compose文件:
version: "3.5" services: my-test: image: registry.cn-shenzhen.aliyuncs.com/******/******:1.0.2 container_name: ****** restart: always ports: - "9501:9501" 复制代码
上面的例子中 1.0.2
就是使用shell脚本中的sed命令替换的,sed是一个在linux上非常强大的文本处理命令。以上的例子使用了一个正则替换,镜像tag以x.y.z的样式命名,实际上有些缺陷,上面的例子中都一位数,最多支持999个tag规则,应该支持更多位数的规则。
my-test image container_name
新建一个代码Tag
可以看到阿里云检测到有新的Tag自动开始构建了
等待构建完成,这里测试是以常规方法启动这个HTTP服务器,检查HTTP服务器日志显示:
可以看到代码中打印了Tag,镜像地址,并且正常拉取了远程的镜像,重启了容器服务,正常打印了项目的启动日志,到此测试完毕。
这里做了一个最简单的示例,因为是自己的项目测试,自己在GitLab增加一个master分支的Tag就会触发项目的自动构建自动部署,非常完美,没有加一些花里胡哨的功能,我想可以加一个webhook,在http服务器中或者shell脚本中加一个curl请求,实现部署完成的消息通知的功能,告诉开发者项目部署已经完毕了。
最后还是老规矩,GitHub分享所有的代码: github.com/koala9527/a…