はじめに
Unix 系の OS には標準で cron という定期的にジョブ(コマンドやプログラム)を実行するための仕組みがあります。
処理するジョブが少ないうちは cron でどうにかなりますが、ジョブの数が増えてくると以下の様な問題が起こります。
- ジョブの数が多すぎて管理しきれない。
- 複数サーバでのジョブ管理が煩雑。
- ジョブ同士の依存関係の解決が困難。
- エラー時の監視機能が弱い。
Rundeck はこれらの問題を解決可能なツールです。Rundeck は次のような特徴があります。
- Web UI と CLI によるジョブの管理
- 複数サーバでのジョブ管理を一元化。
- 大量のジョブの管理が行いやすい Web UI
- cron と同じく CLI による管理も可能。
- 実行時間指定の書式は cron ベースなので移行コストも低い。
- 複数サーバでのジョブ管理を一元化。
- ジョブの構造化
- ジョブの階層構造の定義が可能。
- 依存関係も定義可能。
- エラー対応
- ジョブ開始・正常終了・異常終了時にメールやWebHookで通知可能。
CI 用のツールである Jenkins で同様の仕組みを構築したことはありますが、 Jenkins 自体がかなり大規模なものであるため、ジョブ管理のみなら Rundeck の導入をおすすめします。
インストール方法
筆者の環境
今回は以下の環境を前提にして進めます。
機能 | 名称 |
---|---|
マシン環境 | Amazon Web Service (AWS) EC2 t2.medium インスタンス |
OS | Amazon Linux (2015.09) |
Python | Python 2.7.10 |
SMTP サーバ | Gmail |
インストール
以下の流れでインストールします。
- Java 実行環境(JDK)のインストール
- yum によるインストール
- 設定ファイルの変更
- セキュリティグループの変更
- 起動
- 起動後の初期設定
Java 実行環境(JDK)のインストール
まず以下のコマンドで Java 8 の JDK をインストールします。
$ sudo yum install -y java-1.8.0
以下のコマンドでインストールされている JDK の一覧が確認できます。
$ sudo alternatives --config java
2 プログラムがあり 'java' を提供します。
選択 コマンド
-----------------------------------------------
*+ 1 /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java
2 /usr/lib/jvm/jre-1.8.0-openjdk.x86_64/bin/java
Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:2
今回は古いバージョンが既にインストールされていたので2を入力し、最新バージョンに変更します。次のコマンドで現在選択されている Java のバージョンが確認できます。
$ java -version
openjdk version "1.8.0_77"
OpenJDK Runtime Environment (build 1.8.0_77-b03)
OpenJDK 64-Bit Server VM (build 25.77-b03, mixed mode)
yum によるインストール
以下のコマンド Rundeck のリポジトリを登録後、yum で Rundeck をインストールします。
$ sudo rpm -Uvh http://repo.rundeck.org/latest.rpm
$ sudo yum install -y rundeck
設定ファイルの変更
/etc/rundeck/rundeck-config.properties
の以下の行をインストールしたサーバのIPアドレスもしくはホスト名に書き換えます。
編集前
grails.serverURL=http://localhost:4440
編集後
grails.serverURL=http://XXX.XXX.XXX.XXX:4440
セキュリティグループの変更
Inbound TCP 4440 へのアクセスを許可する必要があるため、AWS のコンソールより以下の設定を変更します。
EC2
-> Security Groups
-> (対象のマシンの) セキュリティグループを選択
-> Inbound タブ を選択
-> Edit
-> Add Rule
ルールは次の通りに入力します。
- Type: Custom TCP Rule
- Protocol: TCP
- Port Range: 4440
- Source: Anywhere (必要に応じて特定のIPを指定する)
Save
を選択してルールを保存します。
起動
以下のコマンドで Rundeck を起動します。
$ sudo service rundeckd start
設定ファイルで設定したURL (http://XXX.XXX.XXX.XXX:4440/
) にアクセスすると、ログイン画面が確認できます。
デフォルトでは User / Password ともに admin
でログインできます。
起動後の初期設定
管理者ユーザのパスワードを変更します。/etc/rundeck/realm.properties
に次の形式で記述されています。
<username>:<password>[,<rolename> ...]
デフォルトだと平文で記述されていますが、セキュリティ上これは良くない状態なので、以下のコマンドで暗号化した文字列を作成します。今回はついでに初期パスワードから新しいパスワードに変更しています。
$ java -cp /var/lib/rundeck/bootstrap/jetty-all-7.6.0.v20120127.jar org.eclipse.jetty.util.security.Password admin [任意のパスワード]
[任意のパスワード]
OBF:XXXXXXXXXXXXXXXXXXXXXXXX
MD5:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
CRYPT:XXXXXXXXXXXXX
出力された3つの文字列のうち一つを選択し、<password>
の部分に記述します。以下のように admin ユーザーに関する行を書き換えます。
```/etc/rundeck/realm.properties`
admin:MD5:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,user,admin,architect,deploy,build
一度ログアウトし、再ログイン時に上記のパスワードを入力すると新しいパスワードでログイン可能になります。
また、エラー時にメールで通知の設定もここで行います。
デフォルトの `/etc/rundeck/rundeck-config.properties` だと一部設定が記述できないので、Groovy の設定ファイルに変更し以下の内容を追記します。
$ sudo mv /etc/rundeck/rundeck-config.properties /etc/rundeck/rundeck-config.properties.bk
```/etc/rundeck/rundeck-property.groovy
loglevel.default="INFO"
rdeck.base="/var/lib/rundeck"
rss.enabled=false
dataSource {
dbCreate="update"
url="jdbc:h2:file:/var/lib/rundeck/data/rundeckdb;MVCC=true;TRACE_LEVEL_FILE=4"
}
grails {
serverURL="http://ホスト名:4440"
mail {
host="smtp.gmail.com"
port = 465
username="XXXXXX@gmail.com"
password="XXXXXXX"
props = ["mail.smtp.auth":"true",
"mail.smtp.socketFactory.port":"465",
"mail.smtp.socketFactory.class":"javax.net.ssl.SSLSocketFactory",
"mail.smtp.socketFactory.fallback":"false"]
}
}
また、/etc/rundeck/profile
を以下のように書き換えます。
...
-Drundeck.config.location=/etc/rundeck/rundeck-config.properties \
...
...
-Drundeck.config.location=/etc/rundeck/rundeck-property.groovy \
...
以下のコマンドでサービスを再起動します。
$ sudo service rundeckd restart
使い方
プロジェクトの作成
今回はサンプルとして sample-project
というプロジェクトを作成します。New Project
をクリックすると新規プロジェクト作成画面になります。
以下の項目を設定します。
- Project Name
-
sample-project
を入力。
-
- Description
-
This is a sample project.
を入力。
-
他は特に変更する必要なし。別マシンでジョブを実行したい場合は、Default Node Executor
や Default Node File Copier
で SSH や SCP に用いる認証鍵の設定する。
その後 Create
をクリックしプロジェクトを作成。
新規ジョブの作成
以下のジョブを作成してみる。
- echo コマンドで画面に文字列を定期的に出力する
- 引数ありの Python スクリプトの実行
- 実行時にエラーになる Python スクリプトを実行しメール通知を行う
echo コマンドで画面に文字列を定期的に出力する
毎分 0 秒に Hello Job!
を出力するジョブを作成してみる。Create New Job を選択し、以下の通りに入力する。
- Job Name:
-
echo sample
を入力。
-
- Decription:
-
echo コマンドで画面に文字列を定期的に出力する。
を入力。
-
- Workflow:
-
Node Steps
でLocal Command
を選択。- Command に
echo "Hello Job!"
を入力。 - Step Description に
echo step
を入力。
- Command に
-
Save
で保存。
-
- Schedule to run repeatedly?:
-
crontab
を選択し、0 * * * * ? *
を入力。
-
他はデフォルトのままでよい。ページ下部の Create をクリック。これで毎分0秒に Hello Job!
が出力される状態となった。実行結果は Activity for this Job -> recent -> (ジョブID)
で確認できる。 Log Output
を選択すると、 Hello Job!
と出力されたのが確認できる。
動作確認が終了したら、定期実行を解除する。Action -> Edit this Job
を選択し、Schedule to run repeatedly?
を No
にして画面下部の Save
をクリックする。これでジョブ詳細画面の Run Job Now
をクリックしないかぎり再実行されなくなった。
引数ありの Python スクリプトの実行
文字列を1つ引数として受け取り、"こんにちは [入力した引数] さん!" を出力する Python スクリプトを実行するためのジョブを作成する。
ますサーバ内で以下のスクリプトを作成する。尚使用している Python はデフォルトの 2 系を前提としていますが、Python 3 を用いる場合は print("XXX")
としてください。
$ sudo mkdir -p /work/arg_print
$ sudo chmod 777 /work
$ sudo chown rundeck /work/arg_print
以下のスクリプトを作成し、所有者を rundeck
ユーザにします。
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import sys
print "こんにちは " + sys.argv[1] + " さん!"
$ sudo chown rundeck /work/arg_print/arg_print.py
次はジョブを作成します。Webのインターフェースから、プロジェクト内で Job Action -> New Job
を選択します。
- Job Name:
-
python arg sample
を入力。
-
- Decription:
-
"こんにちは [Name] さん!" を出力するジョブ。
を入力。
-
- Options:
-
Add an option
を選択。- Option Name:
Name
- Description:
User name
- Default Value:
Admin
- Required:
Yes
- Option Name:
- 上記を入力後
Save
をクリック。
-
- Workflow:
-
Node Steps
でLocal Command
を選択。- Command に
python /work/arg_print/arg_print.py ${option.Name}
を入力。 - Step Description に
arg print step
を入力。
- Command に
-
Save
で保存。
-
他はデフォルトのままでよい。ページ下部の Create をクリック。Run Job Now
をクリックすると、Name
に "Admin"
が代入されて こんにちは Admin さん!
が出力される。
ジョブの詳細ページで Name
の項目をデフォルトの Admin
から RUNDECK
に変更し Run Job Now
をクリックすると、Name
に "RUNDECK"
が代入されて こんにちは RUNDECK さん!
が出力される。
実行時にエラーになる Python スクリプトを実行しメール通知を行う
$ sudo mkdir -p /work/error_sample
$ sudo chown rundeck /work/error_sample
以下のスクリプトを作成し、所有者を rundeck
ユーザにします。
#!/usr/bin/env python
#-*- coding:utf-8 -*-
raise ValueError("sample")
$ sudo chown rundeck /work/error_sample/error_sample.py
次はジョブを作成します。Webのインターフェースから、プロジェクト内で Job Action -> New Job
を選択します。
- Job Name:
-
python error sample
を入力。
-
- Decription:
-
例外処理時のメール送信テスト。
を入力。
-
- Workflow:
-
Node Steps
でLocal Command
を選択。- Command に
python /work/error_sample/error_sample.py
を入力。 - Step Description に
error step
を入力。
- Command に
-
Save
で保存。
-
- Send Notification?:
Yes
- On Failure:
- Send Email: 送信先のメールアドレスをカンマ区切りで指定。
- Subject:
Python error test
- Attach output log: チェック状態にする。
ページ下部の Create をクリック。その後 Run Job Now
をクリックするとジョブが実行され、エラー内容の通知が送信先のメールアドレスに送られます。
終わりに
今回は以下の項目については割愛しています。
- 他サーバ上でのジョブ実行方法。
- 秘密鍵を使った SSH の通信が通るよう設定し、秘密鍵ファイルを登録すれば可能になります。
- 複数ジョブの連続実行
- ジョブの繰り返し設定
ただしこれらの設定は直感的にGUIで設定可能です。
Rundeck を活用して、快適タスク管理生活をエンジョイしましょう。