JenkinsのMesosプラグインで分散処理を試してみた

やりたいこと

前エントリで『cronジョブの負荷を分散したい!』とChronosを検証してみました。

今回はJenkinsのMesosプラグインを使って同じように
Mesosを使ったジョブの分散環境を作ってみたいと思います。
enkinsci/mesos-plugin · GitHub

概要

JenkinsのMesosプラグインを使うと図のようにJenkinsに登録されたジョブを
Mesosがリソースが空いているサーバーに振り分けて分散して実行してくれます。


イメージ図
f:id:tsunokawa:20140916141419p:plain



検証環境

f:id:tsunokawa:20141014200055p:plain

本エントリで例としてIPアドレスが出てきますがこの図の構成を参考にしてください。


今回使用したソフトウェアのバージョンです。

OS CentOS6.5
Jenkins jenkins-1.579-1.1.noarch
Mesos mesos-0.20.0-1.0.centos64.x86_64
ZooKeeper zookeeper-3.4.5+cdh5.1.2+31-1.cdh5.1.2.p0.4.el6.x86_64
ZooKeeper-server zookeeper-server-3.4.5+cdh5.1.2+31-1.cdh5.1.2.p0.4.el6.x86_64
JDK jdk1.8.0_20-1.8.0_20-fcs.x86_64


環境構築

必要パッケージのインストールや設定を行います。
上記図の通り、JenkinsはMesosと同じサーバーに同居しています。

必要パッケージ

インストール
epel有効後

yum install autoconf make gcc gcc-c++ patch python-devel python-setuptools libtool zlib-devel libcurl-devel openssl-devel cyrus-sasl-devel redhat-lsb nodejs


JDKもインストール
jdk-8u20-linux-x64.rpm

ZooKeeper

ダウンロード&インストール
CDHのRPMパッケージを利用しました。
※依存関係のあるbigtop-utilsも同時にインストールします。

cd /usr/local/src
wget http://archive.cloudera.com/cdh5/redhat/6/x86_64/cdh/5/RPMS/noarch/bigtop-utils-0.7.0+cdh5.1.2+0-1.cdh5.1.2.p0.4.el6.noarch.rpm
wget http://archive.cloudera.com/cdh5/redhat/6/x86_64/cdh/5/RPMS/x86_64/zookeeper-3.4.5+cdh5.1.2+31-1.cdh5.1.2.p0.4.el6.x86_64.rpm
wget http://archive.cloudera.com/cdh5/redhat/6/x86_64/cdh/5/RPMS/x86_64/zookeeper-server-3.4.5+cdh5.1.2+31-1.cdh5.1.2.p0.4.el6.x86_64.rpm

rpm -ivh bigtop-utils-0.7.0+cdh5.1.2+0-1.cdh5.1.2.p0.4.el6.noarch.rpm
rpm -ivh zookeeper-3.4.5+cdh5.1.2+31-1.cdh5.1.2.p0.4.el6.x86_64.rpm zookeeper-server-3.4.5+cdh5.1.2+31-1.cdh5.1.2.p0.4.el6.x86_64.rpm


設定(Mesosサーバー1台目)

echo "1" >> /var/lib/zookeeper/myid


設定(Mesosサーバー2台目)

echo "2" >> /var/lib/zookeeper/myid


設定(Mesosサーバー3台目)

echo "3" >> /var/lib/zookeeper/myid


設定(Mesosサーバー全台共通)
/etc/zookeeper/conf/zoo.cfg
に以下を追記

server.1=10.0.0.1:2888:3888
server.2=10.0.0.2:2888:3888
server.3=10.0.0.3:2888:3888


起動

service zookeeper-server init
service zookeeper-server start


自動起動設定

chkconfig zookeeper-server on


Mesos

MesosはZooKeeperによりMasterが選出されます。
Mesosサーバー全台にMesosのインストールを行います。
また、Master, Slave両方の設定を全台に行います。


ダウンロード&インストール
Mesosphere, Inc.から公開されているRPMパッケージを利用しました。
https://mesosphere.io/downloads/
からCentOS6系のパッケージを選択するとダウンロード出来ます。

cd /usr/local/src
wget http://downloads.mesosphere.io/master/centos/6/mesos-0.20.0-1.0.centos64.x86_64.rpm
rpm -ivh mesos-0.20.0-1.0.centos64.x86_64.rpm

curl -sSfL http://downloads.mesosphere.io/master/centos/6/mesos-0.20.0-py2.6.egg --output /tmp/mesos.egg
easy_install --allow-hosts pypi.python.org /tmp/mesos.egg


Mesosライブラリにリンクを張っておきます。

ln -s /usr/local/lib/libmesos.so /usr/lib/libmesos.so



設定(Mesosサーバー全台共通)
設定変更
/etc/mesos/zkファイルを以下のように変更します。

zk://10.0.0.1:2181,10.0.0.2:2181,10.0.0.3:2181/mesos


OS再起動
最後にMesosサーバー全台OS再起動を行います。
MesosはOS起動時に自動起動するようになっているのでOS再起動を忘れず実施してください。


Mesos動作確認
OS再起動後、mesos-masterが正常に稼働しているか確認します。

curl -i 10.0.0.1:5050/master/health


表示例

HTTP/1.1 200 OK
Date: Thu, 04 Sep 2014 00:00:01 GMT
Content-Length: 0

200OKが返ってくれば正常に動作しています。


Mesos管理画面
f:id:tsunokawa:20141014195859p:plain

http://10.0.0.1:5050/
Mesosのステータスが確認出来ます。
mesos-slave3台が登録されていることが確認出来ます。

Maven

ダウンロード&インストール
JenkinsのMesosプラグインのインストールでMavenを使用するためセットアップします。

cd /usr/local/src
wget http://ftp.kddilabs.jp/infosystems/apache/maven/maven-3/3.2.3/binaries/apache-maven-3.2.3-bin.tar.gz

tar zxvf apache-maven-3.2.3-bin.tar.gz
export M2_HOME=/usr/local/src/apache-maven-3.2.3
export M2=$M2_HOME/bin
export PATH=$M2:$PATH


Jenkins

JenkinsはMesosサーバーに共存させる場合、どこか1台でインストールされていればOKです。
mesos-slaveは
・jenkinsユーザ
・JAVA_HOMEが設定
がそれぞれ設定されていればインストール不要です。
が分かりやすいようにMesosサーバー全台にJenkinsをインストールしています。


ダウンロード&インストール

wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key
yum install jenkins


/etc/profileに以下を追記

export JAVA_HOME=/usr/java/default
export JRE_HOME=/usr/java/default
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/jre/lib:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar


JenkinsMesosプラグイン

ダウンロード&インストール

git clone https://github.com/jenkinsci/mesos-plugin.git
cd mesos-plugin
mvn package -Dmaven.test.skip=true
cp target/mesos.hpi ${JENKINS_HOME}/plugins
chown jenkins:jenkins ${JENKINS_HOME}/plugins/mesos.hpi

※MesosプラグインをJenkinsのプラグイン管理画面からインストールした場合うまく動作しませんでした。
なので今回は上記のようにGitHubからダウンロードしたプラグインをコンパイルしています。


Jenkinsデーモン起動

service jenkins start

※mesos-slaveはjenkinsデーモンを起動しておく必要はありません。


Jenkins Mesosプラグイン設定
Jenkinsのプラグイン管理画面からMesosプラグインがインストールされているか確認します。
f:id:tsunokawa:20140916151754p:plain
上記のような表示になっていればインストールが成功しています。


次に[Jenkinsの管理] - [システム設定]からMesosプラグインの設定を行います。
f:id:tsunokawa:20140916152029p:plain
f:id:tsunokawa:20140916152039p:plain

Mesos native library path /usr/lib/libmesos.so
Mesos Master [hostname:port] zk://10.0.0.1:2181,10.0.0.2:2181,10.0.0.3:2181/mesos
Label String mesos

ほぼデフォルト値のままでいいのですが上記設定は書き換えてください。


Jenkinsプロジェクト設定
f:id:tsunokawa:20141027155447p:plain
Mesosで分散したいJenkinsのプロジェクトの設定を変更し、
該当プロジェクトがmesos-slave上で実行されるようにします。
Jenkinsの管理画面から[プロジェクト] - [設定]を開くと

実行するノードを制限

という項目があります。
これにチェックを入れ、以下のように設定値を入力してください。

ラベル式 mesos

この設定値のmesosは先程mesosプラグインの設定で入力したLabel Stringを入力してください。

ジョブの実行

いよいよジョブを登録して実行してみます。
Jenkinsのジョブ登録と実行の説明は割愛します。
通常のJenkinsジョブの登録と実行手順でOKです。


タスク実行前
f:id:tsunokawa:20141020142203p:plain
Active Tasksに何も表示されていません。


タスクの実行その1
f:id:tsunokawa:20141020142215p:plain
10.0.0.2のHostでJenkinsのジョブが実行されたのが分かります。


タスクの終了
f:id:tsunokawa:20141020142227p:plain
タスクが終了するとCompleted Tasksに状態が変化します。

先程は10.0.0.2のHostでJenkinsジョブが実行されました。
この10.0.0.2のHostはテストサーバーでリソースが余っているため
何度ジョブを実行しても同じ10.0.0.2で動いてしまいます。
そこで、while true; do true; doneこのような無限ループ処理をさせてCPUリソースを使い切らせます。
これでもう10.0.0.2のHostはもうリソースの空きがありません。

この状態でもう一度Jenkinsジョブを実行すると10.0.0.1または10.0.0.3のどちらかのHostに処理が振られるはずです。
やってみましょう。


タスクの実行その2
f:id:tsunokawa:20141020142237p:plain
今度はリソースの空きがある10.0.0.3のHostで実行されました。


タスクの終了
f:id:tsunokawa:20141020142245p:plain
2つのタスクがどちらもCompleted Tasksに状態が変化しています。
これら2台に振られたJenkinsジョブが無事終了したことが分かります。


これでJenkinsジョブの分散処理環境が出来上がりました。
当初の課題であったcronやバッチ処理の一元化、可視化もJenkinsの分かりやすいUIにより解決します。
また、Mesosサーバーを横に増やしておけばJenkinsサーバーが重い!という課題も回避できそうです。