Slide 1

Slide 1 text

Amazon CodeBuild でテストをめっちゃ並列実行する話 ター ゲット CI の実行時間長くなってきて辛い人 Docker で無茶したい人 Amazon ECS で頑張ってテスト実行環境作ってる人 Rails での Docker ベー スで分散テストの実際を知りたい人 Rails 以外でも役に立つ現実の世界での糞みたいな知見 今日しない話 CI の導入とか基礎的な話 ソフトウェアのテスト手法そのもの ( 特に本番環境での) デプロイ関連 インター ネットのもめごとについて

Slide 2

Slide 2 text

問題意識 ソフトウェアの開発は簡単になった。 フロント疲れみたいな言葉もいい加減聞かれなくなった 巨大化、 複雑化する UI

Slide 3

Slide 3 text

テストは簡単になったか? 別に最初からそんなに難しくはなかった。 そして、 E2E テストが書かれ まくるようになった。 v i s i t " / h o m e " a s s e r t _ s e l e c t o r " h 1 # t i t l e " , t e x t : / ^ H o m e $ / , c o u n t : 1 f i n d ( " # l o g o u t " ) . c l i c k ( ) a s s e r t _ e q u a l " / " , p a g e . c u r r e n t _ p a t h みたいな。

Slide 4

Slide 4 text

結果起きること 大量に書かれる、 実行に時間がかかりまくるテスト 単純に直列に実行すると、 CI に数時間とか ぼくが働いてる会社の実例

Slide 5

Slide 5 text

当然並列ビルド!!

Slide 6

Slide 6 text

いやいや大規模になってきたらインフラ自分 で組めばいいじゃん? さっきも言いましたが、 ソフトウェア開発は、 本当に簡単になった。 小規模で資金、 人的な問題から運用にリソー スを割けない組織でも巨大 なテストベー スを持ってしまうようになった テスト実行環境は本番環境と同等の信頼性が必要、 不用意な運用はして はいけない

Slide 7

Slide 7 text

そこで Amazon CodeBuild でやっていくこ とにしてみた

Slide 8

Slide 8 text

Amazon CodeBuild とは何ではないか TravisCI を捨てて引っ越せるものではない Jenkins を捨てて引っ越せるものではない では何? いろんなシステムから使える汎用的な Jenkins の slave のような存 在

Slide 9

Slide 9 text

すごくシンプルな使い方 buildspec.yml ってファイルを作ってリポジトリに置く v e r s i o n : 0 . 2 p h a s e s : i n s t a l l : c o m m a n d s : - b u n d l e i n s t a l l b u i l d : c o m m a n d s : - b u n d l e e x e c r a k e t e s t みたいな。 その上で設定して、 ビルドボタンみたいのを Web UI から押す。

Slide 10

Slide 10 text

AWS CodeBuild に無いもの リポジトリを監視して、master の最先端を常にビルドする Pull Request を監視して、 作成、 更新されるたびにビルドする CI ツー ルではない。 UI を見てよく分かったかと思います。

Slide 11

Slide 11 text

常識的な使い方をする場合 AWS CodeStar 糞 AWS CodeBuild Plugin for Jenkins Pull Request を受けて CodeBuild でビルドしたいとかだけな らこれでよさそう感あり

Slide 12

Slide 12 text

ところで v e r s i o n : 0 . 2 b u i l d : c o m m a n d s : - d o c k e r r u n - t i s o m e _ i m a g e

Slide 13

Slide 13 text

AWS CodeBuild はすぐに起動する Docker リソー スプー ルである しかも時間課金(1 分 $0.005) ただしコンテナは永続化しない ポー ト解放もできない

Slide 14

Slide 14 text

AWS Batch は? あれはなんかエンプラエンプラした感じのタスクランナー

Slide 15

Slide 15 text

最近 Azure にももうちょっと汎用的な Docker リソー スプー ルがで きた( 秒課金) けど個人的にも会社的にも AWS なのであんまり真面 目に調べてない 不真面目にはとりあえず使ってみたんだが Azure のコンパネ の酷さはなんだ? GCP のコンパネを触った時、 AWS 未満のも のを作れることに驚きを感じたが、 Azure を触ると GCP が最 悪ではなかったという点で驚きを感じる あっちはコンテナが永続化する、 ポー ト解放もできるのでデプ ロイもできます ただ基本的には瞬間火力需要をタゲってるっぽさ 1 秒課金なので、 1 秒未満でコンテナを終了させると無料 MS 日本法人のプロモ戦略が気に食わないみたいなのが無い人はや っていくといいのでは

Slide 16

Slide 16 text

即起動 => docker run => 即死 というのをやりやすくなってきている

Slide 17

Slide 17 text

