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: