ラベル jenkins の投稿を表示しています。 すべての投稿を表示
ラベル jenkins の投稿を表示しています。 すべての投稿を表示

2013/02/18

Jenkinsのスレーブノードを追加してみた

先日の記事(Hello, Jenkins. GitLab+Jenkins+perl(Mojolicious)でCIをしてみた)では
GitLab(Gitolite)を使っている環境に、Jenkinsをインストールして、
CIのためのシステム構築を行いましたが...
さらに他のマシンをスレーブとして追加することで、ビルドの負荷分散ができます。

今回は新しいVPSにもJenkinsをインストールして、スレーブにしてみました。
この記事では、スレーブを構築&設定する手順を、書いておきます。(自分用メモとしてw)
  • スレーブ側では、Jenkinsサービスを起動しておく必要はありません。
  • ビルドを行う度に、マスターのJenkinsがSSHを介してスレーブのシェルに接続し、スレーブ上のJenkinsの"スレーブエージェント"を実行する仕組みです。(sshを介して通信するので、特に両者間でVPNを張る必要もありません。)
    参照: Distributed builds - 日本語 - Jenkins Wiki
  • 今回、CIを行う対象のプロジェクトは、マスター上のGitLab(Gitolite)にリポジトリがあるものとします。(先日の記事の続きなので。)
尚、今回は鍵を2つ作成することになります。
  • [マスター側で作成する鍵] カギA  - 手順3で作成
    • マスターのJenkinsが、スレーブに接続するため の鍵。
    • 作成されたカギの公開鍵は、スレーブのauthorized_keysに登録します。
  • [スレーブ側で作成する鍵] カギB  - 手順5で作成
    • スレーブのJenkinsが、Gitリポジトリに接続するため の鍵。
    • 作成されたカギの公開鍵は、GitlabもしくはGitoliteに登録します。
(※ もっと良い手順がありましたら、ご教授お願いします!)


  1. [スレーブ] Jenkinsをインストール。
    (先日の記事 "Hello, Jenkins. GitLab+Jenkins+perl(Mojolicious)でCIをしてみた" を参照のこと。jenkinsサービスを開始する必要はありません。)
  2. [スレーブ] JREをインストール。
  3. [マスター] カギAを .sshディレクトリ(/var/lib/jenkins/.ssh/)に作成。
    $ sudo -u jenkins ssh-keygen
    > /var/lib/jenkins/.ssh/id_rsa_con_slave
  4. (マスター側の.sshディレクトリには既に、マスター自身のJenkinsが Gitリポジトリに接続するための鍵があるわけですので、今回は別の名前にします。)
  5. [スレーブ] カギAの公開鍵(id_rsa_con_slave.pub)の中身を、スレーブ上のJenkinsユーザのauthorized_keys (/var/lib/jenkins/.ssh/authorized_keys) に記述。
    $ sudo -u jenkins vi /var/lib/jenkins/.ssh/authorized_keys
    ssh-rsa ~~~~ jenkins@xxx
    ※ 但し、jenkinsユーザは、/etc/passwd上 で /bin/falseに設定されているので、/bin/bashに変更する。
    もしくは、他のユーザを作成する。(セキュリティ的には後者のほうが安全...か?)
  6. $ sudo -u root vi /etc/passwd
    ~~~~
    jenkins:x:xxx:yyy:Jenkins Continuous Build server:/var/lib/jenkins:/bin/bash
  7. [スレーブ] カギBを .sshディレクトリ(/var/lib/jenkins/.ssh/)に作成。
    $ sudo -u jenkins ssh-keygen
    > /var/lib/jenkins/.ssh/id_rsa
  8. [スレーブ] カギBをGitリポジトリへの接続に使えるよう、.ssh/configに記述。(先日の記事でのマスター側と同様。)
    $ sudo -u jenkins vi /var/lib/jenkins/.ssh/config
    Host example.com
        User gitolite
        Port xx
        Hostname example.com
        IdentityFile /var/lib/jenkins/.ssh/id_rsa
  9. [クライアント] カギBの公開鍵(id_rsa.pub)の中身を、GitLab(もしくはGitolite)のJenkinsユーザのSSH鍵に登録。
    (GitLabを使っているならば、先日の記事と同様に、Webブラウザからjenkinsアカウントでログインして、SSH Keys画面から鍵の追加を行います。)
  10. [スレーブ] known_hostsにGitリポジトリサーバの情報を登録するために、一旦、手動でgit cloneをします。
    $ cd /var/lib/jenkins/
    $ sudo -u jenkins git clone ssh://gitolite@example.com:xx/hoge.git
    > Are you sure you want to continue connecting (yes/no)? yes
    $ sudo -u jenkins rm hoge/ -R
    (cloneしてくるリポジトリは、jenkinsアカウントでgit cloneできるものなら何でもOK。cloneされたディレクトリは、すぐに削除して構いません。)
  11. [クライアント] マスターのJenkinsのノード管理画面で、ノードを追加する。

    • "ノード名": 適当
    • "同時ビルド数": 適当 (スレーブのコア数にするのが妥当)。
    • "リモートFSルート":  "/var/lib/jenkins/"
    • "起動方法":  "SSH経由でLinuxマシンのスレーブエージェントを起動"
    • "ホスト": スレーブのホスト名 or IPアドレス
    • "ユーザ名": "jenkins"
    • "ポート" スレーブのSSHデーモンのポート
    • "秘密鍵":  カギAの秘密鍵 ("/var/lib/jenkins/.ssh/id_rsa_con_slave")
  12. [スレーブ] 各プロジェクトのビルド環境を構築する。
    とりあえず手順9まで終えて、ビルドを実行してみると、まだ失敗することがわかると思います。
    ですので、例えば perlのプロジェクトをCIするのであれば、cpanmのインストールなり、perlのモジュールインストールなりを行います。先日の記事の後半どおり、マスター側と同様。
