634 Views
April 23, 24
スライド概要
以下イベントで発表した内容です
https://sencorp.connpass.com/event/311688/
GitHub Actionsによる コンテナビルドの高速化 あるいはとりあえずキャッシュ活用してみようぜ話
おまえ誰? ● ● ソフトウェアエンジニア 好きなもの ○ ○ ○ ● 趣味 ○ ○ ○ ○ ● archlinux neovim Rust 犬派 バイク カメラ ギター(最近始めました) 自宅サーバ・自宅kubernetesクラスタ
最近解決したいこと デプロイが遅い!
デプロイが遅いとなにが困るのか? 高速にたくさんリリースしての試行錯誤ができない
デプロイが遅いとはどんな状態なのか? ● ● ひとくちに「デプロイが遅い」と言っても、いろいろ原因がある 高速化しようとして、見当違いのところを直してもどうしようもない ○ ● パフォーマンスチューニングと同じ たとえば ○ ○ ○ ○ デプロイ前の下処理が遅い ■ ビルドが遅い ■ デプロイ前のテストが遅い デプロイ自体が遅い ■ サーバの起動が遅い ■ サーバの入れ替えが遅い デプロイ後の切り替えが遅い ■ フロントエンドのCDNキャッシュの切り替えが遅い etc……
遅い箇所をどうやって特定するのか? ● パフォーマンスチューニングと違い、ボトルネックの特定はある程度容易 ○ ● デプロイしているということは、手順書やワークフローがある たとえばGitHub Actionsを使っている場合は、単純に直近のworkflowを確認 ○ stepを確認しよう ←ここを見る
原因がわかっても難しい ● ● ● 原因がわかったとてインパクトの大きい改善は難しいものがいっぱい 問題を認知してもハードル高くて最初の一歩で立ち止まってしまうことも たとえば ○ ○ ○ ● テストが遅いのは地道にリファクタしていくしかない デプロイが遅いのはインフラレベルでリアーキテクチャしないといけないかもしれない etc…… という状態で小さな最初の一歩としておすすめなのがビルドの改善 ○ のためのキャッシュの活用
今回の話のコア部分 ● キャッシュはGitHub Actionsの高速化の第一歩といっても過言ではない ○ ○ ● キャッシュができているといいこといっぱい ○ ○ ● ● かもしれない ありとあらゆる高速化の第一歩ともいえる ■ かもしれない 並列化に手を出してより速くなったり 失敗時の再試行がやりやすくなったり なので、いろんなところにしれっとキャッシュを入れて回ってます 意外と簡単に導入できるので、改善のとっかかりとしてもおすすめしたい 今回はキャッシュの活用についてお話します
なぜキャッシュを使うとビルドを速くできるのか GitHub Actionsの仕組みをおさらい ● GitHub Actionsは実行のたびに実行環境を再作成する ○ ● ● ローカルだと、前回のビルド結果が残っているので 差分更新という形で速くビルドが終わる Actionsだと、毎回なにもないところからビルドが 走ることになる ○ ○ ● そのため、前回の実行のファイルを参照することができない (右図参照) ので、なにも工夫しないとビルドが遅くなる ので、並列化しても重い処理がたくさん動くだけになる なんとかして過去のファイルを持ち込む方法の ひとつが、今回活用するキャッシュ
今回のアプローチ箇所 どうやって過去の結果を持ち込むのか? コンテナビルドキャッシュの仕組みを使って持ち込む GitHub Actionsのactions/cacheによる Runner間でのファイル共有の仕組みを使って持ち込む (ここもartifactを使って共有できるともっと速くなる)
今回のアプローチ箇所 コンテナビルドキャッシュの仕組みを使って持ち込む GitHub Actionsのactions/cacheによる Runner間でのファイル共有の仕組みを使って持ち込む (ここもartifactを使って共有できるともっと速くなる)
GitHub Actionsでキャッシュを活用する ● actions/cache アクションを使うことで、Runner間でファイルを共有できる 確認 保存 読込 公式ドキュメント: 依存関係をキャッシュしてワークフローのスピードを上げる
GitHub Actionsでキャッシュを活用する ● ● actions/cacheを導入して、ビルドの前段階のパッケージインストールを短縮 導入は簡単 ○ ○ ○ ● なにかの文字列をkeyとして、特定のパスをキャッシュするように書く 実装例としては右のような形 これだけで保存・読込両方実装完了 注意が必要な点 ○ ○ ○ keyとなる値は頻繁に変わらない値にする ■ lockファイルのハッシュとか ■ keyが頻繁に変わると意味がない 内容が頻繁に変わる値はキャッシュしない ■ ビルド結果などは別の方法で保管する キャッシュはactionsの実行が 成功したときのみ保存される
GitHub Actionsでキャッシュを活用する キャッシュヒットしたとき : キャッシュストレージの参照3秒、依存関係のインストール4秒 キャッシュヒットしないとき : キャッシュストレージの参照0秒、依存関係のインストール16秒
今回のアプローチ箇所 コンテナビルドキャッシュの仕組みを使って持ち込む GitHub Actionsのactions/cacheによる Runner間でのファイル共有の仕組みを使って持ち込む (ここもartifactを使って共有できるともっと速くなる)
コンテナビルドでキャッシュを活用する ● ● コンテナビルドにもキャッシュの仕組みがある コンテナのレイヤー概念を理解するとわかりやすい ○ Dockerfileの1ステップごとにレイヤー=キャッシュを持つイメージ 引用元 公式ドキュメント: Docker build cache
コンテナビルドでキャッシュを活用する ● ● コンテナビルドの結果として、コンテナイメージのほかにレイヤー情報をま とめたビルドキャッシュも生成される 2回目以降のビルドでは、ビルドキャッシュを参照することでビルド工程を短 縮できる 引用元 公式ドキュメント: Using the build cache
コンテナビルドでキャッシュを活用する ● ● ● ローカルでは同一マシン上にキャッシュを保持するので、いい感じにキャッ シュが活用されている状態 GitHub Actionsでは、実行ごとにrunnerがリセットされてしまうので外部に キャッシュを保管してあげる必要がある 外部として丁度いいのが、コンテナイメージを保管するコンテナレジストリ ○ ○ ○ ○ Dockerhub Elastic Container Registry GitHub Container Registry etc……
コンテナビルドでキャッシュを活用する 保存 確認 保存 読込 ここだけ差分があるので レイヤー作り直し
コンテナビルドでキャッシュを活用する ● ● レジストリにビルドキャッシュを保管するのは簡単 公式actionsが用意されているので、これらを使う ○ ○ ○ ● docker/build-push-action docker/metadata-action docker/setup-buildx-action 使い方については以前記事を投稿しているのでそちらを参照ください ○ Docker公式のactionsを使ってGitHub Actionsからコンテナイメージをプッシュする
コンテナビルドでキャッシュを活用する 上から ● ● キャッシュなし キャッシュあり 倍くらい違う
コンテナビルドでキャッシュを活用する ● 注意点として、ビルド時に差分を検知したあとのレイヤーはすべてキャッ シュが無効になり、ビルドしなおす ○ ○ 頻繁に変更されるものは後ろのほうに書くのが吉 ■ たとえばアプリケーションコードのコピーとか 場合によってはDockerfileの書き直しが必要になるので、気合が求められるかも 引用元 公式ドキュメント: Docker build cache
まとめ ● ● 改善の小さな一歩としてビルドに手を入れるのがおすすめ とりあえずキャッシュを活用しよう ○ ○ ● ● GitHub Actionsのキャッシュ コンテナのビルドキャッシュ 用途によってキャッシュの仕組みを使い分けよう キャッシュを活用できるように、既存の設定を見直そう
まとめ ● ● ● キャッシュ活用は高速化の第一歩 ほかにもやれることはいっぱいある たとえば ○ ○ ● ファイルを共有できるようになると、並列化の選択肢が採用できるようになる ■ もっと速く処理できるようになるかも? ビルド結果もArtifactとして今回のキャッシュのように使い回せるようにする どんどんやっていきましょう