山姆鍋最近需要安裝 Jenkins 這個持續整合軟體,但不打算採用過去手動的安裝模式,而是嘗試運用 Vagrant, Puppet 跟 Virtualbox 來做自動部署。持續整合軟體一般建議不要在 Master 上執行建構工作, 所以,本次的實驗就以安裝一台 Master 與一台 Slave 主機為目標。
- 關聯文章: 運用 Vagrant 準備一致的開發與測試環境
由於之後應該陸續會有類似的實驗,山姆鍋將相關的程式碼放在 devops-labs ⎘ 這個 GitHub 項目以方便讀者參考。 本文主要 Puppet 的 manifests 腳本放在 recipies/jenkins-ci ⎘ 這個目錄中。為了完整性,山姆鍋也將相關需要的 Puppet modules 放在這個項目中, 這樣讀者只要 git clone 之後,便可以簡單以下列指令看實際執行的結果:
$ git submodule update --init
$ cd recipes/jenkins-ci
$ vagrant up
如果執行順利,使用瀏覽器連到 http://192.168.33.10:8080/computer
,應該可以看到下列畫面:
請注意:本文的設置,Jenkins 並沒有開啓任何安全設定,也就是說,沒有加上必要安全認證之前, 不要在網路上使用!
準備工作
您的測試機上需已經安裝有下列軟體:
- Git
- Vagrant 1.1+
- VirtualBox 4.1 or 4.2
注意:Vagrant 目前不支援 VirtualBox 4.3。
本文的方法需要依賴下列 Puppet 模組:
puppet-java 這個模組,跟在 「使用 Puppet 在 Ubuntu 系統上自動安裝 Oracle JDK」 說明的差不多,不過改成使用 puppet-apt 來做系統套件庫管理。
虛擬機設定
目標是要安裝兩台服務器,一台當作 Jenkins master,一台當作 Jenkins slave。 Jenkins slave 會自動加入 Jenkins master 的叢集中,如此,master 就可以開始分配工作給 slave 執行。 理想上,可以按照需要依照同樣的設定增加 Jenkins slave。
下面是有關服務器的 Vagrant 設定檔:
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box_url = "http://files.vagrantup.com/precise64.box"
config.vm.define :master, primary: true do |master|
master.vm.box = "precise64"
#master.vm.forward_port 8080, 8080
master.vm.network :private_network, ip: "192.168.33.10"
master.vm.hostname = "ci-master.example.com"
master.vm.provider :virtualbox do |vb|
# Use VBoxManage to customize the VM. For example to change memory:
vb.customize ["modifyvm", :id, "--memory", "512"]
end
master.vm.provision :puppet, :module_path => "../../modules" do |puppet|
puppet.manifests_path = "manifests"
puppet.manifest_file = "master.pp"
puppet.facter = { 'fqdn' => master.vm.hostname }
end
end
config.vm.define :slave do |slave|
slave.vm.box = "precise64"
slave.vm.network :private_network, ip: "192.168.33.11"
slave.vm.hostname = "ci-slave.example.com"
slave.vm.provider :virtualbox do |vb|
# Use VBoxManage to customize the VM. For example to change memory:
vb.customize ["modifyvm", :id, "--memory", "512"]
end
slave.vm.provision :puppet, :module_path => "../../modules" do |puppet|
puppet.manifests_path = "manifests"
puppet.manifest_file = "slave.pp"
puppet.facter = { 'fqdn' => slave.vm.hostname }
end
end
end
由於 Vagrant box 內建的 Puppet 無法正確取得’fqdn’(主機域名), 需要加入 puppet.facter = { ‘fqdn’ => master.vm.hostname } 與 puppet.facter = { ‘fqdn’ => slave.vm.hostname } 來讓 Puppet 可以直接使用而不嘗試採用 facter 取得。
網路的部分,使用 private network,也就是 hostonly 模式。這樣虛擬機之間,主機與虛擬機就可以互相溝通。
Master 的 Puppet 組態檔
下列是 Jenkins master 的組態檔內容:
class { 'apt':
}
class { 'java':
}
class {'jenkins':
install_java => false,
}
include jenkins::master
因為,Jenkins 這個 Puppet 模組預設會試圖安裝 Java 環境,所以, ‘install_java’設為 false 就是讓它跳過安裝 Java 的步驟。
Slave 的 Puppet 組態檔
跟 Jenkins master 的主要差別在於 ‘class {‘jenkins::slave’ 這個部分,其中也指定 Jenkins master 的為止,讓 Jenkins slave 可以自行向 master 註冊。 ‘ui_user’跟’ui_pass’目前是沒有作用的。
class { 'apt':
}
class { 'java':
}
class { 'jenkins::slave':
masterurl => 'http://192.168.33.10:8080',
ui_user => 'adminuser',
ui_pass => 'adminpass',
install_java => false,
}
結語
希望這個配方(recipe)對您有些幫助,但就像醫師的配方一樣,不同人的配方或多或少不同, 可不能隨便服用。同樣地,本文提供的配方,主要目的是了解如何以 Vagrant, Puppet 來進行自動部署, 使用 Jenkins 只是希望有個比較實際的例子。