といった感じです。

スレーブ側では、JenkinsのWeb画面での設定も、ジョブ作成も必要ありません。
その都度、マスターのJenkinsがスレーブへ自動的に転送してくれます。

尚、さらに2台目、3台目のスレーブ...と追加していく場合には、
この記事の手順3は不要ですね。

2013/02/10

Hello, Jenkins. GitLab+Jenkins+perl(Mojolicious)でCIをしてみた

こたつ最高(>ω<)♪ こたつで丸くなっております、Masanoriです(笑)

公開しているプロジェクトではTravis-CIを使わせていただいていたりするのですが
今回は、自前のGitLabで管理しているプロジェクトにもCIを...ということで...

Jenkinsをインストールして、GitLab上のGitリポジトリ、
および nginx(リバースプロキシとして...)と組み合わせる話(※自分用メモ)です。
また、
Jenkinsを用いて、perl(Mojolicious)のプロジェクトをテストします。
(加えて、CPANモジュールの一時的な自動インストールも行えるようにします。[追記: 2013/02/11])


※尚...Gitlabには、Gitlab CIというシンプルなソフトウェアが提供されており、通常はそちらを使うと良いと思います。今回は Jenkinsを使うこととしました。
Jenknsをちゃんと使ってみたかった!という動機がw
  • サーバはいつも通りのCentOSです。JDKなどもセットアップ済みです。
  • nginxをリバースプロキシとして、Jenkinsを /jenkins 下で動作させます。
    (毎度お断りしておきますが、以下にある設定内容は実際の運用サーバとは異なります。)
  • プロジェクトはすでにGitLabで作成済みで運用中、nginxも運用中です。
以下、
madroom project: Gitoliteに触れずにGitLabのhookからJenkins側でビルドする
を参考にさせていただきました。感謝! m(_ _)m♪
(Gitoliteを弄らない方法になっています。)


まずはJenkinsのウェブサイトからRPMをダウンロードしてインストール。
(LTS版もあるみたいですが、最新のJenkins-1.500を選択。)
$ wget http://pkg.jenkins-ci.org/redhat/jenkins-1.500-1.1.noarch.rpm
$ sudo rpm -ivh jenkins-1.500-1.1.noarch.rpm
これでJenkinsのインストールは完了です。とても楽ちんでありがたいですね。

