持续部署(CD) 是 在持续 集成 的基础上,把 集成代码或构建产物自动化 部署到 测试或 生产环境。这就是我们所说的“流动软件”。完全自动化可以使您的部署无缝、更少的出错几率、更快,并且可以缩短反馈循环,因为您现在可以在每次更改之后进行部署。
实现持续部署需要以下要素:
持续集成(CI),如Jenkins或JFrog Pipeline, 用于构建 / 验证新版本。
制品 管理器,如JFrog Artifactory,用于存储 制品, 并提供新版本的部署目标(服务器、智能设备)。
一个部署代理,控制新版本制品的相关运维操作 (停止当前服务器、下载二进制文件、启动服务器)。代理有两种类型:
拉 取方式 : 在目标上运行的 代理
推方式 : 在 任意集中服务器上运行 的代理,远程更新目标 服务
两种方式的对比:
拉和推部署模型各有优缺点,您也可以同时使用这两种模型。拉模型最显著的缺点是代理不知道二进制存储中的更改,因此它不知道何时触发更新。推送模型的一个缺点是安全性,因为目标需要确保部署代理经过身份验证,并且只能执行授权执行的操作。
在 本次分享 中, 我们会分享 如何创建一个推/拉 的 解决方案。我们将 一步一步实现从构建推送 Docker 镜像到注册中心 进行验证, 并 将其 升级 生产环境,最后使用JFrog Artifactory webhook来触发将其部署到我们的生产服务器。
首先,您需要一个运行的Artifactory服务器。如果您还没有云实例,您可以免费创建一个云实例。https://jfrog.com/artifactory/start-free/#saas
首先创建两个Docker 仓 库:Docker-local-staging和Docker-local-prod。

在new repository窗口中:
1. 选择 Docker
2. 输入“docker-local-staging”作为 key
3. 点击“保存并完成”
4. 重复 上述步骤创建 “docker-local-prod”
现在你有了两个空的存储库,继续设置webhook。导航到管理 菜单 Admin | General | Webhooks,点击“新建webhook“像这样填写 :

注意:在这个例子中,URL设置为" http://host.docker.internal:7979/ "。这是因为webhook处理程序将运行在本地主机和端口7979上。这里的host. d ocker.internal主机名是用来从Docker容器到达主机的。在生产环境中,您可能需要将其更改为您的生产服务器URL和您选择的端口 , Artifactory 当文件有变更会主动通知该地址所执行的服务。
在secret字段中,您可以输入任何您想要的字符串,它将以HTTP header “X-jfrog-event-auth” 形式 发送 到目标服务 ,这样您就可以验证查询是否来自可信的源。

选择“Docker tag was promoted”事件。在Artifactory中,Docker 镜像 可以被 升级(晋级,代表测试验证通过,将该镜像升级为更高成熟度状态) ,这需要在不修改内容的情况下将Docker 镜像 从一个 仓库 移动到另一个 仓库 。这可以确保在准备阶段测试的 镜像 是将 验证通过并是即将投产 的 镜像。
点击“Select Repositories”,然后选择要从中提升 镜像 的 仓库 。你也可以在“Include Patterns”部分添加一个过滤器来匹配你的Docker 镜像 清单。

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

webhook处理程序需要 做到以下操作 :
1. 读取并解析HTTP消息体。
2. 验证Docker 镜像 和 仓库 。即使你在Artifactory的webhook设置中添加了过滤器,服务器也应该总是验证 请求输入。
3. 拉 去 最新的Docker 镜像 。
4. 停止正在运行的容器(如果存在的话)。
5. 启动新版本。
下面是处理程序的核心 逻辑。 完整的代码示例可以在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)
}
它使用多个 开源 库:
1. golang内置的http server
2. docker golang SDK
其他部分代码请查看github源码,包含输入信息检查,拉取最新镜像,更新启动新的容器等
使用以下简单的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 该命令将触发以下 流程 :
1. Artifactory将Docker镜像复制到Docker-local-prod存储库中。
2. Artifactory 通过 HTTP请求调用Webhook。
3. Webhook 坐在 服务器获取最新版本。
4. 它会杀死正在运行的服务器(如果存在的话)。
5. 用最新的更改 并 启动 新的 服务。
如果你完成到这里,恭喜您,您已经完成了一个自动化部署方案!!!
希望上面的指南能帮助你开始实现持续部署和使用webhook。还有许多附加的功能可以添加。以下是一些建议:
1. 在CI环境中执行所有Docker / Jfrog CLI命令。例如,使用包含“#prod”的提交消息,使开发人员能够进行部署。
2. 使用容器编排。 进行构建 发布Docker命令, 比如 使用Kubernetes、Docker swarm或者一些云提供商SDK。
3. 提高安全性。您可以向来自Artifactory的HTTP查询添加一个自定义头,以确保该查询不会由发现您的开放端口并 意外 触发部署 动作 。
4. 尝试 通过为“docker push”事件创建webhook,自动化分段部署。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69954434/viewspace-2754497/ ,如需转载,请注明出处,否则将追究法律责任。