Photo Credit: freddie boy via Compfight cc

本文延續 < a href="/post/2013/11/build-own-cloud-continuous-integration-system">上篇文章 說明一個山姆鍋利用 Jenkins 建構的持續整合系統,這個系統跟 Google Apps for Business 認證整合(或者也可以使用其它 OpenID providers)。按照建議的架構,採用 Master-slave 叢集方式,團隊可以視需要增減 slave 服務器。

運用的 Jenkins 插件

除了完成認證整合與叢集架構所需的插件外,山姆鍋也將日後比較常用的一併安裝。下面是讓整個架構變成可能的兩個插件:

OpenID 插件

這個插件讓 Jenkins 可以使用 OpenID 來認證用戶身份,它對 Google Apps for Business 也有直接支援。

Swarm 插件

這個插件的目的就是要讓從屬服務器可以動態地加入叢集中。這個插件需要裝在 Master 服務器上,Slave 服務器會在啟動時自動跟 Master 服務器註冊並開始接受工作。

網路架構

為了跟實際運用比較接近,以一台主服務器加上兩台從屬服務器爲網路架構。

主服務器

1
2
3
網域名稱: master.example.com
Puppet 配置檔:master-node.pp
IP 位址: 192.168.33.10

從屬服務器 1

1
2
3
網域名稱: ci-slave-1.example.com
Puppet 配置檔:slave-node.pp
IP 位址: 192.168.33.11

從屬服務器 2

1
2
3
網域名稱: ci-slave-2.example.com
Puppet 配置檔:slave-node.pp
IP 位址: 192.168.33.12

Master 服務器配置

要讓 Jenkins 可以跟 Google Apps for Business 整合,需要兩個基本資料:

  1. Google Apps for Business 的域名。
  2. 作為系統管理員的用戶 Email,其實也就是登入使用的 ID。 除了這位系統管理員外,其他經過認證的用戶的權限是由’authenticated’這個特殊用戶決定。所以,您可以根據需要調整’authenticated’用戶的權限。

注意:目前那兩個設定都被註解掉,沒有這兩個設定的話,預設是不會做身份認證。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class { 'apt':
}

class { 'java':
}

package {'git':
ensure => 'installed',
}

class {'jenkins':
version => '1.509.4',
install_java => false,
lts => true,
# domain => 'example.com',
# admin_email => 'admin@example.com',
plugin_hash => {
'git' => { version => '2.0' },
'parameterized-trigger' => { version => '2.21' },
'credentials' => { version => '1.9.1', pinned => true, override => true },
'ssh-credentials' => { version => '1.5.1', pinned => true, override => true },
'git-client' => { version => '1.4.6' },
'scm-api' => { version => '0.2' },
'multiple-scms' => { version => '0.2' },
'promoted-builds' => { version => '2.14' },
'token-macro' => { version => '1.9' },
'gradle' => { version => '1.23' },
'openid' => { version => '1.7' },
'build-pipeline-plugin' => { version => '1.4.2' },
'build-name-setter' => { version => '1.3' },
'jacoco' => { version => '1.0.13' },
'clone-workspace-scm' => { version => '0.6' },
}

Jenkins 預設就帶有’credentials’以及’ssh-credentials’這兩個套件,如果只是使用一般方式安裝,在重開機後,Jenkins 就會用內建的版本覆蓋掉新版本。要避免這樣的行為,需要在插件安裝目錄建一個定錨檔(pinned),例如:插件名稱是’plugin_name’,則定錨檔會是 $JENKINS_HOME/plugins/plugin_name.jpi.pinned。'pinned=>true’的目的就是為了產生定錨檔,讓 Jenkins 不要覆蓋。

插件安裝會從網路上下載後解開到插件安裝路徑,但是如果安裝路徑已經有相關的插件則不會進行。'override=>true’設定是要強迫下載後覆蓋已經存在的插件。

配置裡面的插件說明,您可以參考 < a href="https://wiki.jenkins-ci.org/display/JENKINS/Plugins" target="_blank" rel="noopener">Jenkins 的 Wiki。

Slave 服務器配置

Slave 服務器的配置相對簡單很多,因為它基本上是透過 Web Start 機制從 Master 服務器下載與安裝所需的程式。

1
2
3
4
5
6
7
8
9
10
11
12
class { 'apt':
}

class { 'java':
}

class { 'jenkins::slave':
masterurl => 'http://192.168.33.10:8080',
ui_user => 'ADMIN_USER',
ui_pass => 'API_KEY',
install_java => false,
}

其中的'ADMIN_USER’就是預設擁有系統管理權限的用戶;'API_KEY’是 Jenkins 配發給該用戶的 API Key。為什麼需要使用 API KEY 呢?由於我們採用 OpenID 來做用戶認證,導致 slave 服務器無法使用預設的簡單認證 (basic authentication) 機制。但沒有認證,slave 是無法加入叢集的,為了解決這樣的問題,Jenkins 針對程式提供一個通用的認證方式。這樣不管用戶的認證方式爲何,都不會影響的系統間的認證機制。

系統啟動順序

雖然山姆鍋也想做到不管 Master 或 Slave 服務器誰先開都無所謂,最終都要可以形成叢集。但是由於 slave 服務器上需要設定一個註冊的時候用的認證資料,也就是配置說明中的’ADMIN_USER’以及’API_KEY’。雖然’ADMIN_USER’可以預先得知,但’API_KEY’是在 master 服務器啟動完成後才能得知。所以,啟動這個系統需要按照下列順序:

  1. 開啓 master 服務器:在 Vagrant 環境下,透過下列指令:
1
$ vagrant up master

這樣,Vagrant 只會啟動 master 服務器。

  1. Master 服務器正常啟動後,登入到 Jenkins 頁面,選擇右上方出現的用戶名稱聯結後,在左邊選單選擇 & quot; 設定 & quot;(setting)出現該用戶的設定頁,從這頁可以取得該用戶的 API Key。

  2. 將取得 API KEY 設定到 slave 的 Puppet 配置檔後,根據需要開啓所需數量的 slave 服務器。

小結

利用 Vagrant 來整備 (provision) 需要的服務器,再運用 Puppet(或您偏好的配置管理系統)來自動安裝跟部署需要的軟體套件,這樣的組合真的是很有力的工具。透過這個工具,山姆鍋提供一個方案來建置一個適合生產環境使用的持續整合系統。雖然,使用這樣的方式不代表說您就可以不需要了解背後的運作原理,但至少在急需的時候,有機會可以如法炮製。