ホワイトプラスの基盤チームのakaimoです。
lenetではwebサービスの実行にGKEを使用していて、リリースを行うにはDocker Imageを作成する必要があります。また、リリースの前には他にも行わなければならない処理があり、それらを合わせてGCPのCloudBuildで実行しています。
歴史のあるサービスであることもありリポジトリが巨大化していて、CloudBuildの実行に15分以上かかっていました。この状態だと、不具合修正など緊急性の高いリリースの場合でも長い時間待つ必要があり、不具合の影響が大きくなってしまうリスクがありました。
上記リスクの解消、日々の開発体験の向上を目指し改善に取り掛かかった結果、4分まで短縮することができたため改善内容を紹介します。
主な処理内容
CloudBuildではインスタンスに8コアの N1_HIGHCPU_8
を使用し、主に以下の3つの処理を行っています。
- CSSやJSのビルド
- CDNのオリジン(Cloud Storage)へのアップロード
- Docker Imageのビルド
処理の依存関係としては1の結果が2と3に必要になっています。
改善前からある程度の並列化は行われていて、上記2と3は並列で実行されています。 また、1のビルドもプロジェクト単位で並列化されていて、8コアのメリットを活かしている状況でした。
改善方針
既存の仕様を変更してしまうと多数のチームに影響を与えることになり改善の実施が遅れてしまうため、今回は仕様を変更しないチューニングをメインに行っています。経験が豊富な方であればより効果的な改善方法に気がつくかと思いますが、総合的な判断により仕様に大きな影響を与える変更は見送っています。
改善内容
改善の効果が大きかったものから紹介していきます。
CloudBuildの machineType
の変更
障害発生時に与える影響や日々のリリース作業における待ち時間の短縮とコストの増加を天秤にかけた場合にコスト増を許容しうると判断したため、CloudBuildで使用できる最大のコア数を持つ32コアのインスタンスに変更しました。すでに並列化されていたこともあり、これだけで5分以上短縮することができました。
Node関連やDockerのビルド時間はコア数を増やしても大きな変化はありませんでしたが、Cloud Storageへアップロードを行うgsutilの実行が大幅に短縮されました。
大幅に短縮できた改善はこれだけで、続く改善は大きくて1分程度になっています。
使用しなくなった静的ファイルの削除
歴史のあるリポジトリだったため現在も利用されているか不明な動画や画像、シンボリックリンクなどが多数存在していました。これらをアップロードすることは無駄なため使用状況の調査を行い削除しました。特にCloud Storageではシンボリックリンクを使用することができないため、リンク部分は全体を再アップロードする必要があり転送量に大きな影響を与えていました。
容量の大きなファイルを中心に数百MBを削除しました。
gsutilの並列実行
32コアに変更後、gsutilのオプションで指定できる parallel_
系の数値を大きくしてもあまり効果がでなかったため、ディレクトリ単位でgsutilの実行を並列化しました。
依存関係の最適化
上記の対応でCloud Storageへのアップロードが細分化されたため、画像などビルドの完了を待つ必要のないディレクトリのアップロードをCIの開始直後に行うように変更しました。
Source Repositories連携からGitHub連携に切り替え
古くからCloudBuildを使用していることもあり、初期のころから存在するSource Repositoriesを使用した連携方法になっていたため、GitHubと直接連携するように変更しました。 Source RepositoriesからCloneするよりもGitHubからの方が速度が速く、半分程度の時間で済みます。
CloudBuildの実行Regionの指定
こちらも初期のころには指定できなかった設定で、実行Regionを東京に設定することでCloud StorageやArtifact Registryへのアップロードが速くなります。
Node.js関連のキャッシュを有効化
CSSやJSのビルドを高速化するために、 node_modules
をキャッシュしたりwebpackのキャッシュ機能を有効化したりしました。
CloudBuildには他のCIにあるようなお手軽なキャッシュ機能がないため、Cloud Storageを使用して自前で実装しています。
dockerignoreの設定
画像などはCDNから配信しているためDocker Imageに入れる必要はありません。 dockerignoreで画像などのディレクトリを指定して除外しました。dockerignoreを複雑にしすぎるとパフォーマンスの低下や不具合の原因となってしまうため、効果が大きくシンプルに指定できるディレクトリのみを指定しています。
この改善はCloudBuildの実行時間だけでなく、GKEで実行されるDocker Imageのpullにかかる時間も改善され、リリースやオートスケールも素早く行えるようになります。
おわりに
以上の改善によりCloudBuildの実行時間を15分から4分まで短縮することができました。CloudBuildは分単位の時間課金であるため、machineType
を上げたことによる費用増加は実行時間の減少により相殺され、費用はほとんど変わりませんでした。
この改善記事がCloudBuildで歴史あるリポジトリの処理を実行している方の参考になれば幸いです。
ホワイトプラスでは、ビジョンやバリュー、そしてホワイトプラスの開発文化に共感していただけるエンジニアを募集しています!
ネットクリーニングの「リネット」など「生活領域×テクノロジー」で事業を展開している会社です。どんな会社か気になった方はオウンドメディア「ホワプラSTYLE」をぜひご覧ください。
オンラインでカジュアル面談もできますので、今回の記事の内容に興味を持っていただけたら、ぜひお気軽にお問い合わせください。