次にJenkinsからGitリポジトリへアクセスできるよう鍵を作ります。
(今回はサーバ上でなくクライアント上で作って転送したほうが、GitLabでの登録がうまく行くそうです。)
$ ssh-keygen
Enter file in which to save the key (~~~): id_rsa_jenkins
Enter passphrase (empty for no passphrase): (空)
Enter same passphrase again: (空)
作成した鍵は、/var/lib/jenkins/.ssh/ 下に置いておきます。

さらに /var/lib/jenkins/.ssh/config を記述します。
$ sudo vi /var/lib/jenkins/.ssh/config
Host example.com
    User gitolite
    Port xx
    Hostname example.com
    IdentityFile /var/lib/jenkins/.ssh/id_rsa_jenkins
またknown_hostsも手動で記述しておきますw
$ sudo vi /var/lib/jenkins/.ssh/known_hosts
[example.com]:xx,[xxx.xx.xxx.xxx]:xx ssh-rsa ~~~~
次にJenkinsの設定ファイル(/etc/sysconfig/jenkins)を開いて
ポート設定およびディレクトリパスを変更します。

$ sudo vi /etc/sysconfig/jenkins
~~~~
# JENKINS_PORT="8080"
JENKINS_PORT="8888"
~~~~
#JENKINS_ARGS=""
JENKINS_ARGS="--prefix=/jenkins"
さらにnginxの設定ファイルにリバースプロキシのための設定を追加しておきます。
$ sudo vi /etc/nginx/nginx.conf
http {
    ~~~~
    upstream Jenkins.backend {
        server 127.0.0.1:8888;
    }
 ~~~~
    server {
        ~~~~
        location ~ ^/jenkins.* {
                proxy_pass      http://Jenkins.backend
                break;
        }
        ~~~~
    }
}
次に、Gitlabにブラウザからアクセスし、Jenkinsのユーザアカウントを作成します。
またCIを行うプロジェクトの"Reporter"権限をそのアカウントに対し設定します。

