自己没有一个镜像仓库,只有一个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…