JAWS-UG コンテナ支部 #11
現実世界でのコンテナの運び方@wata727Mar 13, 2018 JAWS-UG コンテナ支部#11
View Slide
Question
本番でコンテナ使ってますか?
なぜ我々は(苦労して)コンテナを運ぶのか● コンテナを使うから、どうやってイメージをビルドするか、とか、どうやってデプロイするのか、を考えなくてはいけなくなる● rsyncでソースコードばらまく、じゃダメ?
なぜ我々は(苦労して)コンテナを運ぶのか● コンテナを使うから、どうやってイメージをビルドするか、とか、どうやってデプロイするのか、を考えなくてはいけなくなる● rsyncでソースコードばらまく、じゃダメ?⇛コンテナで解決する課題がある
アジェンダ● デプロイに求められるもの● Dockerイメージをどう作るか● どうやってECSにコンテナを配置するか
デプロイに求められるもの
デプロイに求められるもの● 信頼性● ロールバックの容易さ
信頼性● 安全に新しいアプリケーションを配置できること○ その際に、サービスダウンなどを伴わないこと● デプロイしたら、ちゃんとすぐに新しいアプリケーションに切り替わること
信頼性● 安全に新しいアプリケーションを配置できること○ その際に、サービスダウンなどを伴わないこと● デプロイしたら、ちゃんとすぐに新しいアプリケーションに切り替わることコンテナ以前: Graceful Restart
信頼性● 安全に新しいアプリケーションを配置できること○ その際に、サービスダウンなどを伴わないこと● デプロイしたら、ちゃんとすぐに新しいアプリケーションに切り替わることコンテナ以前: Graceful Restartコンテナ時代: Rolling Deployment
ロールバックの容易さ● 問題があったら、すぐに前のバージョンに戻せること○ 言語やOSのバージョンを上げるとか
ロールバックの容易さ● 問題があったら、すぐに前のバージョンに戻せること○ 言語やOSのバージョンを上げるとかコンテナ以前: Golden Image
ロールバックの容易さ● 問題があったら、すぐに前のバージョンに戻せること○ 言語やOSのバージョンを上げるとかコンテナ以前: Golden Imageコンテナ時代: Rolling Deployment
現実世界でのデプロイに求められるもの● 信頼性● ロールバックの容易さ● 早さ● 簡単さ● 管理の容易さ
早さ● デプロイが遅いとデプロイに抵抗感が生まれる○ デプロイに30分かかるとかだと「夜も遅いし、デプロイは明日に...」とかなる
簡単さ● デプロイの手順は簡単であるべき○ 手順が増えると、デプロイできる人が限られてしまう○ プルリクエストをマージしたり、git pushしたらすぐデプロイできるくらいの方が良い
管理の容易さ● 快適なデプロイを維持するためのコストが高いと大変● デプロイサーバとか持ち始めると、その面倒を見る必要がある...
Dockerイメージをどう作るか
Dockerイメージをどう作るか● Jenkinsでビルド● Travis CIとかCodeBuildでビルド
JenkinsGitHubのWebhookを受けてジョブを実行● Pros○ サーバがあるので、大体なんでもできる● Cons○ サーバがあるので辛い
JenkinsGitHubのWebhookを受けてジョブを実行● Pros○ サーバがあるので、大体なんでもできる● Cons○ サーバがあるので辛い○ 管理の容易さ☓
Travis CIやCodeBuildmasterの更新をhookしてジョブを実行● Pros○ サーバ不要● Cons○ イメージのキャッシュが効かないのでビルドが遅い
Travis CIやCodeBuildmasterの更新をhookしてジョブを実行● Pros○ サーバ不要● Cons○ イメージのキャッシュが効かないのでビルドが遅い○ 早さ☓
キャッシュが効かない?実はいくつかやりようがある
docker save/load● saveでtarを吐けるので、それをキャッシュしてloadすれば良い● CodeBuildでもファイルキャッシュが使える○ https://aws.amazon.com/jp/blogs/devops/how-to-enable-caching-for-aws-codebuild/
docker build --cache-from● 都度pullして--cache-fromで指定すれば、Jenkinsでbuildするのと同じようにキャッシュを効かせられる● 大きいイメージだとpullに時間がかかるのが問題だが...$ docker pull your-app:latest$ docker build -t ${TAG} --cache-from your-app:latest .$ docker tag your-app:${TAG} your-app:latest$ docker push your-app:${TAG}$ docker push your-app:latest
どうやってECSにコンテナを配置するか
どうやってECSにコンテナを配置するか● docker runとか直接できないのでAPI経由になる● APIを叩くツールは山ほどある● https://github.com/nathanpeck/awesome-ecs○ ここにあるだけで14種類○ ecs-deployという名前だけで4つある○ みんなが使う定番っぽいものは無い...
Amazon ECS CLI (おすすめ)● https://github.com/aws/amazon-ecs-cli● docker-compose likeにデプロイできる○ ローカルではdocker-composeで大体検証可能● ecs-cli compose runでワンオフも可能● スケールアウトもできる$ ecs-cli compose service up$ ecs-cli compose run oneoff bundle exec rake db:migrate$ ecs-cli compose service scale 2
Cronジョブの配置● サーバーは無いので、従来のcronは使えない● Railsならresque-schedulerとかを使う手もある○ https://github.com/resque/resque-scheduler● ECSのScheduled Tasksが代わりに使える○ https://docs.aws.amazon.com/AmazonECS/latest/developerguide/scheduled_tasks.html
Amazon ECS CLI + Elastic Whenever● https://github.com/wata727/elastic_whenever○ Rubyで書かれたschedule.rbからScheduled Tasksを生成する● ecs-cliで最新のTask Definitionを作って、それを元にScheduled Tasksを更新する$ ecs-cli compose create cronjob$ elastic_whenever -i myapp
より早いデプロイのために● ALBのderegistration delay○ https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-target-groups.html#deregistration-delay● ローリングデプロイ時に古いコンテナがALBから外れるのを待つ時間● デフォルト300秒だが、Herokuは50秒でタイムアウトするので、短くて良い場合も多い○ https://devcenter.heroku.com/articles/request-timeout
大変じゃないですか?● ここまでにアプリケーション独自の事情はほとんどなし○ では、もっと汎用的な基盤を作れるのでは?● 例えば...○ git pushしたら雑にデプロイしてほしい○ EC2足りないからスケールアウトできないとか考えたくない
Herogate● https://github.com/wata727/herogate○ Heroku + AWS Fargate● Heroku likeな操作でAWSのマネージドなサービスを操作できるようになれば、裏側で何が起きているのか考えなくても済むのでは?という実験● herogate createでCFn経由でCodePipeline, CodeBuild,CodeCommit, Fargate, ALBを全部作る
構成図
課題1: createが遅い● herogate createの裏側はCFnのcreate stackなので5分くらいかかる● heroku createは5秒くらいで終わるよ!
課題2: デプロイが遅い● git pushして変更検知して、CodeBuildが走って、ECSの更新完了までにかかる時間が10分● デプロイに10分はちょっと厳しいでしょ...
まとめ● コンテナのデプロイは複雑だが、複雑さを受け入れるだけの価値がコンテナにはある● 現実的にはデプロイの早さやビルドサーバのメンテなど、考えるべき問題もあるが、各位工夫して頑張りましょう● 銀の弾丸は無いです