さらに、プロジェクトのWebHooks画面で JenkinsのURL (http://example.com/jenkins/git/notifyCommit?url=gitolite@example.com:xxx/yyy.git)
を登録しておきます。

また、作成したアカウントでGitlabにログインして、
さきほど作成した公開鍵を登録します。


次に...Jenkinsを起動します。
$ sudo service jenkins start
これでブラウザからアクセスできるようになっているはずです。 http://example.com/jenkins

早速、"新規ジョブ作成"へ進....
...といいたいところですが、その前に...Git Pluginのインストールです。
これがWebのUIで取得〜適用まで可能になってるんですね〜...素晴らしいです! (ちょっと違うところでは、TracとかRedmineもそうなってきてますが、手軽でありがたいことですw
 以下スクリーンショット付きですw)


まず、"Jenkinsの管理"をクリック。
"プラグインの管理"をクリック。
"利用可能"タブをクリックして...
"Git Plugin"にチェックを入れ、"再起動せずにインストール"をクリック。
(※"Git Server Plugin"などありますが、またこれとは別です。
 "Git Plugin"だけ、フィルタをかけてもうまくヒットしないときがありました。 "高度な設定タブで、設定をいじったり、何回か更新処理を実行した後に正しく表示されました。)

(それにしても...他にも色々おもしろそうなプラグインがwktk)

"インストール完了後、ジョブがなければ〜再起動"にチェックを入れて待ちます。
インストールが終われば、ダッシュボードから再度、"Jenkins"の管理をクリックし、 "システムの設定"をクリックします。

"Git plugin" セクションの"Global Config user.name Value"と、
 "Global Config user.email Value"を入力し、"保存"をクリック。


次に、再度ダッシュボードに戻り、
"新規ジョブ作成"をクリック。
ジョブ名を入力し"フリースタイル・プロジェクトのビルド"を選択。
"OK"をクリック。

"Git"にチェックを入れ "Repositories"の
"Repository URL"に ssh://~なURLを入力して・・・

さらに、"ビルド・トリガ"セクションの "SCMをポーリング"にチェックを入れ "保存"をクリックします。

また最後であれですが..Jenkinsで認証を設定しておきましょう(※最初にやるべきか(汗;
"Jenkinsの管理"→"グローバルセキュリティの設定"から、設定できます。
 [追記:2013/02/11]
"アクセス制御"セクションの "行列による権限設定"を選択して、表を編集することで、非ログインユーザーによる閲覧をブロックすることが可能です。
(※尚、"ログイン済みユーザーに許可"のほうを選択してしまうと、非ログインユーザでも閲覧はできますので注意。)
尚、このグローバルセキュリティの設定ですが、設定ミスによりアクセスできなくなった場合は、
一時的に無効化しましょう (→ Jenkins パスワードのリセット方法 - エンジニアきまぐれTips (感謝♪))


さらにもし必要ならば、別途、nginx側などで閲覧認証をつけてください。

これでプロジェクトを取り込む設定は、ひとまず完了です。

あとは、GitLab上でTest Hookを実行するか、リポジトリにプッシュすれば
Jenkins側で、ひとまずビルドが走ります.........



さて、これではまだ、テストケースを実行して評価することができません。

今回CIを実施したいプロジェクトは、
perlのMojoliciousというWAFで開発しているWebアプリケーションなのですが、
これをJenkinsでテストできるよう設定したいと思います。

Tatsuya Blog » PerlのテストコードをJenkinsで動かすのページを
参考にさせていただきました。感謝です m(_ _)m♪
  • 但し、今回の記事では、テスト実行の際、一時的にCPANモジュールを自動インストールできるようにしておきます
    インストールされるモジュールは、Makefile.PLに定義します。
  • テストスクリプト(t/*.t)とMakefile.PLについては、作成済みです。
    Makefile.PLは、以前の記事: Travis CIでPerl(Mojolicious)アプリケーションを自動テストを参照。
    また、Mojoliciousでのテストスクリプトの書き方は、Test::Mojoなどを参考に。
まず cpanmを Jenkins用に、
Jenkinsのホームディレクトリ(/var/lib/jenkins)下へインストールします。

$ sudo -u jenkins mkdir /var/lib/jenkins/bin
$ cd /var/lib/jenkins/bin
$ sudo -u jenkins curl -LOk https://raw.github.com/miyagawa/cpanminus/master/cpanm
$ sudo chmod +x ./cpanm

次に、cpanmで、TAP::Formatter::JUnit をインストールします。
$ sudo cpanm TAP::Formatter::JUnit

次に、Jenkins上のプロジェクトの設定画面を開きます。


ここでは、"ビルド"セクションで、"シェルの実行"を選び、
"シェルスクリプト"欄に次のコマンドを記述します。
/var/lib/jenkins/bin/cpanm -l dlibs --installdeps .
prove -Idlibs/lib/perl5 -b --formatter=TAP::Formatter::JUnit -lvr t > test_results.xml
(最初にcpanmを使って、dlibsフォルダ下にモジュールを自動ダウンロードしています。
尚、proveコマンドについては、詳細なログが不要であれば-v オプションを取り除くといいです。
オプションについて詳しくは...prove についてのおさらいを参照するとよいでしょう。(感謝♪))


さらに、"テスト後の処理"セクションで、"JUnitテスト結果の集計"を選び、
 "テスト結果XML"欄に次のファイル名を入力します。
test_results.xml
"保存"ボタンをクリックして設定完了です。

あとはプッシュすれば、ビルドが自動的に行われ、テスト結果が生成されます。
また手動でもビルド実行が可能です。

無事通過(PASS)したテスト。Jenkinsでは青色のマークが表示されます。
通知設定などはまた別途行ってください。
それにしても...Jenkinsおじさん、ステキですwww

[2013/02/18 追記]
今回の続きとして...Jenkinsへスレーブを追加してみました。
Masanoriのプログラミング日誌++: Jenkinsのスレーブノードを追加してみた