上一次演示了如何使用阿里云Codepipeline,阿里云容器镜像服务实现CI,讲到这里我们push一下代码后就自动编译、自动跑单元测试、自动构建镜像、自动推送镜像到私仓。那么离我们最初设定的目标只差那么一小步了,那就是自动部署到测试/生产环境,这一步就是持续交付/部署(CD)。
CD其实是两个意思 (1)Continuous delivery (持续交付) 指的是,频繁地将软件的新版本,交付给质量团队或者用户,以供评审。如果评审通过,代码就进入生产阶段。 (2)continuous deployment(持续部署) 指的是代码通过评审以后,自动部署到生产环境。摘自阮一峰大神的blog
之前我一直以为CD只是持续部署的意思,最近仔细查资料才发其实是有两层意思。虽然是两层意思,但是其实也差不多,都是部署到某个可以运行起来的环境中,把程序跑起来。持续交付一般是部署到测试环境,供测试团队评审;持续部署是指通过测试评审后把程序部署到生产环境。既然差不多这里我就不细分了,因为都是部署,只是部署的位置不一样。
流程上次的流程到把镜像推送到私仓(阿里云容器镜像服务)后就结束了,后面的流程需要手动跑shell脚本来完成。我们要把后面的流程串起来,让shell脚本自动运行起来,需要一个触发机制,比如webhook。幸好,阿里云容器镜像服务有这么一个功能,可以让我们把流程串起来,那就是触发器功能。这个触发器功能跟webhook其实差不多,当容器镜像服务收到新镜像后会对外发送一个HTTP POST请求。那么我们只需要在服务器上部署一个web服务,当接收到POST请求的时候就运行服务器端的shell脚本,拉取镜像,运行容器,这样程序就部署起来了。 新建PublishHook服务
上面已经说了为了接收容器镜像服务发出的POST请求,需要一个web服务来接收处理请求。这个服务很简单,使用ASP.NET MVC都是杀鸡用牛刀,仅仅是监控一个请求而已。这里我使用另外一个轮子AServerhttps://github.com/kklldog/AServer 。
1. 新建一个控制台程序,取名PublishHook 2. 使用nuget安装AServer 3. 修改Program的main函数 using Agile.FrameworkNetCore.Log; using System; using System.Diagnostics; namespace PublishHook { class Program { static void Main(string[] args) { Console.WriteLine("PublishHook is running now !"); var server = new Agile.AServer.Server(); server.AddHandler(new Agile.AServer.HttpHandler() { Method = "POST", Path = "/api/hook", Handler = (req, resp) => { string shell_name = req.Query.shell; if (!string.IsNullOrEmpty(shell_name)) { RunShell(shell_name); } return resp.Write("ok"); } }); server .SetIP("0.0.0.0") .SetPort(9000) .Run(); Console.Read(); } static void RunShell(string fileName) { var processStartInfo = new ProcessStartInfo(fileName) { RedirectStandardOutput = true }; var process = Process.Start(processStartInfo); if (process == null) { Console.WriteLine("Can not run shell ."); } else { using (var sr = process.StandardOutput) { while (!sr.EndOfStream) { var str = sr.ReadLine(); Console.WriteLine(str); Logger.Info(str); } if (!process.HasExited) { process.Kill(); } } } } } }启动一个http Server监听9000端口,添加一个http handler,接收请求,解析QueryString获取脚本名称,然后运行脚本
运行publish_hook sudo dotnet restore sudo dotnet publish使用dotnet publish命令发布这个程序,然后复制到服务器上。
sudo dotnet PublishHook.dll使用dotnet命令在服务器上运行这个服务。注意:这个服务不能使用docker运行,因为它要运行shell脚本来操作宿主机的docker。如果这个服务跑在容器内,那么它执行的shell是相对于它的容器来说的,无法操作宿主机的docker环境。 复制上次新建的publish_cicd_test.sh脚本文件到PublishHook程序目录并赋予权限
复制上次新建的publish_cicd_test.sh脚本文件到PublishHook程序目录,一遍程序能够从根目录读取。
chmod +x publish_cicd_test.sh使用chmod +x给shell脚本赋值可执行权限
在容器镜像服务新建触发器点击创建触发器
在新建界面填写触发器名称,触发器url。这个url就是PublishHook监听的地址 测试一下