WHITEPLUS TechBlog

株式会社ホワイトプラスのエンジニアによる開発ブログです。

リリース前に実行されるCloudBuildの実行時間を1/3に改善する

ホワイトプラスの基盤チームのakaimoです。

lenetではwebサービスの実行にGKEを使用していて、リリースを行うにはDocker Imageを作成する必要があります。また、リリースの前には他にも行わなければならない処理があり、それらを合わせてGCPのCloudBuildで実行しています。

歴史のあるサービスであることもありリポジトリが巨大化していて、CloudBuildの実行に15分以上かかっていました。この状態だと、不具合修正など緊急性の高いリリースの場合でも長い時間待つ必要があり、不具合の影響が大きくなってしまうリスクがありました。

上記リスクの解消、日々の開発体験の向上を目指し改善に取り掛かかった結果、4分まで短縮することができたため改善内容を紹介します。

主な処理内容

CloudBuildではインスタンスに8コアの N1_HIGHCPU_8 を使用し、主に以下の3つの処理を行っています。

  1. CSSやJSのビルド
  2. CDNのオリジン(Cloud Storage)へのアップロード
  3. Docker Imageのビルド

処理の依存関係としては1の結果が2と3に必要になっています。

改善前からある程度の並列化は行われていて、上記2と3は並列で実行されています。 また、1のビルドもプロジェクト単位で並列化されていて、8コアのメリットを活かしている状況でした。

改善方針

既存の仕様を変更してしまうと多数のチームに影響を与えることになり改善の実施が遅れてしまうため、今回は仕様を変更しないチューニングをメインに行っています。経験が豊富な方であればより効果的な改善方法に気がつくかと思いますが、総合的な判断により仕様に大きな影響を与える変更は見送っています。

改善内容

改善の効果が大きかったものから紹介していきます。

CloudBuildの machineType の変更

障害発生時に与える影響や日々のリリース作業における待ち時間の短縮とコストの増加を天秤にかけた場合にコスト増を許容しうると判断したため、CloudBuildで使用できる最大のコア数を持つ32コアのインスタンスに変更しました。すでに並列化されていたこともあり、これだけで5分以上短縮することができました。

Node関連やDockerのビルド時間はコア数を増やしても大きな変化はありませんでしたが、Cloud Storageへアップロードを行うgsutilの実行が大幅に短縮されました。

cloud.google.com

大幅に短縮できた改善はこれだけで、続く改善は大きくて1分程度になっています。

使用しなくなった静的ファイルの削除

歴史のあるリポジトリだったため現在も利用されているか不明な動画や画像、シンボリックリンクなどが多数存在していました。これらをアップロードすることは無駄なため使用状況の調査を行い削除しました。特にCloud Storageではシンボリックリンクを使用することができないため、リンク部分は全体を再アップロードする必要があり転送量に大きな影響を与えていました。

容量の大きなファイルを中心に数百MBを削除しました。

gsutilの並列実行

32コアに変更後、gsutilのオプションで指定できる parallel_ 系の数値を大きくしてもあまり効果がでなかったため、ディレクトリ単位でgsutilの実行を並列化しました。

cloud.google.com

依存関係の最適化

上記の対応でCloud Storageへのアップロードが細分化されたため、画像などビルドの完了を待つ必要のないディレクトリのアップロードをCIの開始直後に行うように変更しました。

Source Repositories連携からGitHub連携に切り替え

古くからCloudBuildを使用していることもあり、初期のころから存在するSource Repositoriesを使用した連携方法になっていたため、GitHubと直接連携するように変更しました。 Source RepositoriesからCloneするよりもGitHubからの方が速度が速く、半分程度の時間で済みます。

cloud.google.com

CloudBuildの実行Regionの指定

こちらも初期のころには指定できなかった設定で、実行Regionを東京に設定することでCloud StorageやArtifact Registryへのアップロードが速くなります。

cloud.google.com

Node.js関連のキャッシュを有効化

CSSやJSのビルドを高速化するために、 node_modules をキャッシュしたりwebpackのキャッシュ機能を有効化したりしました。

webpack.js.org

CloudBuildには他のCIにあるようなお手軽なキャッシュ機能がないため、Cloud Storageを使用して自前で実装しています。

dockerignoreの設定

画像などはCDNから配信しているためDocker Imageに入れる必要はありません。 dockerignoreで画像などのディレクトリを指定して除外しました。dockerignoreを複雑にしすぎるとパフォーマンスの低下や不具合の原因となってしまうため、効果が大きくシンプルに指定できるディレクトリのみを指定しています。

docs.docker.jp

この改善はCloudBuildの実行時間だけでなく、GKEで実行されるDocker Imageのpullにかかる時間も改善され、リリースやオートスケールも素早く行えるようになります。

おわりに

以上の改善によりCloudBuildの実行時間を15分から4分まで短縮することができました。CloudBuildは分単位の時間課金であるため、machineType を上げたことによる費用増加は実行時間の減少により相殺され、費用はほとんど変わりませんでした。

この改善記事がCloudBuildで歴史あるリポジトリの処理を実行している方の参考になれば幸いです。

ホワイトプラスでは、ビジョンバリュー、そしてホワイトプラスの開発文化に共感していただけるエンジニアを募集しています!

ネットクリーニングの「リネット」など「生活領域×テクノロジー」で事業を展開している会社です。どんな会社か気になった方はオウンドメディア「ホワプラSTYLE」をぜひご覧ください。

オンラインでカジュアル面談もできますので、今回の記事の内容に興味を持っていただけたら、ぜひお気軽にお問い合わせください。

www.wh-plus.co.jp