RailsアプリをECSで本番運用するためのStep by Step
@joker1007
self.inspect
- @joker1007
- パーフェクトRuby, パーフェクトRails 著者
- Asakusa.rb, Yokohama.rb, Shibuya.rb
- データ分析基盤構築, Bigquery, インフラ全般
- fluent-plugin-bigqueryメンテナ
- (株)Repro
宣伝タイム
現在のECSの活用状況
- 主要システムはほぼECSに移行完了
- メインWeb, API, 各種非同期処理ワーカー
- クラスタは基本で15台
ASでその倍から3倍ぐらいまで増える
- 開発者用ステージング、QA環境等にも利用
何故ECS化したのか
- ミドルウェアのバージョン管理の容易さ
- Ruby, nginx, fluentd …
- TaskDefinitionのリビジョンでロールバックできる
- 無停止デプロイメントの簡易化
- AutoscaleのためのAMI管理不要
- pull型のデプロイアーキテクチャ
- CentOS6ェ……
現実に必要なこと
- コンテナイメージデザイン
- 各環境の管理 (staging, QA, production)
- デプロイ、ロールバックスクリプト
- ロギング
- メンバーへの展開
- Autoscale
- 移行 (今日話さない)
RailsアプリのDockerイメージ
- 各環境毎の設定をどう管理するか
- 起動時に外部から取得する
- 全環境分を管理対象に含める
- 非同期処理のワーカーをどうするか
- assets:precompile
全環境の設定を管理対象に含める
- リポジトリ自体の管理を楽にする
- 秘匿情報をどう扱うか
- KMSで暗号化して起動時に複合化して読み込む
- ECSならIAMロールで複合化権限を管理できる
- yaml_vault
- ファイルとして持っておきたいものもS3に暗号化して配置
Entrypoint
- いくつかの起動モードを切り替えられるようにしておく
- アプリケーションプロセス
- 非同期処理のWorkerプロセス
- Rakeの実行
- TaskDefinitionの定義時やEntryKitで調整
- graceful stopが出来るようにsignal handlerを調整する
- unicornはSIGTERMで即死するので要調整
assets:precompile
- 全環境分のデータを事前に作成する
- assetファイル自体はイメージ構築時にS3に
1イメージで全環境対応のイメージが完成
ビルドサーバーの構築
- docker環境を各チームメンバーが持たなくて良い
- CIサービスでのデータキャッシュ管理に制約が多い
- ビルドイメージやprecompileの結果をキャッシュする
- docker cpでビルド後のイメージから結果を引っぱりだす
- capistranoで任意のコミットからイメージを作成できるようにする
デプロイスクリプト
- 既存の運用(capistrano)と同じ使い勝手を実現する
- ecs_deploy
- capistranoのタスクを定義するgem
- ECSのAutoscaling機能込み (後述)
ecs_deployの挙動
- 任意のコミットのSHA1を利用してdocker imageを特定
- TaskDefinitionをregister
- db:migrate等の即時実行タスクをECS上で実行
- serviceの定義を新しいTaskDefinitionで更新
- serviceの状態が収束するまで待ち受ける
デプロイの課題
- デプロイ時にminimum healthy percent分の余剰ノードが必要
- でないとサービスが収束せずにタイムアウトする
- 自動でEC2のノードを伸縮させる仕組みが必要
ロギング
- fluentd log driverを利用
- 最終的にはpapertrailに転送する
- 今ならcloudwatch logsが楽そう
- アプリケーションのエラーはrollbar
メンバーへの展開と開発環境
- docker自体に習熟していないメンバーも居る
- docker-composeで1発起動可能に準備
- 使いたくなった時にすぐ使えるように準備して、
後は各自の習熟に任せる
Autoscale
- TokyoリージョンにService Autoscaleが無い
- 雑に車輪を再発明
- cloudwatchアラームをpollingしてtask countを調節
- 設定はyamlから読み込む
- EC2のノード数も計算して同時にスケールさせる
- 正直、ちょっと虚しい……。
- Autoscaler自体もECS上で実行
Autoscaleの際の注意点
- EC2ノードレベルでは何のコンテナが動いているか分からない
- 停止時に抱えたコンテナが停止しているとは限らない
- 複数のアプリを混ぜると巻き込まれる
得られた成果
- デプロイ速度の向上
- ミドルウェアアップデートの仕組み
- Chefレシピを大幅に削減
- ゼロダウンタイム
Tips
- 1プロセス1コンテナをちゃんと守る
- できるだけ直接コンテナを見なくて済むように
- ネイティブライブラリのコンパイルオプションに注意
- marchオプションが指定されてるとポータビリティが……
- 環境変数を増やし過ぎないように工夫する
AWSへの要望
- 監視に使えるメトリック増やして欲しい
- EC2のノード数を自動調整して欲しい。
- net=hostを使いたい
- ワンタイムなタスク実行した時の出力が取りたい
やっぱりコンテナ便利 :+1: