還在寫定時任務進行部署? ---使用Artifactory Webhooks和Docker實現持續部署

引言

持續部署(CD) 在持續集成的基礎上,把集成代碼或構建產物自動化部署到測試或生產環境。這就是我們所說的“流動軟件”。完全自動化可以使您的部署無縫、更少的出錯機率、更快,並且可以縮短反饋循環,因爲您現在可以在每次更改之後進行部署。

實現持續部署需要以下要素:

持續集成(CI),如Jenkins或JFrog Pipeline,用於構建/驗證新版本。

製品管理器,如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窗口中:

  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.docker.internal主機名是用來從Docker容器到達主機的。在生產環境中,您可能需要將其更改爲您的生產服務器URL和您選擇的端口, Artifactory 當文件有變更會主動通知該地址所執行的服務。

在secret字段中,您可以輸入任何您想要的字符串,它將以HTTP header“X-jfrog-event-auth”形式發送到目標服務,這樣您就可以驗證查詢是否來自可信的源。

選擇“Docker tag was promoted”事件。在Artifactory中,Docker鏡像可以被升級(晉級,代表測試驗證通過,將該鏡像升級爲更高成熟度狀態),這需要在不修改內容的情況下將Docker鏡像從一個倉庫移動到另一個倉庫。這可以確保在準備階段測試的鏡像是將驗證通過並是即將投產鏡像。

點擊“Select Repositories”,然後選擇要從中提升鏡像倉庫。你也可以在“Include Patterns”部分添加一個過濾器來匹配你的Docker鏡像清單。

2創建Webhook 處理程序

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源碼,包含輸入信息檢查,拉取最新鏡像,更新啓動新的容器等

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該命令將觸發以下流程:

  1. Artifactory將Docker鏡像複製到Docker-local-prod存儲庫中。
  2. Artifactory通過HTTP請求調用Webhook。
  3. Webhook坐在服務器獲取最新版本。
  4. 它會殺死正在運行的服務器(如果存在的話)。
  5. 用最新的更改啓動新的服務。

如果你完成到這裏,恭喜您,您已經完成了一個自動化部署方案!!!

4.一些建議

希望上面的指南能幫助你開始實現持續部署和使用webhook。還有許多附加的功能可以添加。以下是一些建議:

  1. 在CI環境中執行所有Docker / Jfrog CLI命令。例如,使用包含“#prod”的提交消息,使開發人員能夠進行部署。
  2. 使用容器編排。進行構建發佈Docker命令,比如使用Kubernetes、Docker swarm或者一些雲提供商SDK。
  3. 提高安全性。您可以向來自Artifactory的HTTP查詢添加一個自定義頭,以確保該查詢不會由發現您的開放端口並意外觸發部署動作
  4. 嘗試通過爲“docker push”事件創建webhook,自動化分段部署。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章