この記事は JustSystems Advent Calendar 2017 の 1日目の記事です
お断り
この記事は GitLab Meetup Tokyo #4 で発表した内容です.
スライドだけではトーク内容が伝わりにくいので,記事化することにしました.
スライド:
https://speakerdeck.com/tetsukay/reasonable-auto-scaling-ci-with-aws-spot-instance
Reasonable Auto Scaling CI with AWS Spot Instance
現在進行形の怖い話
大量のModules
以前のCI環境
- プラットフォーム
- GitLab CI
- サーバ
- AWSオンデマンドインスタンス
- m4.xlarge(4core 16GB $0.258/h)
こんな環境でDockerベースCIをしていました.
課題
- 前述の通り,大量のModulesがあるためCIに時間がかかる
- しかも並列でCIが走るとどんどん遅くなる
- 4CIも同時に走ると,タイムアウトでCIがコケる
- (計算してみたらそうでもなかったけど)ハイコスト
$72 = 280 hours * $0.258
BY THE WAY...
AWSの課金が時間単位から秒単位になりましたね !
やるっきゃない! Auto scaling
Auto scaling with GitLab CI
GitLab CIは,docker-machineをサポートしています.
CIが実行されるたび,GitLab CIはdocker-machineでAWSスポットインスタンスを立てて,そこでCIを行います.
こんなかんじ
- GitLabとスポットインスタンス(CIインスタンス)の間に,GitLab Runnerが仲介
- この子はオンデマンド(t2.small)でGitLabからのCIリクエストを受け付ける役割
- この子がdocker-machineでCIインスタンスを立ち上げる
スポットインスタンスってなあに?
先程からチラチラでているスポットインスタンスについて簡単に説明します.
余った資源をお安く提供
AWSのデータセンターは,需要の増減を見越してある程度余裕を持たせて稼働しています.当然ですよね.
でも今度は逆に処理能力が余ってしまうわけです.もったいない!
そこで,需要が少なく処理能力が余っている時,余っている処理能力をお安く提供しますよ.っていうのがスポットインスタンスです.
ちなみにスポットインスタンスの価格は変動します.「ここまで出せる!」という価格を決めて入札します.
- おおよそオンデマンドの 15〜20% くらいの価格で買うことができます.
- 例えば, c4.4xlarge(16core 30GB RAM)では
- on-demand: 1.008/h
- spot: 0.182/h(最安時)
となり,1秒単位で課金されます.
スポットインスタンスのデメリット1
なら,全部スポットで良いんじゃないかな?
と,おもいますよね?
全部スポットインスタンスで賄えれば,それは大きなコスト削減につながりますが,デメリットもあります.
ひとつ目は,価格変動リスク
AWSリソースの需要が逼迫した場合,スポットインスタンスの価格はオンデマンドの10倍()近くまで跳ね上がります.
なお,設定した入札価格を超えて知らず知らずのうちに10倍払っていた…ということにはなりませんのでご安心を.
スポットインスタンスのデメリット2
ふたつ目は,突然強制的にシャットダウンされることがある点です.
スポットインスタンス使用中に価格が入札価格を上回った場合,1〜2分の猶予時間を与えられてから強制的にインスタンスをシャットダウンされます.
また,CIのたびにインスタンスを起動するので,1〜2分ほどインスタンスを起動する時間がビルド時間にプラスして掛かります.
改善後のCI環境
さて,上記の仕組みを導入した結果…
- CIの実行インスタンスタイプは
- m4.xlarge(4core 16GB)から c4.4xlarge(16core 30GB)へ!
- 入札価格は $0.5 としています
- m4.xlarge(4core 16GB)から c4.4xlarge(16core 30GB)へ!
- CIの実行時間は
- 25min から 14minへ!
- 並列数は無制限!
- といいたいところですが,インスタンス起動可能数に上限があるのを忘れていました.
- 今回の環境の場合は,20が上限です.が,現時点では十分すぎるくらいです.
コスト計算
Before
- Runner Instance(on-demand)
- 前環境では直接ここでCIをしていた
- m4.xlarge $0.258
- 280時間/月稼働
- 280*0.258 = $72.24
After
-
Runner Instance(on-demand)
- CIリクエストを捌く係.CIはしない
- t2.small $0.0152
- 280時間/月稼働
- 280*0.0152 = $4.256
-
CI Instance(spot)
- Runnerからリクエストを受けてCIする係
- c4.4xlarge $0.1825(最安値)
- 200 CI /月(おおよそ)
- 14min * 200 = 2800 min/月 = 46.67 時間/月
- 46.67 * 0.1825 = $8.52
-
Total
- 4.256 + 8.52 = $12.776
なにより,並列でCIを起動してもビルド時間が伸びない嬉しさ!!
まとめ
- CIするインスタンススペックをドカッと上げることができたよ!
- (事実上)無制限な並列CIができたよ!
- それなのにコストも 1/3(概算) まで下がってしまったよ!