还在写定时任务进行部署? ---使用Artifactory Webhooks和Docker实现持续部署

还在写定时任务进行部署?---使用Artifactory Webhooks和Docker实现持续部署

引言

持续部署(CD)是在持续集成的基础上,把集成代码或构建产物自动化部署到测试或生产环境。这就是我们所说的“流动软件”。完全自动化可以使您的部署无缝、更少的出错几率、更快,并且可以缩短反馈循环,因为您现在可以在每次更改之后进行部署。

实现持续部署需要以下要素:

持续集成(CI),如Jenkins或JFrogPipeline,用于构建/验证新版本。

制品管理器,如JFrog Artifactory,用于存储制品,并提供新版本的部署目标(服务器、智能设备)。

一个部署代理,控制新版本制品的相关运维操作 (停止当前服务器、下载二进制文件、启动服务器)。代理有两种类型:

拉取方式: 在目标上运行的代理

推方式:  在任意集中服务器上运行的代理,远程更新目标服务

两种方式的对比:

拉和推部署模型各有优缺点,您也可以同时使用这两种模型。拉模型最显著的缺点是代理不知道二进制存储中的更改,因此它不知道何时触发更新。推送模型的一个缺点是安全性,因为目标需要确保部署代理经过身份验证,并且只能执行授权执行的操作。

在本次分享中,我们会分享如何创建一个推/拉的解决方案。我们将一步一步实现从构建推送Docker镜像到注册中心进行验证,并将其升级生产环境,最后使用JFrog Artifactory webhook来触发将其部署到我们的生产服务器。

1.搭建制品库Artifactory

首先,您需要一个运行的Artifactory服务器。如果您还没有云实例,您可以免费创建一个云实例。https://jfrog.com/artifactory/start-free/#saas

首先创建两个Docker仓库:Docker-local-staging和Docker-local-prod。

在new repository窗口中:

[if !supportLists]1. [endif]选择Docker

[if !supportLists]2. [endif]输入“docker-local-staging”作为key

[if !supportLists]3. [endif]点击“保存并完成”

[if !supportLists]4. [endif]重复上述步骤创建“docker-local-prod”

现在你有了两个空的存储库,继续设置webhook。导航到管理菜单Admin |General| Webhooks,点击“新建webhook“像这样填写:

注意:在这个例子中,URL设置为" http://host.docker.internal:7979/ "。这是因为webhook处理程序将运行在本地主机和端口7979上。这里的host.docker.internal主机名是用来从Docker容器到达主机的。在生产环境中,您可能需要将其更改为您的生产服务器URL和您选择的端口, Artifactory 当文件有变更会主动通知该地址所执行的服务。


在secret字段中,您可以输入任何您想要的字符串,它将以HTTP header“X-jfrog-event-auth”形式发送到目标服务,这样您就可以验证查询是否来自可信的源。


选择“Docker tagwas promoted”事件。在Artifactory中,Docker镜像可以被升级(晋级,代表测试验证通过,将该镜像升级为更高成熟度状态),这需要在不修改内容的情况下将Docker镜像从一个仓库移动到另一个仓库。这可以确保在准备阶段测试的镜像是将验证通过并是即将投产的镜像。

点击“Select Repositories”,然后选择要从中提升镜像的仓库。你也可以在“Include Patterns”部分添加一个过滤器来匹配你的Docker镜像清单。

2创建Webhook 处理程序

webhook处理程序将在生产服务器上运行,并将接收一个包含变更事件信息的HTTP请求。在上述镜像升级的情况下,它的请求数据将看起来像这样:

webhook处理程序需要做到以下操作:


[if !supportLists]1. [endif]读取并解析HTTP消息体。

[if !supportLists]2. [endif]验证Docker镜像和仓库。即使你在Artifactory的webhook设置中添加了过滤器,服务器也应该总是验证请求输入。

[if !supportLists]3. [endif]拉去最新的Docker镜像。