テストの数だけ、 実行環境を大量に建てて、 1 テスト 1 実行環境でやったら、 最強なのでは?

Slide 18

Slide 18 text

まあ実際そう上手くはいかないんですが

Slide 19

Slide 19 text

ここからは現実の話をします

Slide 20

Slide 20 text

全体の流れ 1. Travis でリポジトリ監視 2. Travis で Docker build & push push 先は宗教上の事情無い限り Amazon ECS が楽と思う 3. Travis から適宜大量に CodeBuild たてる 4. Travis 側で API ポー リングするかなにかして実行状況監視 = > 実行 結果を集計 このうち 1. については特に話すことはないでしょう。

Slide 21

Slide 21 text

2. について僕が実際に会社でやったこと

Slide 22

Slide 22 text

一番簡単なやり方としては、 Travis からは CodeBuild をとにかく起動 するだけで、 CodeBuild の設定で実行環境のビルドからなにからやると いうのが考えられる。 それが駄目な理由 めっちゃ並列数上げると、 Github リポジトリへの git による大量ア クセスが発生して死ぬ CodeBuild は時間課金なので、 実行環境のビルドという共通処理を 各インスタンスでやるのは無駄 CodeBuild はビルド成果物のキャッシュ機構がないので時間(== 金) の無駄 毎回 0 から bundle install とか npm i とかしたくないっていう

Slide 23

Slide 23 text

いいかんじにものごとをキャッシュしながら Rails アプリの Docker イメー ジを build したい TravisCI には依存ライブラリとかそういうものをディレクトリキャッシ ュしてくれる機能があります。 c a c h e : d i r e c t o r i e s : - c l i e n t / n o d e _ m o d u l e s - v e n d o r / b u n d l e これを使おう!!!

Slide 24

Slide 24 text

Docker Image を複数回に分けてビルドする 1. 全体のベー スイメー ジをビルドする 言語処理系とかテストツー ルとかが入ってるやつ 2. 依存ライブラリインストー ル用のイメー ジをビルドする Gemfile package.json requirements.txt など「 だけ」 を作業 用ディレクトリにコピー する 3. docker run で依存ライブラリをホスト側ディレクトリにインストー ル d o c k e r r u n \ - v ` p w d ` / c a c h e / b u n d l e : / a p p / v e n d o r / b u n d l e \ b u n d l e i n s t a l l 4. テスト実行用イメー ジには cache/bundle を COPY する 5. ↑ の 3. で作ったディレクトリを CI ツー ルのキャッシュ機構でキャ ッシュする

Slide 25

Slide 25 text

Docker Multi Stage Build とか CircleCI の Docker Image Cache じゃ駄目なの? docker build 中に外部環境にアクセスしたい、 というものなので大分話 が違うと思う。 https://github.com/moby/moby/issues/15338 でこれと似たような話(docker build 中に link をしたい) が門前払い食ら ってたので、 公式機能としてこういうことが出来るようにはならん気す る。 Dockerfile のなかにディレクトリを固めて S3 に上げたり持ってきたり とかしてキャッシュ機構を自前で書いてもいい気はする。 なにが一番シ ンプルに見えるかは人それぞれ?

Slide 26

Slide 26 text

テストの実行 CodeBuild は API で環境変数を与えながら docker image を起動できま す。 テストファイルごととかにコンテナを起動して並列数をめっちゃ上 げて実行してしまうと便利。 注意点 コンテナ実行環境のプロビジョニングは失敗する可能性がありま す、 失敗したらリトライするといったコー ドが必要 一瞬で起動する実行環境が 70 を越えたあたりからプロビジョニン グの失敗率が激増します。 並列数を 60 ぐらいに抑える制御がある とよい

Slide 27

Slide 27 text

簡単にやる https://github.com/wata727/drunker これちょうすごい。 プロジェクトディレクトリを tar.gz で固めて docker hub にあるありもののイメー ジで docker run すれば動くような プロジェクトだとこれでよさそう。 E2E テストとか沢山書かれている環境だとわりと自分でビルドプロセス 書きまくらないといかんかな。

Slide 28

Slide 28 text

ところで 調子に乗ってるとそこそこ金はかかる。 0.005/min == 0.3/h m4.xlarge は 0.28$h

Slide 29

Slide 29 text

まとめ 1. Docker リソー スプー ル的なサー ビスが出てきている 2. 自分でテスト実行用クラスタ構築する必要はなくなってきている 3. 並列数を( 従来比で) 猛然と上げても大丈夫な感じなのでやっていき ましょう

Slide 30

Slide 30 text

自己紹介 ssig33 / 小池 陸 ユビレジというところからきました、 B2B プロダクトで今日話したよう なことをやってます