mina 20130417
TRANSCRIPT
minaについてそろそろ語っておくか
shibuya.rbSEO Naotoshi (@sonots)
2013/04/17
自己紹介describe Sonots do its(:last_name} { should == ”瀬尾” }
its(:twitter) { should == ”@sonots” } its(:company) { should == :DeNA } its(:job_title) { should == ”Infra Engineer” }
it_should_behave_like ”DeNA employee”end
shared_examples_for ”DeNA employee” do it { should write(:perl) } #=> failend
最近やってること
Haikankoなにか画像があった気がす
る
-配管工-
Haikankoなにか画像があった気がする
• Fluentd クラスタ管理ツール
• sinatra / erb / mina
• 詳しくはブログで http://blog.livedoor.jp/
sonots/archives/25694161.html
Haikanko
mina(ミーナ?ミナ?)
Yet another
Capistrano
Mina works really fast because it’s a deploy Bash script generator.
It generates an entire procedure as a Bash script and runs it remotely in the server.
シェルスクリプトを生成して、リモートサーバで実行する
Compare this to the likes of Vlad or Capistrano, Mina only creates one SSH session per deploy, minimizing the SSH connection overhead.
Capistrano と違って、1度しかSSHセッションを開かない
速い
サンプルconfig/deploy.rbrequire 'mina/git'require 'mina/bundler'require 'mina/rails'
set :domain, 'your.server.com'set :user, 'your_username'set :repository, 'https://github.com/xxx/repo.git’
task :deploy do deploy do invoke :'git:clone' invoke :'deploy:link_shared_path' invoke :'bundle:install' endend
task :restart do queue! %[sudo service restart nginx]end
$ gem install mina$ mina init$ mina deploy$ mina restart
サンプル(2)config/deploy.rbrequire 'mina/rbenv'
task :environment do invoke :'rbenv:load' # invoke :'rvm:use'end
task :setup => :environment do queue! %[mkdir -p "#{deploy_to}/shared/log"] queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/log"]
queue! %[mkdir -p "#{deploy_to}/shared/config"] queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/config"]
queue! %[touch "#{deploy_to}/shared/config/database.yml"] queue %[echo "-----> Be sure to edit 'shared/config/database.yml'."]end
!"" current!"" releases#"" shared !"" config $ #"" database.yml #"" log
$ mina setup #=>
シェルスクリプト臭
シェルスクリプト臭
だがそれがいい
(なにか画像があった気がする)
• queue or queue! でコマンドを enqueue
• task を実行すると :domain に指定したホストでシェルスクリプトを生成して実行
• mina {task_name} --simulate # dry-run
• mina {task_name} --verbose
• queue! で指定したコマンドを echo
• queue! だけでおk
ここから(個人的に)本題
Haikanko でどのように
mina を使っているか
<source> type forward port <%= port %></source>
<% archivers.each do |archiver| %><match raw.<%= archiver.agent_tag %>.**> type copy
<store> stdout </store>
<store> type file_alternative path <%= archiver.path %> output_include_time false output_include_tag false output_data_type attr:message add_newline true compress gz </store>
<%= erb :'_flowcounter' %></match><% end %>
Fluentdクラスタ
deploy
設定ファイル
ディレクトリ構造
config`-- deploy.rbpipework|-- boot.rb|-- files/|-- mina/`-- templates/
erb ファイル
require ‘boot.rb’のみ
通常ファイル
mina レシピ
拡張メソッドdef remote_file(target_path, source_path = nil) if block_given? contents = yield source_path = create_tempfile(contents) elsif source_path source_path = File.expand_path(source_path, files_dir) end queue! %[sudo mkdir -p $(dirname #{target_path})] queue! %[sudo rsync -a #{localhost}:#{source_path} #{target_path}]end
remote_file
def template_file(target_path, template_path, options = {}) remote_file(target_path) do template_path = "#{template_path}.erb" unless File.extname(template_path) == ".erb" template_path = File.expand_path(template_path, templates_dir) Tilt.new(template_path).render(self, options[:locals]) endend
template_file
def remote_directory(target_path, source_path) source_path = File.expand_path(source_path, files_dir) queue! %[sudo mkdir -p $(dirname #{target_path})] queue! %[sudo rsync -a --delete #{localhost}:#{source_path}/ #{target_path}/]end
remote_directory
chefインスパイア
:D
multistage 対応
defaults: &defaults repository: ‘haikanko’ branch: 'master'
development: <<: *defaults host: localhost
test: <<: *defaults host: localhost
staging: <<: *defaults host: xxxxxxx
config/haikanko.yml
https://github.com/ngmoco/bootloader
capistrano/extmultistageconfig|-- deploy.rb`-- deploy |-- staging.rb |-- sandbox.rb `-- production.rb
• mina は rake ベースコマンドオプション
$ mina ”deploy[localhost,foobar]”
task :deploy, :host, :hoge do |t, args| set :domain, args[:host] puts args[:hoge]end \(^0^)/
task :deploy set :domain, ENV[‘HOST’] puts ENV[‘HOGE’]end
$ HOST=localhost HOGE=foobar mina deploy
※なんとかしたいとは思っている環境変数で
複数サーバdef multi_invoke(task, domains, args = []) isolate do domains.each do |domain| set :domain, domain yield if block_given? run! if commands.any? Rake::Task.tasks.each {|t| t.reenable } end endend
multi_invoke
rake タスクは1度実行するとフラグが立って、実行できなくなる複数ホストに対して実行できるようなメソッドを用意
まとめ
• SSHセッション1回
• シェルスクリプト脳(個人的な意見)
• シェルスクリプトノウハウ詰まってる
良いところ
• rake のオプションキモい
• 途中に処理挟めない
悪いところ
task :setup => :environment do queue! %[cd] a = Tempfile.new #=> 最初に実行 queue! %[ls]end
• デプロイツールなのに、プロビジョニングツール(chef)っぽく使っている
• こういうプロビジョニングツールあってもいいかもね
• なんか作りたい
Haikankoでは
•haikanko を github におきました•テスト足りてない ^^;
•プルリク歓迎
お知らせ
https://github.com/sonots/haikanko