2020年にJenkinsをAWS上で動かす選択肢としてECSを強く推したい

Kento Ohgi
Dec 4, 2020

--

この記事はDMMグループ Advent Calendar2020の4日目の記事です。
最近はノリと勢いで組んだお家k8sが無事置物になっている @2357giがお送りします。ワイワイ。

Jenkinsのお話です。
EC2上で動いていたJenkinsを、ECS上でいい感じに動くようにするお仕事をしているので紹介したいと思います。
現在作業中の内容ですので、もしかすると後々変更が入るかもしれず、その際にはこの記事も追って修正します。そして、一通り構成し終わったらまたQiita等に移すかもしれません。モチベがあれば…。

この記事で触れる内容
・ECS上でJenkinsを動かすアーキテクチャ
・Jenkins on ECSのメリット
・構築するときの注意点

この記事で触れない内容
・Jenkinsそのものの説明
・ECSそのものの説明

既存の構成とその問題点

弊プロジェクトではJenkinsがバッチスケジューラとして活躍しています。ひと目で各バッチの健康状態が見通せるUIに、バッチジョブ自体の詳細や、パラメータ付きバッチの操作といったポイントから、Jenkinsはバッチスケジューラとしてはとても優秀です。
しかし、今の私達のJenkinsはmaster nodeが一台のEC2の上で動いており、masterの操作によりworker用EC2が立ち上がりその中でバッチジョブが実行されるという環境になっております。

この構成はgit cloneからバッチが始まるので遅くてシンドいとか、Jenkins本体やJenkinsのプラグインのバージョンの面倒が見れておらず、入れたいプラグインが入れられないとか、
なによりmaster nodeがHA構成になっておらず、障害点となりうるので早急になんとかすべきなどと言った問題が詰まっておりました。

JenkinsをやめてAWS Batch等新しいバッチスケジューラを使用することや、ECSのtask schedulerを使用するといった手法が候補に上がったのですが、今回は様々な理由からJenkinsごとECSで動かす方針にしました。

新たな構成とそのメリット

Jenkinsのmaster nodeをECS Serviceで動かし、バッチジョブは一つ一つECS タスク定義を作成し、masterによりECS Taskとして実行することによりバッチジョブを実行することにしました。

① Developerがバッチを実行, もしくは定期的にバッチが実行される
② バッチごとに定義されたタスク定義を参照し
③ タスクを生成し、バッチを実行する

だいたいこのような流れになります。
Jenkins master nodeをECS Serviceで運用することにより、下記の恩恵を得ることができます。

ECS Serviceによる高可用性, 耐障害性
EFSを用いることによった設定ファイルの永続化
cfnやterraformにより複製可能な環境

コスト面でもEC2上でmaster/workerを実行する既存環境よりも優位性があります。
また、ほかにも弊チームではECS上でプロダクトを運用しており、ECSに対する知見が溜まっていたことも選択した理由の一つとして挙げられます。
上記の点からECS等を既にお使いであり、且つそこそこボリューミーなバッチ処理が動いているJenkinsのモダンな移行先をお探しであればAWSでJenkinsを動かす構成の選択肢としてECSは強く推せます
(EKSとjenkins x k8s…?たのしそうですけど弊プロジェクトはk8sやってないんで…)

先に上げた3つの恩恵と、その勘所を解説していきます。

ECS Serviceによる高可用性, 耐障害性

コンテナ数1のjenkinsを実行するECS タスクを定義し、そのECS タスクを実行する複数AZに跨ったECS Serviceを定義します。
これにより、AZ障害等発生したとしても速やかに新しいAZに回復してくれます。
ただし、ここでポイントなのが
Jenkins Master nodeは並列稼働を許さない(一つの設定ファイルを使用するJenkins Master nodeが複数立ち上がると破綻してしまう)ので、そうならないように気を配る必要があります。
特にECS Serviceのローリングアップデートなどではタスク数が2つ以上にならないようにする必要があります。
具体的にはECS Serviceを定義する際に最小ヘルス率を0に、最大率を100%にすることで解決することができます。
AWS Compute Blog
Amazon ECS launches new deployment capabilities; CloudWatch metrics; Singapore and Frankfurt regions

AWS ConsoleのECS Service新規作成画面

cloudFormations, Terraformでも上記の項目があるのでしっかりと設定しましょう。

EFSを用いた設定ファイルの永続化

Jenkins master nodeは設定ファイルを内部に持ち、その設定ファイルでユーザーを管理したり、設定ファイルを元にジョブを実行したりします。よってステートフルでありコンテナとして動かすには適していないのですが、逆にその設定ファイルだけ外出ししてあげればなんとかなります。

そして、ECS Fargate 1.4にてEFSをコンテナにボリュームマウントする機能が追加されました。
これにより、設定ファイルを外部のEFSにて永続化することが可能となりました。

もしAZ障害が発生し動いていたJenkins Master Nodeがお亡くなりになられたとしても、別のAZで再び先程まで参照していたJenkinsの設定ファイルを参照したJenkins Master Nodeが再び立ち上がります。

既存のJenkins Masterが落ちたあと別のAZで回復したJenkins Masterが再び同じ設定ファイルを参照する図

EC2で動くJenkins Master nodeをHA構成にする手法としてJenkins Master Nodeをインスタンス数1のオートスケーリンググループに登録し、同じ用に設定ファイルをEFSに外だしする手法もありましたが、あわよくばEC2の管理も丸投げしたいですよね。個人的にはECSがおすすめです。

cfnやterraformにより複製可能な環境

まんまです。弊社のような様々な事業部が存在するのであれば横展開も考えられて良いですね。

おわりに

JenkinsをAWSで動かす際には今はこのような選択肢もあるんだなと思っていただければ幸いです。まだ実際に作成中ですので中途半端な記事にはなりますので、一通りきりがついたら再びアップデートしようと考えています。
私は今年弊社に新卒入社したばかりのぺーペーですが、そんな私でも主導的にアーキテクチャを考え提案し、すり合わせ、実際に実装するといった裁量のある仕事ができています。
もし弊社や弊社のSREチームに興味がございましたらTwitter@2357giまでお気軽にご連絡ください。最近は新卒採用業務や新卒研修業務にも携わる様になってきたので、そのあたりでも詳しいお話ができるかもしれません。是非。

DMM Advent Calendar2020 明日は@mecaotaさんがVue2+Typescript+Vuex+Vue-apolloでコードが破綻しかけた話をしてくださるそうです。楽しみですね。

--

--

Kento Ohgi
Kento Ohgi

No responses yet