BLOGSpeee開発陣による技術情報発信ブログです。インフラ・ネットワークTweet初投稿になります。アルゴリズムの探求者です。現場に近い話題で情報発信していければと思っています。お願いします!さて、今回は「HomeRoomで実践中のJenkinsバッチジョブ管理Tip集」というタイトルでお送りします。Jenkinsと言えば、もう今や知らないエンジニアは居ないだろうという地位を確立したCIツールですが、CIツールとしてではなく、バッチジョブ管理に使おうという活用法があります。WEB上を検索すると、そのような使い方をしているという話は結構聞きますし、明らかにバッチ管理用と思われるJenkinsプラグインも多数あります。具体的なジョブ設定にまで踏み込んだ情報は意外に少ないなという印象です。HomeRoomはSpeeeで運営している賃貸情報サイトです。物件情報を毎日最新情報に更新するためのバッチを始め、アクセス分析やデータバックアップなど、様々なバッチが裏で稼働しています。それらのバッチはcron上に乗っていましたが、2013年8月に、それらのバッチを全てJenkins上に移行し、より見やすいバッチ管理と、より精度の高いログ収集とエラー検知、有事の際の素早いアラート通知を実現しました。そこで今回は、HomeRoomで運用しているバッチジョブ管理用Jenkinsで実際に使用している設定をいくつか、Tips形式で紹介したいと思います。Jenkinsの見た目を変えようバッチジョブ管理用のJenkinsを構築する上で、通常のCIツールとしてのJenkinsと最も異なる点は、「Jenkinsや登録したジョブが止まるとトラブルに繋がる」という点です。システムの観点から安定性を追求することも必要ですが、加えて、Jenkinsを操作する人間がミスを起こしにくい環境を作ることも重要になってきます。いうことで、まずは稼働中のCI用Jenkinsと間違えないよう、見た目を変えましょう。Pluginを使います。デザインにこだわりがなければ、TOPBARの色を変えるだけでも効果的です。Pluginに設定するだけです。リモートホストでのバッチ起動バッチ処理を実際に起動するホストにJenkinsも立てる場合は楽なのですが、ネットワーク・セキュリティやリソースの観点から別ホストにJenkinsを立てるケースも多いでしょう。その場合は、Jenkinsからリモートホスト上のバッチを制御する必要があります。その手法として、主に2パターンあります。Jenkinsスレーブをバッチサーバに立てて、スレーブでジョブを実行するマスターからSSHでバッチを直接制御するどちらが良いかは一概には言えないところかと思います。スレーブ方式SSH方式Jenkinsジョブ設定が簡潔バッチサーバを複数構築して負荷分散をしたい場合にジョブ振り分けをJenkinsに任せることができるバッチサーバのリソース(特にメモリ)をJenkinsが奪わない(環境にも依るが)Jenkinsが落ちても実行中のバッチは処理継続するHomeRoomでは、特に最後の「Jenkinsが落ちても実行中のバッチは処理継続する」という部分を重要視して、SSH方式を採っています。Jenkinsは元々CIツールですので、自身が作ったプロセスは極力掃除して残さないような動作をします。Jenkins自身が落ちると、スレーブプロセスやスレーブが立ち上げたジョブプロセスもkillを試みます。CIツールとしてみたときにはありがたい機能ですが、バッチジョブ管理としては、バッチプロセスに無条件でシグナルを送るのは好ましくありません。clientプロセスにはkillが届きますが、SSHリモートで作成されたプロセスは生き残ります(設定にも依ります)。特定のユーザ権限でないと動かないバッチも多いかと思いますが、そうなるとJenkinsへの権限委譲についても考慮する必要が出てきます。一般化すると、「JenkinsはhostAのjenkinsuserで動いていて、hostBのbatchuserでバッチを起動する」という状況を実現するために権限設定をどうするかを決めるということになります。ここではSSH方式を採用しているHomeRoomでのパーミッション制御について紹介します。図を見ていただければわかるかと思いますが、Jenkinsからjenkinsuser@hostBにログインし、hostB上でsudoによりbatchuser権限を取得します。このとき重要な事は、Jenkinsは画面上からコマンドを記述して実行することができるため、sudo設定で単純にALL権限を付与してしまうと、委譲する権限が強すぎるということです。Jenkinsがbatchuser@hostB権限で実行できるのは特定のバッチの起動のみ、という権限管理をすべきです。これを踏まえ、HomeRoomでは以下のようにsudoer設定をしています。BATCH_CMND1行目は、端末からの利用でない場合でもsudoの使用を許可する設定です。デフォルト設定次第ではこの設定がないと動作しません。2,3行目で、特定のバッチ起動コマンドだけ、batchuserとしてパスワードなしでsudoできるよう設定しています。あとは、/path/to/batch.shのWrite権限がjenkinsuserに無いことを確認すれば、最小限の権限移譲を実現できます。ジョブの粒度バッチ処理をJenkinsジョブに落としこむときに、ジョブの粒度が問題になると思います。処理A,B,Cを順番に実行するバッチがあった時に、1つのJenkinsジョブの中で3つの処理を実行する各々の処理を実行するジョブを計3つ作り、Jenkins上で依存関係を貼るという2つの選択肢があります。この問題に対しては、「バッチがエラーになった場合のリカバリー方法」で決めるのが良いと思います。「処理BやCがエラーになった場合は処理Aからやりなおし」という性質のバッチであれば、1つのJenkinsジョブにまとめてしまうべきです。その方がJenkins設定も簡潔になります。逆に、「処理Bでエラーになったら処理Bからやりなおせばよい」という性質のバッチであれば、処理AとBは別のジョブとして設定すべきです。すれば処理Bでエラーになったら処理Bジョブを、処理Cでエラーになったら処理Cジョブを再実行するという運用もJenkinsからワンクリックで可能になりますし、場合によっては「処理Bでエラーになったら処理Bジョブを自動で再実行する」という仕組みを構築することさえ可能です。エラー検知を厳しくこれはJenkins独特のノウハウというよりはバッチジョブ管理ツールを活用するための必須要件かと思いますが、ツールが「ジョブの成否」を判断する必要があります。今までcronで起動していたバッチをJenkinsに乗せる場合、Jenkinsが成否を判断できるようになっていない場合がほとんどだと思いますので、必要に応じて修正を入れましょう。/path/to/batch.shこの「e」オプションで正常稼働できるように修正していくと良いと思います。「e」オプションはスクリプト内の各コマンドでリターンコード0以外が返されると、その時点でスクリプトの実行を止め、スクリプト実行自体もそのリターンコードを返すというものです。例外機構の整ったプログラミング言語で書かれたものは想定外のエラーが発生した時点で実行を止めるものが多いと思いますが、「e」オプションはシェルスクリプトもその挙動に近づけるというイメージでしょうか。途中で止まった場合はリターンコード0以外が返りますので、Jenkinsもエラーと判定してくれます。「e」オプション付きでJenkinsにバッチを乗せると、「実は今までエラーになっていたけど気づいていなかった」というバッチに出会うケースがかなり高確率であります。一度このホラーを体験してみてくださいw「x」オプションはスクリプト内のコマンドを標準出力に出力してくれるコマンドです。「e」オプションをつけてエラーが発生した場合は「どこでエラーになったのか」という情報が重要ですので、「x」オプションも合わせてつけておくのがオススメです。「特定のファイルの更新をチェックしておき、更新されたらジョブを起動する」というように、厳密な意味でのトリガーがJenkinsの外にある場合です。HomeRoomでも「不動産会社様から最新の物件情報をFTPで送信していただけるので、ファイルが置かれたことを検知したらDB反映バッチを起動する」という、よくあるパターンのバッチがあります。Jenkinsは実行されたジョブに対して成否を判断するため、「本来トリガーされるべきジョブがトリガーされていない」というエラーは存在しないのです。そのため、Jenkinsの外にトリガーがある場合は、「トリガーされたか」を確認する必要が別途出てきます。Pluginを使って「トリガーされたか」チェックジョブを設定しました。ファイル更新チェックジョブ側で、更新を確認したら、バッチ本ジョブをキックすると同時に、以下のようにキック時刻を記録します。Pluginのアーカイブ対象に登録します。別途、「トリガーされたか」チェック用ジョブを作成し、「定期的に実行」で夜、起動します。Workspace」を選択し、先ほどのジョブからファイルを持ってきます。1してやることにより、チェックジョブがエラーとなり、「今日はまだトリガーされてないよ!」というアラートを飛ばすことができます。タイムアウトを設ける「エラー検知を厳しく」のところで述べたように、「e」オプションさえつけていれば、エラーが上がればすぐにそれをJenkinsが検知することができますが、これでは「何らかの不具合でコマンドが返ってこない」というケースには対応できません。HomeRoomでも、ディスクが物理的に故障していてプロンプトがずっと返ってこないという状況になり、バッチが終わらないということがありました。このような状況でもアラートを飛ばすためにはタイムアウトを設けるのが無難です。Pluginを使います。さいごに今回はHomeRoomでJenkinsをバッチジョブ管理ツールとして利用する際に実施した設定をいくつか紹介させていただきました。今回紹介した以外にも様々な工夫をしていますので、またの機会に。Jenkinsをバッチジョブ管理ツールとして利用するというのは、ある意味では本来の使い方から外れた使い方とも言えますので、工夫して解決しなければいけない課題があることも事実ですが、このようにノウハウを共有してより良いJenkins活用の参考にし合えればと思います。Speeeエンジ...2018-08-08広告レコメンドにおける多腕バンディット問題の適用とその解法Speeeエンジニアの義田@yoppiblogです。今年7月にSpeeeが運営...2017-03-28魔法の世紀の片鱗(勤怠打刻を頑張らない話)Tei1988です。参加してきました月別アーカイブスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。