[if !supportLists]4. [endif]停止正在运行的容器(如果存在的话)。

[if !supportLists]5. [endif]启动新版本。

下面是处理程序的核心逻辑。完整的代码示例可以在Github中找到。

https://github.com/jfrog/project-examples/tree/master/webhook-example


func main() {

http.HandleFunc("/", func (w http.ResponseWriter, r *http.Request) {

ctx := context.Background()

p, err := readPayload(r)

if err != nil {

http.Error(w, err.Error(), http.StatusBadRequest)

log.Printf("Payload reading error: %+v", err)

return

}

if !isMyServerEvent(p) {

http.Error(w, "Bad event", http.StatusBadRequest)

log.Printf("Unexpected event %+v", p)

return

}

cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())

if err != nil {

log.Printf("New client error: %+v", err)

return

}

err = pullLatestVersion(cli, ctx)

if err != nil  {

log.Printf("Pull error: %+v", err)

return

}

err = stopRunningContainer(cli, ctx)

if err != nil {

if client.IsErrNotFound(err){

log.Printf("Container does not exists")

} else {

log.Printf("Stop error: %+v", err)

return

}

}

err = startContainer(cli, ctx)

if err != nil {

log.Printf("Start error: %+v", err)

} else {

            log.Printf("Container updated ")

        }

})

http.ListenAndServe(":8081", nil)

}


它使用多个开源库:

[if !supportLists]1. [endif]golang内置的http server

[if !supportLists]2. [endif]docker golang SDK


其他部分代码请查看github源码,包含输入信息检查,拉取最新镜像,更新启动新的容器等


2 构建并推送docker images(demo 应用)

使用以下简单的golang web服务器进行测试:server.go


测试启动:go run serve.go

一个很简单测试服务,当你在浏览器中加载“http://localhost:8080”时打印出“Hello world”。

以下是这个应用程序的Dockerfile (大部分来自VSCode的golang Dockerfile模板):


用以下命令构建dockerfile。这在CI持续集成过程中应该是自动化的(基于JFrog CLI)。

docker build . -t localhost:8082/docker-local-staging/helloworld


jfrog rt docker-push localhost:8082/docker-local-staging/helloworld docker-local-staging --url http://localhost:8082/artifactory --user admin --password password


jfrog rt docker-promote helloworld docker-local-staging docker-local-prod --copy --user admin --password password --url http://localhost:8082/artifactory

jfrog rt docker-promote该命令将触发以下流程:


[if !supportLists]1. [endif]Artifactory将Docker镜像复制到Docker-local-prod存储库中。

[if !supportLists]2. [endif]Artifactory通过HTTP请求调用Webhook。

[if !supportLists]3. [endif]Webhook坐在服务器获取最新版本。

[if !supportLists]4. [endif]它会杀死正在运行的服务器(如果存在的话)。

[if !supportLists]5. [endif]用最新的更改并启动新的服务。


如果你完成到这里,恭喜您,您已经完成了一个自动化部署方案!!!


4.一些建议

希望上面的指南能帮助你开始实现持续部署和使用webhook。还有许多附加的功能可以添加。以下是一些建议:

[if !supportLists]1. [endif]在CI环境中执行所有Docker / Jfrog CLI命令。例如,使用包含“#prod”的提交消息,使开发人员能够进行部署。

[if !supportLists]2. [endif]使用容器编排。进行构建发布Docker命令,比如使用Kubernetes、Docker swarm或者一些云提供商SDK。

[if !supportLists]3. [endif]提高安全性。您可以向来自Artifactory的HTTP查询添加一个自定义头,以确保该查询不会由发现您的开放端口并意外触发部署动作。

[if !supportLists]4. [endif]尝试通过为“docker push”事件创建webhook,自动化分段部署。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,635评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,628评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,971评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,986评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,006评论 6 394
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,784评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,475评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,364评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,860评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,008评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,152评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,829评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,490评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,035评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,156评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,428评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,127评论 2 356

推荐阅读更多精彩内容