Amazon RDSとELBでRundeckをクラスタ構成にして履歴をS3とElasticsearchに入れて可視化する
Rundeckをクラスタ構成にする
DevIOでは既に複数回に渡ってRundeckのご紹介をしていましたが、今回は、クラスタ構成にして高可用性を確保したいと思います。
以下は完成イメージです。
まずは基本セットアップ
まずはじめにRundeckの単体起動を確認したいと思います。今回は、Amazon Linuxを用いています。また、インスタンス起動時にIAM RoleでPowerUserを指定しました。後でS3コマンドなどを実行するときにキーをベタ書きしないためです。
$ sudo yum update -y $ sudo rpm -Uvh http://repo.rundeck.org/latest.rpm $ sudo yum install rundeck -y $ sudo service rundeckd start Starting rundeckd: [ OK ] $ sudo chkconfig rundeckd on $ sudo chkconfig rundeckd --list rundeckd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
これで自動起動するようになりました。しかし、このままではサイトが正しく表示されません。
設定ファイルを編集してサイトのホームとなるURLを指定します。
$ cd /etc/rundeck/ $ ls admin.aclpolicy jaas-loginmodule.conf realm.properties apitoken.aclpolicy log4j.properties rundeck-config.properties cli-log4j.properties profile ssl framework.properties project.properties $ sudo vi rundeck-config.properties #loglevel.default is the default log level for jobs: ERROR,WARN,INFO,VERBOSE,DEBUG loglevel.default=INFO rdeck.base=/var/lib/rundeck #rss.enabled if set to true enables RSS feeds that are public (non-authenticated) rss.enabled=false # change hostname here grails.serverURL=http://localhost:4440 dataSource.dbCreate = update dataSource.url = jdbc:h2:file:/var/lib/rundeck/data/rundeckdb;MVCC=true;TRACE_LEVEL_FILE=4 grails.serverURL=http://ec2-XXX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com $ sudo service rundeckd restart Stopping rundeckd: [ OK ] Starting rundeckd: [ OK ]
これで正しく表示されるようになりました。
ELB配下で実行できるようにする
単体でRundeckの動作確認ができましたら次はELB配下に置いてみましょう。先ほど構築したインスタンスを新規作成したELBの配下に登録します。次に、Rundeckの設定ファイルを編集してホームとなるURLをELBのアドレスに変更します。ELBは、jsessionidによるスティッキーセッションとします。
ヘルスチェックはRundeckの存在するアドレスを指定します。
以上により、ELBのアドレスで表示することができました。実運用では独自ドメインなどを指定することになると思います。
データベースにRDSを指定する
このまま複数EC2インスタンスにするとデータベースをそれぞれ持つことになってしまうので、RDS(MySQL)を指定して共通の設定を見るように変更します。まずはじめにVPC内のプライベートサブネット側にRDSを構築します。そして、Rundeckが入っているインスタンスからRDSにアクセスをしてみます。アクセス確認できたら空のデータベースを作成します。
$ sudo yum install mysql -y $ mysql -u mydbadmin -p -h mydb.cjazjhqtzXXX.ap-northeast-1.rds.amazonaws.com mysql> create database rundeck; Query OK, 1 row affected (0.00 sec) mysql> grant ALL on rundeck.* to 'rundeckuser'@'172.16.0.0/16' identified by 'rundeckXXXXXXXX'; Query OK, 0 rows affected, 1 warning (0.01 sec) mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | rundeck | +--------------------+ 2 rows in set (0.00 sec)
次に、RundeckからRDSに接続するための設定を記述します。
$ cd /etc/rundeck/ $ sudo vi rundeck-config.properties dataSource.dbCreate = update dataSource.url = jdbc:mysql://mydb.cjazjhqtzXXX.ap-northeast-1.rds.amazonaws.com/rundeck?autoReconnect=true dataSource.username=rundeckuser dataSource.password=rundeckXXXXXXXX $ sudo service rundeckd restart Stopping rundeckd: [ OK ] Starting rundeckd: [ OK ]
変更したRDSに対して実際にアクセスされているのか確認してみたいと思います。
$ mysql -u rundeckuser -p -h mydb.cjazjhqtzXXX.ap-northeast-1.rds.amazonaws.com mysql> use rundeck; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show tables; +----------------------------+ | Tables_in_rundeck | +----------------------------+ | auth_token | | base_report | | execution | | log_file_storage_request | | node_filter | | notification | | orchestrator | | plugin_meta | | project | | rdoption | | rdoption_values | | rduser | | report_filter | | scheduled_execution | | scheduled_execution_filter | | storage | | workflow | | workflow_step | | workflow_workflow_step | +----------------------------+ 19 rows in set (0.00 sec)
これで、Rundeckに関する設定などは共通のデータベースを参照するようになりました。
実行ログをS3に保存する
Rundeckの設定をRDSに書き込むことができましたので、次はログ関連をS3に格納したいと思います。Rundeckのプラグインを用います。
まずは、下準備をします。JDK8とGitとGradleの環境を整えます。sdkmanというSDKの簡単導入ツールを使っています。
$ curl -s "https://get.sdkman.io" | bash $ source "$HOME/.sdkman/bin/sdkman-init.sh" $ sdk version ==== BROADCAST ================================================================= * 06/07/16: Final announcement test. * 06/07/16: Test again. * 06/07/16: Testing ================================================================================ SDKMAN 5.0.0+51 $ sdk install gradle Downloading: gradle 2.14 In progress... ######################################################################## 100.0% Installing: gradle 2.14 Done installing! Do you want gradle 2.14 to be set as default? (Y/n): y Setting gradle 2.14 as default. $ sudo yum install -y git $ sudo yum install -y java-1.8.0-openjdk-devel $ 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
下準備ができましたので、ブラグインをインストールします。
$ git clone https://github.com/rundeck-plugins/rundeck-s3-log-plugin.git $ cd rundeck-s3-log-plugin/ $ gradle clean build $ cd build/libs/ $ ls rundeck-s3-log-plugin-1.0.3.jar $ sudo find / -name libext /var/lib/rundeck/libext $ sudo cp rundeck-s3-log-plugin-1.0.3.jar /var/lib/rundeck/libext $ cd /etc/rundeck/ $ sudo vi rundeck-config.properties rundeck.execution.logs.fileStoragePlugin=org.rundeck.amazon-s3
ログの出力先としてS3バケットを指定しました。このバケット名は世界中でユニークである必要がありますので気をつけてください。バケットを作成しておきましょう。
$ aws s3 mb s3://satoshi1977-rundeck-logs make_bucket: s3://satoshi1977-rundeck-logs/ $ sudo vi framework.properties #name of the bucket framework.plugin.ExecutionFileStorage.org.rundeck.amazon-s3.bucket=satoshi1977-rundeck-logs #path to store the logs framework.plugin.ExecutionFileStorage.org.rundeck.amazon-s3.path=logs/${job.project}/${job.execid}.log
全ての設定を書き終わったらサービスを再起動してブラウザからジョブを実行してみましょう。以下のようにログが吐き出されてることが確認できれば成功です。
$ aws s3 ls satoshi1977-rundeck-logs/logs/MyProject1/ 2016-07-07 04:06:41 860 3.log.execution.xml 2016-07-07 04:06:41 972 3.log.rdlog 2016-07-07 04:06:41 723 3.log.state.json
EC2との連携を管理する
ノードとして動かしたいEC2インスタンスと連携するプラグインも入れてみます。
$ cd $ git clone https://github.com/rundeck-plugins/rundeck-ec2-nodes-plugin.git $ cd rundeck-ec2-nodes-plugin/ $ cd build/libs/ $ ls rundeck-ec2-nodes-plugin-1.5.3-SNAPSHOT.jar $ sudo cp rundeck-ec2-nodes-plugin-1.5.3-SNAPSHOT.jar /var/lib/rundeck/libext
基本的にはこれだけです。Rundeckのサービスを再起動してから、新しいプロジェクトを追加してみてください。オプションが新たに表示されます。
ログをストリーミングしたい
S3にログを吐き出すのは永続化という意味ではとても良いですが、リアルタイムに流して検知したいこともあるかと思います。そこで、logstashプラグインを使ってみます。
$ git clone https://github.com/rundeck-plugins/rundeck-logstash-plugin.git $ cd rundeck-logstash-plugin/ $ sudo cp LogstashPlugin.groovy /var/lib/rundeck/libext/
インストールしたら設定を追記します。Rundeckと同じサーバーのLogstashを指定しています。
$ cd /etc/rundeck/ $ sudo vi rundeck-config.properties rundeck.execution.logs.streamingWriterPlugins=LogstashPlugin $ sudo vi framework.properties framework.plugin.StreamingLogWriter.LogstashPlugin.port=9700 framework.plugin.StreamingLogWriter.LogstashPlugin.host=localhost
Logstashをインストールします。
$ wget https://download.elastic.co/logstash/logstash/packages/centos/logstash-2.3.3-1.noarch.rpm $ sudo rpm -ivh logstash-2.3.3-1.noarch.rpm $ sudo service logstash start $ sudo chkconfig logstash on $ sudo chkconfig logstash --list logstash 0:off 1:off 2:on 3:on 4:on 5:on 6:off $ /opt/logstash/bin/logstash -e 'input { stdin { } } output { stdout {} }' hello world Settings: Default pipeline workers: 1 Pipeline main started 2016-07-07T06:55:14.764Z ip-172-16-0-184 hello world
Elasticsearchと連携します。
Logstashのプラグインをインストールします。Amazon Elasticsearch Serviceとの連携までやってくれます。素晴らしい。
$ sudo /opt/logstash/bin/logstash-plugin install logstash-output-amazon_es Validating logstash-output-amazon_es Installing logstash-output-amazon_es Installation successful
事前にElasticsearchにアクセスできることを確認しておいてください。
$ curl -XGET search-myelastic-heic6rbqefquujhb3yuosXXXXXXX.ap-northeast-1.es.amazonaws.com { "status" : 200, "name" : "Jamal Afari", "cluster_name" : "XXXXXXXXXXXX:myelastic", "version" : { "number" : "1.5.2", "build_hash" : "62ff98XXXXXXXa0c45860bebb259e21XXXXXXXXXXXX", "build_timestamp" : "2015-04-27T09:21:06Z", "build_snapshot" : false, "lucene_version" : "4.10.4" }, "tagline" : "You Know, for Search" }
LogstashとElasticsearchが連携するために設定ファイルを書きます。
$ cd /etc/logstash/conf.d $ vi rundeck-logstash.conf input { tcp { port => 9700 tags => ["rundeck"] type => "rundeck" } } output { amazon_es { hosts => ["search-myelastic-heic6rbqefquujhb3yuosXXXXXXX.ap-northeast-1.es.amazonaws.com"] region => "ap-northeast-1" index => "rundeck" } }
動作確認
それでは準備が整いましたので、Rundeckで実行したジョブのログが、Logstash経由でElasticsearchに格納されているか確認してみましょう。まずは、Amazon Elasticsearch Serviceの管理画面で確認してみます。
たしかにデータが入っていますね!Kibanaでも見てみましょう。
見た目をゴニョゴニョすると、、、、、
ステキです。
まとめ
ジョブスケジューラのRundeckについて、ELBとRDSを利用することで高可用性を確保することができました。次に、ログをS3やElasticsearchに格納することで、ジョブの結果を画面で直感的に把握することができました。