見出し画像

管理画面としてのJenkins

Web系開発のコンテキストにおける話です。

Jenkins を運用しているとよくあるパターンとして、最初はエンジニアが実行する単発のバッチ処理や、システム的に重要な定期バッチ処理のために使われているのだが、そのうち、CSやマーケティングなど、エンジニア以外の様々な業務を受け持つ人によって実行されるようになる。

それでそのうち、たとえば権限管理の問題とかが出てきて、「そもそもJenkinsはシステム管理者が使うものであって、それ以外の人が使うものは管理画面を用意すべきなのでは?」という話が出たりする。

個人的には、管理画面を作れるならもちろんベストなのだけど、意外と難しかったり面倒だったりするのに対して、実際Jenkinsは管理画面的な用途でも結構便利なので、わかって使う分には良いんじゃないか、と思っている。

管理画面から実行するような処理は、エンドユーザーが行うものに比べてずっと時間がかかるものが多く、それらは非同期処理として実現したい。しかし、Webの管理画面は、非同期処理を表現するのに少し手間がかかると思う。

たとえば僕が普段使う Ruby on Rails の場合で話す。非同期処理そのものは Active Job という仕組みを Rails が用意している。Active Job は非同期ジョブのための共通インターフェイスのようで、それに適合するライブラリがいくつかある。そこから一つ選んで、対応するデータストアを用意してデーモンとして実行すれば、非同期処理はわりとすぐに実現できる。(たとえば、sidekiq というライブラリは、バックエンドに Redis の Sorted Set を使っている。ちなみに Active Job を使わずに直接 sidekiq を使うことも可能である)

しかし、実際に管理画面としての要件を考えると、非同期処理として実行するだけでは足りない。まず、その処理が実行中なのか、成功したのか、失敗したのか、失敗したならその理由は何か、という情報が必要である。このような要件を満たすのは意外と面倒だ。たとえば sidekiq は実行状況を確認できる Web UI を持っているが、全ての非同期処理を一覧にしているだけなので、その中でどれが自分が実行したジョブなのかをパッと見分けるのは難しい。なので、自分でそういう画面を作ることになるのだが、これをやってるとなんだか非同期処理の再発明をしているような気分になってきて、割と面倒だと思う。
(ここから Active Job を例にして話すが、読み飛ばしてもらって構わない。Active Job のレコードは基本的に検索するような用途を想定していないので、job_id から引くことくらいしかできず、別途でこれこれの操作の実行履歴みたいなテーブルを持つ必要がある。そこに実行者のIDと job_id を保存しておけば、実行中か成功か失敗かくらいはわかるだろうけど、失敗した理由とその時吐いたログみたいのは Job 側には保持されてないので、結局実行履歴を表すテーブルにはそういうアプリケーションよりの情報を持つことになる。)
また、できれば処理が終了したときには通知してほしいけれども、これもポーリングするのかWebSocketをはるのか、いずれにしても何かと面倒なわけだ。

...というところまで考えると、これって Jenkins が全部実装してくれてるよな? という気持ちになってくる。Jenkins は Web UI が存在していて、ジョブの種類という概念があって、どれが自分が実行したジョブかがわかって、実行中か成功か失敗かわかるし、実行するとコンソールログが出続けるし、実行が終わればリロードしなくてもボタンの色が変わって終了したことがわかる。

もっとも、JenkinsとWebアプリケーションの接続については別に考える必要がある。例えば Rails アプリケーションであれば Rake Task として実行可能なタスクを提供することができ、ジョブの設定にコマンドを書くだけで完成だ。とはいえ、Jenkins サーバー上に Rails をデプロイして実行するのはいかにも前時代的な感じもある。Kubernetes や ECS のようなコンテナ環境の場合、実行自体はそちらのクラスターの中で行いたい。すると、Kubernetes の CronJob や、ECS の Task として実行しつつ、標準出力をJenkins上の出力につなげて、実行が終了したらJenkins側も終了するような仕組みが必要になる。こういうツールは前職(ECS)でも現職(Kubernetes)でもSREが用意してくれていた。こういうところに複雑さを押し付けておいてWeb開発者がラクをしてる感は若干ある。とはいえ、こういうツールはサービスごとに作らなくてすむし、サービスの言語に非依存だし、Jenkins以外でも使えるので、一度作れば便利に使い続けられる。

そんなわけで、個人的には Jenkins が管理画面してくれるのは大いにアリだと思っている。まあ、当たり前だけど Jenkins は何かの Write 系を実行する場であって、Read は別のツールを使うことになるので、操作が分断されていて不便感は否めないが。(そういえば Read はそれはそれで redash の管理画面化みたいな問題を目にしたことがある気がするな...。)

noteの通貨流通量を増やしていきたい!!