圖片

Jenkins With Chef


Jenkins 這幾年算是 Open Source 界 CI 的一哥,而 Configuration Management 則是一直如雨後春筍般冒出,每個 DevOps 都有各自擁護的工具,而我目前是選擇用 OpsCode 的 Chef 來做伺服器的管理,而管理中相當重要的一環便是網路應用程式的部署,因此我就很想要把 Jenkins 和 Chef 做個連結,Google半天後,發現 CloudBees 已經有為 Chef 和 Puppet 做出了一個雛形,在 Jenkins 已經為大家準備好對應的 Plugin ,而在 Chef 和 Puppet 也都已經寫好對應的Script 供大家使用,可是我一用,發現...串不起來XD花了一點時間研究和改了一點 Chef的 Script 之後,總算是可以動了,今天這篇文章就簡單地跟大家介紹我是如何做到的

原理

在開始動手做做看之前,先跟大家講解一下 Jenkins 和 Chef 是如何上下交相賊的,首先就是在 Jenkins 這邊產生一個文字檔案,並且產生其MD5,然後Jenkins 就開始等待;Chef 這邊則是使用檔案類別的 Resource (file, template…) 做出一樣的檔案,在 Deployment 結束後,Recipe會將所有有發生改變的檔案 MD5 傳回 Jenkins,要是MD5與Jenkins一致,那麼Jenkins 就當作已經有一台伺服器已經Deployment完成

前置作業

  • Jenkins
    • 在 Jenkins 這邊需要安裝好 Chef Tracking Plugin
    • 並且稍微瞭解一下什麼是 Fingerprint,這個東東相當的重要,因為不管是雙方的溝通,或是之後我想要介紹的 Jenkins Pipeline,Fingerprint 都扮演著想當重要的角色
  • Chef
    • 而在 Chef 這裏需要在你的 Deployment 的需要 Include chef-handler-jenkins 這本 Cookbook,而我小改後才串得起來,但是我一直還沒有發 Pull request 給原作者,所以大家可以先 git clone 我的版本來做實驗

建置作業

  • Jenkins
    • 假設我們在Deployment有這些步驟 Deploy -> Testing -> Complete,因此 Fingerprint 會在 Deploy 步驟先產生起來放,然後一路流串到 Complete,如此一來,便完成一個完整的 Deployment 過程,我的作法如下

    • 新增一個 free style 的 Jenkins project,然後要把允許下一個 Project 可以 Copy Fingerprint 的權限開起來,並且把Project 名字給填好

    • 可以看到我在我用 echo 在workspace產生一個叫做 version.conf 的檔案來當作 Fingerprint,而我習慣的做法,是在裡面寫上要 Deployment 的版本號,以及Deploy當下的timestamp,最後在寫入下一個要觸動的 Project 名稱 (記得要選用 Manually 的,因為 Deploy 執行下去之後,要等 Chef 被動觸動),Test 是我亂打的,所以 Jenkins 找不到XD最下面則是跟 Jenkins 說你要把什麼檔案當成 Fingerprint

    • 接下來新增另外一個 Project 充當剛剛所說的 Test 角色,在 Build Trigger 的地方,選擇讓 Chef 來掌控,要安裝剛剛所說的 Chef Tracking Plugin,才可以看到這個選項,Upstreaming Job 也就是我們剛剛新增的 Deploy project,Condition 的地方要填入 Chef 定義好的 Environment,以及台數

  • Chef

    • 假設底下是你的 deploy recipe “deploy.rb"
# 設定Jenkins URL, 一定要記得 include chef-handler-jenkins

node.normal[chef-handler-jenkins][jenkins_url] = "填入你的 Jenkins 網址"
node.normal[chef-handler-jenkins][dryrun] = false
include_recipe 'chef-handler-jenkins'

... 一堆Deploy的步驟 ...

# 產生跟剛剛在 Jenkins 做出來的 Fingerprint 一模一樣的檔案
template "/var/www/html/test/version.conf" do
  source 'version.conf.erb'

  variables({
    :environment => node.chef_environment,
    :version => node['OMEGA_frontend']['deploy']['version'],
    :timestamp => node['OMEGA_frontend']['deploy']['timestamp']
  })
end

  • 底下為 version.conf.erb,相當的簡單,就跟 Jenkins 所產生的 Fingerprint 一樣
<%= @environment %>-<%= @version %>.<%= @timestamp %>

執行結果

  • Jenkins
    • 執行成功的話,應該會看到設定數目的 Chef Client 上來 Jenkins 上來報告
  • Chef
    • 而在 Chef Client 的執行 Log 中,在執行完 deploy.rb之後應該也可以看到如下的資訊產生
[2015-01-26T10:37:46+08:00] INFO: Submitting run data to http://xx.xx.xx.xx:xx: {
  "node": "TW-WSE-DEV1",
  "environment": "TW-WSE-DEV",
  "start_time": "Mon, 26 Jan 2015 10:37:38 +0800",
  "end_time": "Mon, 26 Jan 2015 10:37:46 +0800",
  "updates": [
    {
      "path": "/var/www/html/test/version.conf",
      "action": "create",
      "type": "Chef::Resource::Template",
      "md5": "ea796392c896abdee55783a483dfaf16"
    }
  ]
}
廣告

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

w

連結到 %s