密着! nibohsiデプロイ 13:00-13:05 - railsアプリのデプロイ事例 -
-
Upload
yukihiko-sawanobori -
Category
Technology
-
view
986 -
download
4
description
Transcript of 密着! nibohsiデプロイ 13:00-13:05 - railsアプリのデプロイ事例 -
密着 ! Niboshi 更新デプロイ13:00 ~ 13:05
2012/10/31Niboshi::Version #=> 1.1.0.1DocumentVersion #=> 1.2
制作・著作: HiganWorks 合同会社
Niboshi とは• Z Cloud のコンパネです• Rails + resque で構成– Nginx + unicorn– Rescure worker, scheduler
• 外部サービスとの連携多し– Joyent SmartDatacenter (SDC)– Giraffi ( モニタリング SaaS)– ペイメント代行サービス
開発は Team Shinobi
密着! Niboshi デプロイ 2
"sinobi".scan(/[niboshi]/) #=> ["s", "i", "n", "o", "b", "i"]
注意• このスライドは 2012 年 10 月 31 に行った
Niboshi デプロイ 1.1.0.1 の作業ログです
• 作業の視点はデプロイ担当者、アプリのコードには関与していない
• 手法、コマンドなどは作業記録当時のものであり、最新とは限りません
密着! Niboshi デプロイ 3
デプロイは FEATUREの把握から
密着! Niboshi デプロイ 4
前提知識:一般的な Rails アプリの更新デプロイ
• 開発情報– Git のタグ– Changelog
• マイグレーションタスク抽出– DB マイグレーション– コンフィグディレクティブ
• 運用情報– 起動終了スクリプト– モニタリング– ワーカなどのデーモン管理
密着! Niboshi デプロイ 5
New Feature, changelog の聞き込みQ A Do
タグは何? 1.1.0.1 • リリース対象として認識
• Git log , diff のチェック
どういうリリース? 管理システムとキュー連携してタスクを実行する機能の実装あとバグ Fix
サーバで必要なタスクの洗い出し=> 次ページへつづく
Config 変更は? ない デプロイ時の Structureチェックのみで OK
DB マイグレーション あったっけ。。?
お互い確認⇒ あった。
デプロイ時、リスタート前に rake db:migrate:status で確認後 db:migrateが必要になる密着! Niboshi デプロイ 6
なぜ聞き込みがいるのでしょう。
アプリが何の機能を提供するかを知ることで、インフラやミドルウェアがどういう状態であるべきかの判断材料とするためです。その情報をもとにデプロイ先の動作環境を事前に調整します。
また、更新時に不必要なダウンタイムを発生させないためでもあります、 DB のマイグレーション・コンフィグのディレクティブ追加の通知を忘れるとアプリケーションが正常にリスタートできずダウンします。
密着! Niboshi デプロイ 7
掘り下げて把握& Tododig Dug Todo / result
Feature:管理システムキュー連携
メッセージングは Resqueで行う実行は Resque でやるエンキューは社内の管理システムから
• 新規 resque worker! の設置
• Fail のチェックタスク• 管理サーバからの Redis
ポートの Open
- ( 運用 ) 新規 resque worker 起動方法のMonit でストップ / スタート
• Capistrano スクリプト修正
Bugfix:あれこれ
詳細後述 本番稼働とリリース対象のタグで log と diff を見る
Migration:データベース
DB:migrate:status で確認しつつdb/migrate/ を見る
メッセージキューを受けて叩くタスク用のカラムが 2つ追加される模様密着! Niboshi デプロイ 8
今回の掘り下げの成果は。
訳あってスプリント (※) の期間が空いたため、大いにありました。DB のマイグレートと Config ファイルは見逃した際の本番環境へのインパクトが特に大きいため、自動チェックの仕組みを幾つか用意した上で直前にも口頭で確認しています。
開発側は普段がそれぞれの development 環境で行っているため、 Production との差をあまり意識しません。期間が空くとどこまで適用済みかなんて自分も含めてみんな忘れていますから。
密着! Niboshi デプロイ 9
(※) リリースのこと
ミドルウェアの設定変更がありますね。
Feature を引っさげてのリリースですから。連携側のシステムも私が環境構築しているので色々とスムースです。
密着! Niboshi デプロイ 10
テスト通ってる?
密着! Niboshi デプロイ 11
自動実行の結果をチェック
密着! Niboshi デプロイ 12
この時点での Jenkins 実行内容• Bundler 実行可否– .lock から生成する “– deployment” モードで
• Config.sample と development の構造チェック– 更新や階層変更、 Syntax エラーの検出
• Rake から unit, functional, integration テストの実行
課題: Jenkins サーバからデプロイできそうだが、まだ心配&デプロイコードのリファクタしたいので据え置き
密着! Niboshi デプロイ 13
Jenkins の役割はなんでしょう。
まず結合テストの実行と実行結果のシェア&通知です。導入前に比べ、単体の Ruby(rails) アプリケーションとしてのテスト効率は飛躍的に向上しました。
本番デプロイを想定した流れをジョブ化しており、テストもその環境で行われます。 DB や Config の構成変更は特に周知せずともここで検出できるようにしています。
密着! Niboshi デプロイ 14
アプリケーションのコンフィグはどの様に運用していますか。
Niboshi では関係者が値を確認しやすいよう、 staging, production のコンフィグコピーを WEB で閲覧&編集できるようなツールを作っています。編集したコンフィグのみそのままデプロイできますが、書式が変なら警告して止まる仕組みです。
ほか、デプロイ用のサーバでは git の post-merge フックにて config.yml(sample) の diff を毎回出力させるなど、対応不要ならスルーし、要対応はどこかで止められるようにしています。
密着! Niboshi デプロイ 15
デプロイの準備
密着! Niboshi デプロイ 16
Git log で雰囲気を把握• 本番稼働中のタグ確認
• cap production deploy:version– #=> ( 略 )/current/VER_1.1.0b
– Log みる• git log --oneline 1.1.0b..1.1.0.1
– 5e4e605 Update Gemfile.lock by doing bundle update– fd20c2e Update the Email template for update payment information– 21d8ab3 Comment-in newrelic gem in Gemfile– 3529ba2 Add resque worker for run notification queue– (中略)– b972edc Set default value for path of HTTP monitoring
– コメントで気になったらコードみる• git show 21d8ab3
– +gem “newrelic_rpm“ # なるほど
密着! Niboshi デプロイ 17
コード見るの?
見ないことも多い、趣味で。もはや Ruby は必修科目なので参考にしたり。
密着! Niboshi デプロイ 18
Resque worker ++の対応• 普通のワーカーなので Capistrano にセット– Production.rb
-set :resque_workers, %w{reap_free_machines}+set :resque_workers, %w{reap_free_machines run_notification_queue}
• テンプレートから起動&終了スクリプトの設置とmonit 登録用コンフィグを生成するための配列
• DryRun (-n) でチェック• cap production -n deploy:create_ctl_scrpts
– ====Start preview config ==resque_run_notification_queue_start.sh==– #!/usr/local/rvm/bin/rvm-shell 1.9.3-p125– ( 中略 )– ====End preview config ==resque_run_notification_queue_start.sh==
– 内容問題無さそう ( ってか Staging で稼働の確認済み )
密着! Niboshi デプロイ 19
Capistrano とは。
コードベースからアプリケーションをデプロイするためのツールです。デフォルトでは Rails プロジェクト向けのタスクが組まれていますが、 Ruby の内部 DSL でタスクを定義できるので便利です。どちらかと言うと開発者が自分で自由にデプロイするために使うツールだと思いますが、最近は DevOps とか言うしそこだけ特定の誰かがやるのもあまり不自然ではないかも。
今回 Resque-worker がテンプレ通りだったので追加も楽でした。
密着! Niboshi デプロイ 20
Redis の対応• 先日立てた管理アプリとの連携のためポート開放• デプロイ前
– Listen が localhost– Iptables は余計なものを開けてはいないが社内 IP は通して
いる ⇒ bind address を変更すれば OK
-bind 127.0.0.1+bind 0.0.0.0
• Redis をリスタート– # service redis-server restart– # netstat -naplt | grep redis– tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 3553/redis-server
密着! Niboshi デプロイ 21
CAPでのデプロイをおこなう
密着! Niboshi デプロイ 22
と思ったけど 毎時 30 分に行うタスクが“Resque scheduler” にエンキューされる寸前だったので完了まで待つ
密着! Niboshi デプロイ 23
適当に見届ける
密着! Niboshi デプロイ 24
今回のデプロイ段取りをおさらい• Cap で 1.1.0.1 をデプロイする
– Bundler が複数ベンダのプライベートリポジトリをまたぐので多段 ssh-agent環境で行う
– Gemset も“ ruby-1.9.2-p290@capistrano” を固定で使用– migrate:status にて down 検出、リスタートしない
• db:migrate する– Cap の deploy:migrate も使えるはずだが、導入時に rvm との連携を作ってな
かったのでそのまま
• Rack アプリをリスタート• Resque-* (worker, scheduler, resque-web) を
リスタート• 新 worker 用の Monit スクリプトのロード
密着! Niboshi デプロイ 25
“ 今回の“段取り?
ただの Bugfix などのケースだと、 Deploy&Restart でオシマイですからね。
密着! Niboshi デプロイ 26
Cap deploy でコードを• コマンド
– # cap production deploy– ( 中略 )– Tag to deploy (make sure to push the tag first): [1.1.0rc4] 1.1.0.1
– やること(普通にカスタマイズ可)• まずMysql のダンプ• 新規 Dirに Git clone & checkout & rm –rf .git• bundle install –deployment( ほかオプションも )• current リンクの付け替え• コンフィグの設置• 本来ならアプリのリスタート (※ 無効化済み )
代わりに db:migrate:status を表示させている。密着! Niboshi デプロイ 27
Capistrano にカスタマイズで追加したタスクは?
今回出てくるのでは、 DB のバックアップ、コンフィグ /管理スクリプト設置 (Dryrun プレビュー込 ) 、リビジョン確認くらいです。
あとはリバースプロキシ用の Nginx の操作をテンプレート&タスクにしてます。
密着! Niboshi デプロイ 28
管理スクリプトも設置• 各種起動&停止スクリプトの設置– 毎回上書き設置• # cap production deploy:create_ctl_scrpts
– *_start.sh, *_stop.sh と monit_*.conf ファイルの作成と設置• deploy.rb でタスク、 staging.rb, production.rb で環境別
attribute をセット!( path とか resque-worker とか)
• {# deploy_to} の shared/system に設置
密着! Niboshi デプロイ 29
DB:migrate
• アプリのサーバで migrate– 普通の rails 的更新– アプリの“ Current” は symlink なので、毎回 CD し
ないといつのまにか古いディレクトリにいる– ↓確認– bundle exec rake db:migrate:status RAILS_ENV=production
» down 20121012075801 Add status and executed at to notification queues
– ↓更新– bundle exec rake db:migrate RAILS_ENV=production
密着! Niboshi デプロイ 30
なぜ” Current” は実体でなくシンボリックリンクなのですか。
Capistrano のやり方ですが、リンクの付け替えだけでアプリケーションのロールバックができるからです。Rails の DB マイグレーションの仕組みはロールバックもサポートしており (※) 、だいたい可逆です。
繰り返しになりますがデプロイ直後はカレントディレクトリに注意しないと古いものを見てしまいます。
密着! Niboshi デプロイ 31
(※) 特定のマイグレーションを DOWN にできる。マイグレーション内容によっては保証しかねるので流石にダンプの取得は必須
アプリのリスタートをしていく
密着! Niboshi デプロイ 32
Rack アプリ( Rails )• Monit に管理させている– Cap で deploy:stop & deploy:start か– Monit で restart のどちらでも OK
– とりあえず– monit restart niboshi_unicorn_production
• デプロイを asset_pipeline にちゃんと対応してないので、リスタート後一発目の表示が遅い
密着! Niboshi デプロイ 33
なぜ Monit なのですか。
いろいろやった結果、起動終了をスクリプトにしておいてmonit経由でデーモンをコントロールするのが分かりやすさや互換性、可搬性に優れていると思いました。
コントローラとしても、自動リスタートの内部監視としても優秀です。
密着! Niboshi デプロイ 34
Rack アプリのリビジョンチェック• 過去、再起動失敗でプロセス古いままという事例があったのでチェックするようにしている
• # cap production deploy:version• “Current” にあるファイル群の表示
– ** [out :: **.**.**.***] /opt/deploy/niboshi/current/VER_1.1.0.1– ** [out :: **.**.**.***] 5e4e605fd2731d0f0a30a8e83ecc567d1bb55e65
• 起動中の unicorn_master プロセスの proc/*/cwd の下– ====– ==== Revision of unicorn ========– ====– ** [out :: **.**.**.***] /proc/8639/cwd/VER_1.1.0.1– ** [out :: **.**.**.***] 5e4e605fd2731d0f0a30a8e83ecc567d1bb55e65
密着! Niboshi デプロイ 35
リスタート失敗してた?
いろんな要因の失敗があった。CI してない頃は、もう何も信用出来なかった。
最近は少なくとも Staging に上げる頃にはコケる要素がほぼ駆除されている。
密着! Niboshi デプロイ 36
Worker の monit への追加• Capistrano で作ったコンフィグを Monit の
include_dir へ• ln -s / (略) /shared/system/monit_resque_run_notification_queue_production.conf \
/etc/monit/enable-conf.d/
• # monit –t> Control file syntax OK• # monit reload• # monit summary # ほっとくと起動してくれる
– Process 'resque_run_notification_queue' Initializing– Process 'resque_run_notification_queue' Does not exist– Process 'resque_run_notification_queue' Running
密着! Niboshi デプロイ 37
Resque 関連リスタート• CWD が古いので、すべて一旦リスタートする。– Resque-(worker, scheduler, web)
– Monit でグループにしているのでまとめてリスタート命令
– cap production deploy:restart2 #deploy.rb で定義– * executing "monit restart -g resque_workers“
– cap production deploy:version で CWD のリビジヨンチェック
– 全プロセスが VER_1.1.0.1
密着! Niboshi デプロイ 38
作業にはどのくらいの時間がかかりましたか。
聞きこみ&把握はテンプレなので事前の準備などには 20 分、実際にデプロイ&新ワーカーの稼働はタイトル通り、 5 分で終わりました。
密着! Niboshi デプロイ 39
最後に何か。
当初は各段階でその場の対応をよくしていたが、最近はほとんどのデプロイが目視確認&そのまま次へとなってきています。
聞きこみの部分だけ何とかなれば、ワンクリック /完全自動化が次のステップになるでしょう。
密着! Niboshi デプロイ 40
密着 !Niboshi 更新デプロイ13:00 ~ 13:05
制作・著作: HiganWorks 合同会社
END