SlideShare a Scribd company logo
1 of 40
Download to read offline
成長を加速する
minne の技術基盤戦略
変化するサービスとチームを支える
self.introduce
=>
{
name: “SHIBATA Hiroshi”,
nickname: “hsbt”,
title: “Chief engineer at GMO Pepabo, Inc.”,
commit_bits: [“ruby”, “rake”, “rubygems”, “rdoc”, “tdiary”,
“hiki”, “railsgirls”, “railsgirls-jp”, …],
sites: [“hsbt.org”, ruby-lang.org”, “rubyci.com”, “railsgirls.com”,
“railsgirls.jp”],
}
Do scale-out
with automation
2014/11 の minne の状況
• IaaS の上で動くシンプルな Rails アプリケーション
• Rails が動いているサーバーは 6 台
• デプロイは capistrano 2 を使用
• ジョブワーカーは Web サーバーに同居
• 用途不明なサーバーもちらほら…
オペレーションは心温まる手作業
• 動いているサーバーを LB から外して “Golden Image” を
作成し、インスタンスを複製
• 複製したインスタンスの設定変更は手順書をもとに手作
業で実施
• おおよそ 4-6 時間の工程…
No ssh
“No SSH” ルールを作成し、Packer でイメージ構築を自動化
“No SSH” のコンセプト
ある程度の規模のサービスにとっては 1 サーバーは UNIX
でいう 1 プロセスと同等である
プロセスに gdb でアタッチしたりしない
→ インスタンスに ssh ログインしない
プロセスのメモリを書き換えて変数を変えたりしない
→ インスタンスの設定ファイルを変えたりしない
遅い処理
OS 起動
puppet/chef 実行
Rails アプリケーションの
デプロイ
No SSH によるサーバー構築の流れ
速い処理
OS 設定の変更
Capistrano の準備
LB に接続(サービスイン)
Packer によるイメージ作成
• 公式 OS イメージ
• プラットフォーム提供

• Minimal イメージ(phase 1)
• Network, User, Package 設定のみ実行
• puppet/chef, プラットフォームの cli ツールを追加
• Role 専用イメージ(phase 2)
• 起動するだけで Role 特有のアプリケーションが起動
Minimal イメージ
cloud-init provisioner
#cloud-config
repo_update: true
repo_upgrade: none
packages:
- git
- curl
- unzip
users:
- default
locale: ja_JP.UTF-8
timezone: Asia/Tokyo
rpm -ivh http://yum.puppetlabs.com/
puppetlabs-release-el-7.noarch.rpm
yum -y update
yum -y install puppet
yum -y install python-pip
pip install awscli
sed -i 's/name: centos/name: cloud-user/' /etc/
cloud/cloud.cfg
echo 'preserve_hostname: true' >> /etc/cloud/
cloud.cfg
www イメージ
cloud-init provisioner
#cloud-config
preserve_hostname: false
puppet agent -t
set -e
monit stop unicorn
/usr/local/bin/globefish -w
rm -rf /var/www/deploys/minne/releases/*
rm -f /var/www/deploys/minne/current
# tar xf するだけで動くRails アプリケーションを取得
(snip)
# mackerel のホスト設定が packer 実行時のものとかぶらないように初期化
rm /var/lib/mackerel-agent/id
# cloud-init をもう一度動かすようにする準備
rm -rf /var/lib/cloud/sem /var/lib/cloud/instances/*
packer の実行は ruby の thor から実行
$ some_cli_tool ami build-minimal
$ some_cli_tool ami build-www
$ some_cli_tool ami build-www —init
$ some_cli_tool ami build-www -a ami-id
module SomeCliTool
class Ami < Thor
method_option :ami_id, type: :string, aliases: "-a"
method_option :init, type: :boolean
desc 'build-www', 'wwwの最新イメージをビルドします'
def build_www
…
end
end
end
thor でオペレーションをコード化
$ some_cli_tool instances launch -c …
$ some_cli_tool mackerel fixrole
$ some_cli_tool scale up
$ some_cli_tool deploy blue-green
イメージ作成
その他 IaaS 操作コマンド
インスタンス挙動のテスト
http(s) でアクセスした時の
挙動のみテストを行う
サーバー内部のパッケージ
個別のバージョンナンバー
などはテストの対象としな
い
インフラCIの導入
サーバーにインストール済みのパッケージや起動している
プロセスなどの詳細は Serverspec を用いて継続的にテスト
を実行
Puppet + Drone CI(with Docker) + Serverspec = WIN
CIがあれば何でも(puppet マニフェストをアグレッシブにリ
ファクタリング)できる!
Serverspec
“RSpec tests for your servers configured
by CFEngine, Puppet, Ansible, Itamae or anything else.”
http://serverspec.org/
% rake -T
rake mtest # Run mruby-mtest
rake spec # Run serverspec code for all
rake spec:base # Run serverspec code for base.minne.pbdev
rake spec:batch # Run serverspec code for batch.minne.pbdev
rake spec:db:master # Run serverspec code for master db
rake spec:db:slave # Run serverspec code for slave db
rake spec:gateway # Run serverspec code for gateway.minne.pbdev
(snip)
Drone CI
“CONTINUOUS INTEGRATION FOR GITHUB AND BITBUCKET THAT
MONITORS YOUR CODE FOR BUGS”
https://drone.io/
Drone CI は nyah と呼ばれる Openstack の上に構築
Integration tests with Packer
Packer の実行後にも Serverspec でテスト実行 (by @udzura)
"provisioners": [
(snip)
{
"type": "shell",
"script": "{{user `project_root`}}packer/minimal/provisioners/run-serverspec.sh",
"execute_command": "{{ .Vars }} sudo -E sh '{{ .Path }}'"
}
]
yum -y -q install rubygem-bundler
cd /tmp/serverspec
bundle install --path vendor/bundle
bundle exec rake spec
packer configuration
run-serverspec.sh
Blue-Green
Deployment
Blue-Green デプロイの手順
1.起動するインスタンスを Packer で作成し、hakata コマ
ンドで起動
2.LB に接続して、“InService” となるまで待機
3.古いインスタンスを廃棄
B-G デプロイの hakata コマンド
class deploy < Thor
def blue_green
old_instances = running_instances(load_balancer_name)
invoke Instances, [:launch], options.merge(:count => old_instances.count)
catch(:in_service) do
sleep_time = 60
loop do
instances = running_instances(load_balancer_name)
throw(:in_service) if (instances.count == old_instances.count * 2) &&
instances.all?{|i| i.status == 'InService'}
sleep sleep_time
sleep_time = [sleep_time - 10, 10].max
end
end
old_instances.each do |oi|
oi.delete
end
end
end
nginx + consul-template の様子
Mackerel
“A Revolutionary New Kind ofApplication Performance
Management. Realize the potential in Cloud Computingby
managing cloud servers through “roles””
https://mackerel.io
consul + consul-alerts
Disposable なインスタンスのプロ
セス監視は consul と consul-alerts
で実行
https://github.com/hashicorp/consul
https://github.com/AcalephStorage/consul-
alerts
td-agent と log collector
動的に変化するイン
スタンスのログは td-
agent で集約
<match nginx.**>
type forward
send_timeout 60s
recover_wait 10s
heartbeat_interval 1s
phi_threshold 16
hard_timeout 60s
<server>
name aggregate.server
host aggregate.server
weight 100
</server>
<server>
name aggregate2.server
host aggregate2.server
weight 100
standby
</server>
</match>
<match nginx.access.*>
type copy
<store>
type file
(snip)
</store>
<store>
type tdlog
apikey api_key
auto_create_table true
database database
table access
use_ssl true
flush_interval 120
buffer_path /data/tmp/td-agent-td/access
</store>
</match>
Large-scaled
Deploy with
Rails application
2015/11 現在の minne の状況
• Rails 4.2.4 and Ruby 2.2.3, MySQL 5.6.23
• Capistrano 3, stretcher + consul
• solr(with sunspot), delayed_job
• Models: 136, Controllers 143, Code to Test Ratio: 1:1.7
• サーバー台数 100台弱
capistrano によるデプロイ問題
• ある日、社内の GHE が不定
期に重くなるという報告
• GHE にログインしてプロセス
リストを見てみると…
• git…git…git…(100個くらい)
• minne がデプロイすると全
サーバーが GHE に git clone/
fetch を実行する
consul with stretcher
• トリガとして consul/serf
のイベントを受け取って動
作するプログラム
• インスタンスが自律的にコー
ド更新を実行
• 更新するコードは s3 から
取得
https://github.com/fujiwara/stretcher
Bundled package of Rails application
Rails アプリケーションを Ruby だけあれば起動するような
tgz を作成(bundle install/assets precompile 済み)
capistrano を用いてビルド専用サーバーで各種タスクを実
行後に s3 へアップロード
$ bundle exec cap production archive_project
desc "Create a tarball that is set up for deploy"
task :archive_project =>
[:ensure_directories, :checkout_local, :bundle, :npm_install, :bower_install,
:asset_precompile, :create_tarball, :upload_tarball, :cleanup_dirs]
consul の event を通知するために consul watch で stretcher
を systemd でデーモン化
consul watch と stretcher
[Unit]
Description=Stretcher Deamon with Consul
Documentation=https://github.com/fujiwara/stretcher
[Service]
User=rails
Group=rails
EnvironmentFile=-/etc/sysconfig/consul
Environment="AWS_CONFIG_FILE=/home/rails/.aws/config"
ExecStart=/usr/bin/consul watch -type event -name <%= @event_name %> stretcher
ExecReload=/bin/kill -HUP $MAINPID
KillSignal=SIGINT
[Install]
WantedBy=multi-user.target
systemd への完全移行
supervisord や monit で動かしていた consul などを全て OS
標準の systemd へと移行
[Unit]
Description=Rack HTTP server for fast clients and Unix
Documentation=http://unicorn.bogomips.org/
[Service]
User=rails
Group=rails
EnvironmentFile=-/etc/sysconfig/unicorn
WorkingDirectory=/var/www/rails_applicaiton
PIDFile=/var/www/rails_application/shared/pids/unicorn.pid
ExecStart=/usr/local/rbenv/shims/bundle exec unicorn -c config/unicorn.conf -E <%= @environment %>
ExecReload=/bin/kill -USR2 $MAINPID
ExecStop=/bin/kill -QUIT $MAINPID
KillSignal=SIGINT
[Install]
WantedBy=multi-user.target
rails 向け stretcher manifests
src: s3://your-buckets-name/production/application-<%= env.now %>.tgz
checksum: <%= checksum %>
dest: /var/www/rails/releases/<%= env.now %>
commands:
pre:
-
post:
- ln -nfs /var/www/rails/releases/<%= env.now %> /var/www/rails/current
- rm -rf /var/www/rails/current/log
- ln -nfs /var/www/rails/shared/log /var/www/rails/current/log
- mkdir -p /var/www/rails/current/tmp
- ln -nfs /var/www/rails/shared/pids /var/www/rails/current/tmp/pids
- ln -nfs /var/www/rails/shared/data /var/www/rails/current/data
success:
- <%= h[:cmd] %> && rm-releases /var/www/rails/releases 5
failure:
- cat >> /tmp/failure
- (slack に失敗メッセージを通知)
- "*.pid"
- "*.socket"
yaml を erb から生成
し、s3 にアップロー
ドする cap task を作
成
tgz 作成後に実行
capistrano との統合
namespace :minne do
desc 'Deploy via Stretcher'
task :deploy do
set :deploying, true
invoke "minne:archive_project"
(ENV['ROLES'] || fetch(:minne_deploy_roles)).split(',').each do |target_role|
on application_builder_roles do
opts = ["-name deploy_#{target_role}_#{fetch(:stage)}"]
opts << "-node #{ENV['HOSTS']}" if ENV['HOSTS']
opts << “s3://your-buckets-name/manifest_#{target_role}.yml"
execute :consul, :event, *opts
end
end
end
before 'minne:deploy', 'slack:deploy:starting'
after 'minne:deploy', ‘slack:deploy:finished'
end
stretcher を用いて cap からデプロイ
1. build サーバーで rails + bundler gems + node modules +
assets 入りの tgz を作成、s3 にアップロード
2. stretcher 用の manifests を作成して s3 にアップロード
3. consul event を指定した roles に対して発行
4. event を受け取った role に所属するインスタンスで
stretcher が起動、コードの更新
$ bundle exec cap production minne:deploy
今後に向けて
今後に向けた技術基盤の刷新
検索によるユーザー価値の創造
• solr から elasticsearch への移行
• ハンドメイドならではの検索結果の表示
高速なサイトを目指して
• 高可用性ジョブキュー(sidekiq)への変更
効果的なモバイルUIの構築に向けて
• モバイルログ基盤の構築
IaaS のハイブリッド利用
• OpenStack への段階的な移行
• 10/21 時点で1-2割のサーバーが OpenStack で稼働中
完全オートスケールの導入
• OpenStack 上で実現するツールの開発
今後に向けた技術基盤の刷新
もっと
おもしろく
できる
成長を加速する minne の技術基盤戦略

More Related Content

What's hot

今日から使い始めるChef
今日から使い始めるChef今日から使い始めるChef
今日から使い始めるChefMasahiro NAKAYAMA
 
OpenShift from Easy way to Hard ? Way
OpenShift from Easy way to Hard ? WayOpenShift from Easy way to Hard ? Way
OpenShift from Easy way to Hard ? Wayロフト くん
 
もう XAMPP / MAMP はいらない!
Vagrant で作る PHP 開発環境
もう XAMPP / MAMP はいらない!
Vagrant で作る PHP 開発環境もう XAMPP / MAMP はいらない!
Vagrant で作る PHP 開発環境
もう XAMPP / MAMP はいらない!
Vagrant で作る PHP 開発環境Masashi Shinbara
 
LL言語でもHudsonを使おう!
LL言語でもHudsonを使おう!LL言語でもHudsonを使おう!
LL言語でもHudsonを使おう!KLab株式会社
 
SmartNews TechNight Vol5 : SmartNews AdServer 解体新書 / ポストモーテム
SmartNews TechNight Vol5 : SmartNews AdServer 解体新書 / ポストモーテムSmartNews TechNight Vol5 : SmartNews AdServer 解体新書 / ポストモーテム
SmartNews TechNight Vol5 : SmartNews AdServer 解体新書 / ポストモーテムSmartNews, Inc.
 
ChefとPuppetの比較
ChefとPuppetの比較ChefとPuppetの比較
ChefとPuppetの比較Sugawara Genki
 
『How to build a High Performance PSGI/Plack Server』のその後と ISUCON3を受けての話題
『How to build a High Performance PSGI/Plack Server』のその後と ISUCON3を受けての話題『How to build a High Performance PSGI/Plack Server』のその後と ISUCON3を受けての話題
『How to build a High Performance PSGI/Plack Server』のその後と ISUCON3を受けての話題Masahiro Nagano
 
ビルドサーバで使うDocker
ビルドサーバで使うDockerビルドサーバで使うDocker
ビルドサーバで使うDockerMasashi Shinbara
 
毎秒2000Requestを捌くPerl製CMSの内部構造(Debianサーバ1台にて)
毎秒2000Requestを捌くPerl製CMSの内部構造(Debianサーバ1台にて)毎秒2000Requestを捌くPerl製CMSの内部構造(Debianサーバ1台にて)
毎秒2000Requestを捌くPerl製CMSの内部構造(Debianサーバ1台にて)nabe-abk
 
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...Naoya Ito
 
認証機能で学ぶ Laravel 5 アプリケーション
認証機能で学ぶ Laravel 5 アプリケーション認証機能で学ぶ Laravel 5 アプリケーション
認証機能で学ぶ Laravel 5 アプリケーションMasashi Shinbara
 
itamae + Serverspecで テスト駆動インフラやってみた #shibuyarb
itamae + Serverspecで テスト駆動インフラやってみた #shibuyarbitamae + Serverspecで テスト駆動インフラやってみた #shibuyarb
itamae + Serverspecで テスト駆動インフラやってみた #shibuyarbGo Sueyoshi (a.k.a sue445)
 
Ansible 2.0を使って組む kubernetesクラスタ vol.1
Ansible 2.0を使って組む kubernetesクラスタ vol.1Ansible 2.0を使って組む kubernetesクラスタ vol.1
Ansible 2.0を使って組む kubernetesクラスタ vol.1Hidetoshi Hirokawa
 
10分で作る Node.js Auto Scale 環境 with CloudFormation
10分で作る Node.js Auto Scale 環境 with CloudFormation10分で作る Node.js Auto Scale 環境 with CloudFormation
10分で作る Node.js Auto Scale 環境 with CloudFormationKazuyuki Honda
 
Heroku で作る
スケーラブルな 
PHP アプリケーション
Heroku で作る
スケーラブルな 
PHP アプリケーションHeroku で作る
スケーラブルな 
PHP アプリケーション
Heroku で作る
スケーラブルな 
PHP アプリケーションMasashi Shinbara
 
VarnishではじめるESI
VarnishではじめるESIVarnishではじめるESI
VarnishではじめるESIIwana Chan
 
Mod lua
Mod luaMod lua
Mod luado_aki
 

What's hot (20)

Puppet on AWS
Puppet on AWSPuppet on AWS
Puppet on AWS
 
今日から使い始めるChef
今日から使い始めるChef今日から使い始めるChef
今日から使い始めるChef
 
OpenShift from Easy way to Hard ? Way
OpenShift from Easy way to Hard ? WayOpenShift from Easy way to Hard ? Way
OpenShift from Easy way to Hard ? Way
 
もう XAMPP / MAMP はいらない!
Vagrant で作る PHP 開発環境
もう XAMPP / MAMP はいらない!
Vagrant で作る PHP 開発環境もう XAMPP / MAMP はいらない!
Vagrant で作る PHP 開発環境
もう XAMPP / MAMP はいらない!
Vagrant で作る PHP 開発環境
 
LL言語でもHudsonを使おう!
LL言語でもHudsonを使おう!LL言語でもHudsonを使おう!
LL言語でもHudsonを使おう!
 
SmartNews TechNight Vol5 : SmartNews AdServer 解体新書 / ポストモーテム
SmartNews TechNight Vol5 : SmartNews AdServer 解体新書 / ポストモーテムSmartNews TechNight Vol5 : SmartNews AdServer 解体新書 / ポストモーテム
SmartNews TechNight Vol5 : SmartNews AdServer 解体新書 / ポストモーテム
 
ChefとPuppetの比較
ChefとPuppetの比較ChefとPuppetの比較
ChefとPuppetの比較
 
『How to build a High Performance PSGI/Plack Server』のその後と ISUCON3を受けての話題
『How to build a High Performance PSGI/Plack Server』のその後と ISUCON3を受けての話題『How to build a High Performance PSGI/Plack Server』のその後と ISUCON3を受けての話題
『How to build a High Performance PSGI/Plack Server』のその後と ISUCON3を受けての話題
 
ビルドサーバで使うDocker
ビルドサーバで使うDockerビルドサーバで使うDocker
ビルドサーバで使うDocker
 
毎秒2000Requestを捌くPerl製CMSの内部構造(Debianサーバ1台にて)
毎秒2000Requestを捌くPerl製CMSの内部構造(Debianサーバ1台にて)毎秒2000Requestを捌くPerl製CMSの内部構造(Debianサーバ1台にて)
毎秒2000Requestを捌くPerl製CMSの内部構造(Debianサーバ1台にて)
 
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...
 
認証機能で学ぶ Laravel 5 アプリケーション
認証機能で学ぶ Laravel 5 アプリケーション認証機能で学ぶ Laravel 5 アプリケーション
認証機能で学ぶ Laravel 5 アプリケーション
 
itamae + Serverspecで テスト駆動インフラやってみた #shibuyarb
itamae + Serverspecで テスト駆動インフラやってみた #shibuyarbitamae + Serverspecで テスト駆動インフラやってみた #shibuyarb
itamae + Serverspecで テスト駆動インフラやってみた #shibuyarb
 
Ansible 2.0を使って組む kubernetesクラスタ vol.1
Ansible 2.0を使って組む kubernetesクラスタ vol.1Ansible 2.0を使って組む kubernetesクラスタ vol.1
Ansible 2.0を使って組む kubernetesクラスタ vol.1
 
らくちん Go言語
らくちん Go言語らくちん Go言語
らくちん Go言語
 
10分で作る Node.js Auto Scale 環境 with CloudFormation
10分で作る Node.js Auto Scale 環境 with CloudFormation10分で作る Node.js Auto Scale 環境 with CloudFormation
10分で作る Node.js Auto Scale 環境 with CloudFormation
 
Heroku で作る
スケーラブルな 
PHP アプリケーション
Heroku で作る
スケーラブルな 
PHP アプリケーションHeroku で作る
スケーラブルな 
PHP アプリケーション
Heroku で作る
スケーラブルな 
PHP アプリケーション
 
Puppetのススメ
PuppetのススメPuppetのススメ
Puppetのススメ
 
VarnishではじめるESI
VarnishではじめるESIVarnishではじめるESI
VarnishではじめるESI
 
Mod lua
Mod luaMod lua
Mod lua
 

Viewers also liked

How to Begin Developing Ruby Core
How to Begin Developing Ruby CoreHow to Begin Developing Ruby Core
How to Begin Developing Ruby CoreHiroshi SHIBATA
 
Large-scaled Deploy Over 100 Servers in 3 Minutes
Large-scaled Deploy Over 100 Servers in 3 MinutesLarge-scaled Deploy Over 100 Servers in 3 Minutes
Large-scaled Deploy Over 100 Servers in 3 MinutesHiroshi SHIBATA
 
Thorでカジュアルにコマンドラインツールを作る
Thorでカジュアルにコマンドラインツールを作るThorでカジュアルにコマンドラインツールを作る
Thorでカジュアルにコマンドラインツールを作るnixiesan
 
Middleware as Code with mruby
Middleware as Code with mrubyMiddleware as Code with mruby
Middleware as Code with mrubyHiroshi SHIBATA
 
Serf / Consul 入門 ~仕事を楽しくしよう~
Serf / Consul 入門 ~仕事を楽しくしよう~Serf / Consul 入門 ~仕事を楽しくしよう~
Serf / Consul 入門 ~仕事を楽しくしよう~Masahito Zembutsu
 
GitHub Enterprise with GMO Pepabo
GitHub Enterprise with GMO PepaboGitHub Enterprise with GMO Pepabo
GitHub Enterprise with GMO PepaboHiroshi SHIBATA
 
Middleware as Code with mruby
Middleware as Code with mrubyMiddleware as Code with mruby
Middleware as Code with mrubyHiroshi SHIBATA
 
[社内勉強会]SPAのすすめ
[社内勉強会]SPAのすすめ[社内勉強会]SPAのすすめ
[社内勉強会]SPAのすすめhirooooo
 
オンラインゲームソリューション@トレジャーデータ
オンラインゲームソリューション@トレジャーデータオンラインゲームソリューション@トレジャーデータ
オンラインゲームソリューション@トレジャーデータTakahiro Inoue
 
How to test code with mruby
How to test code with mrubyHow to test code with mruby
How to test code with mrubyHiroshi SHIBATA
 
How to Begin to Develop Ruby Core
How to Begin to Develop Ruby CoreHow to Begin to Develop Ruby Core
How to Begin to Develop Ruby CoreHiroshi SHIBATA
 
mruby で mackerel のプラグインを作るはなし
mruby で mackerel のプラグインを作るはなしmruby で mackerel のプラグインを作るはなし
mruby で mackerel のプラグインを作るはなしHiroshi SHIBATA
 
Practical Testing of Ruby Core
Practical Testing of Ruby CorePractical Testing of Ruby Core
Practical Testing of Ruby CoreHiroshi SHIBATA
 
MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜
MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜
MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜Takahiro Inoue
 
The story of language development
The story of language developmentThe story of language development
The story of language developmentHiroshi SHIBATA
 
Advanced technic for OS upgrading in 3 minutes
Advanced technic for OS upgrading in 3 minutesAdvanced technic for OS upgrading in 3 minutes
Advanced technic for OS upgrading in 3 minutesHiroshi SHIBATA
 
React.js + Reduxで作るSPA
React.js + Reduxで作るSPAReact.js + Reduxで作るSPA
React.js + Reduxで作るSPAShohei Saeki
 

Viewers also liked (20)

How to Begin Developing Ruby Core
How to Begin Developing Ruby CoreHow to Begin Developing Ruby Core
How to Begin Developing Ruby Core
 
Large-scaled Deploy Over 100 Servers in 3 Minutes
Large-scaled Deploy Over 100 Servers in 3 MinutesLarge-scaled Deploy Over 100 Servers in 3 Minutes
Large-scaled Deploy Over 100 Servers in 3 Minutes
 
Thorでカジュアルにコマンドラインツールを作る
Thorでカジュアルにコマンドラインツールを作るThorでカジュアルにコマンドラインツールを作る
Thorでカジュアルにコマンドラインツールを作る
 
High Performance tDiary
High Performance tDiaryHigh Performance tDiary
High Performance tDiary
 
Middleware as Code with mruby
Middleware as Code with mrubyMiddleware as Code with mruby
Middleware as Code with mruby
 
Serf / Consul 入門 ~仕事を楽しくしよう~
Serf / Consul 入門 ~仕事を楽しくしよう~Serf / Consul 入門 ~仕事を楽しくしよう~
Serf / Consul 入門 ~仕事を楽しくしよう~
 
GitHub Enterprise with GMO Pepabo
GitHub Enterprise with GMO PepaboGitHub Enterprise with GMO Pepabo
GitHub Enterprise with GMO Pepabo
 
Middleware as Code with mruby
Middleware as Code with mrubyMiddleware as Code with mruby
Middleware as Code with mruby
 
[社内勉強会]SPAのすすめ
[社内勉強会]SPAのすすめ[社内勉強会]SPAのすすめ
[社内勉強会]SPAのすすめ
 
オンラインゲームソリューション@トレジャーデータ
オンラインゲームソリューション@トレジャーデータオンラインゲームソリューション@トレジャーデータ
オンラインゲームソリューション@トレジャーデータ
 
How DSL works on Ruby
How DSL works on RubyHow DSL works on Ruby
How DSL works on Ruby
 
How to test code with mruby
How to test code with mrubyHow to test code with mruby
How to test code with mruby
 
How to Begin to Develop Ruby Core
How to Begin to Develop Ruby CoreHow to Begin to Develop Ruby Core
How to Begin to Develop Ruby Core
 
mruby で mackerel のプラグインを作るはなし
mruby で mackerel のプラグインを作るはなしmruby で mackerel のプラグインを作るはなし
mruby で mackerel のプラグインを作るはなし
 
Practical Testing of Ruby Core
Practical Testing of Ruby CorePractical Testing of Ruby Core
Practical Testing of Ruby Core
 
Practical ngx_mruby
Practical ngx_mrubyPractical ngx_mruby
Practical ngx_mruby
 
MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜
MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜
MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜
 
The story of language development
The story of language developmentThe story of language development
The story of language development
 
Advanced technic for OS upgrading in 3 minutes
Advanced technic for OS upgrading in 3 minutesAdvanced technic for OS upgrading in 3 minutes
Advanced technic for OS upgrading in 3 minutes
 
React.js + Reduxで作るSPA
React.js + Reduxで作るSPAReact.js + Reduxで作るSPA
React.js + Reduxで作るSPA
 

Similar to 成長を加速する minne の技術基盤戦略

シラサギハンズオン 1015 1016
シラサギハンズオン 1015 1016シラサギハンズオン 1015 1016
シラサギハンズオン 1015 1016Yu Ito
 
Cloudstack user group meeting in osaka
Cloudstack user group meeting in osakaCloudstack user group meeting in osaka
Cloudstack user group meeting in osakaNaotaka Jay HOTTA
 
Server side Swift & Photo Booth
Server side Swift & Photo Booth Server side Swift & Photo Booth
Server side Swift & Photo Booth LINE Corporation
 
マイクロサービス時代の生存戦略 with HashiCorp
マイクロサービス時代の生存戦略 with HashiCorpマイクロサービス時代の生存戦略 with HashiCorp
マイクロサービス時代の生存戦略 with HashiCorpMasahito Zembutsu
 
恋に落ちるデプロイツール
恋に落ちるデプロイツール恋に落ちるデプロイツール
恋に落ちるデプロイツールtotty jp
 
ラズパイ2で動く Docker PaaS
ラズパイ2で動く Docker PaaSラズパイ2で動く Docker PaaS
ラズパイ2で動く Docker PaaSnpsg
 
Dockerを使ったローカルでの開発から本番環境へのデプロイまで
Dockerを使ったローカルでの開発から本番環境へのデプロイまでDockerを使ったローカルでの開発から本番環境へのデプロイまで
Dockerを使ったローカルでの開発から本番環境へのデプロイまでRyo Nakamaru
 
Wasm blazor and wasi 2
Wasm blazor and wasi 2Wasm blazor and wasi 2
Wasm blazor and wasi 2Takao Tetsuro
 
はてなにおける継続的デプロイメントの現状と Docker の導入
はてなにおける継続的デプロイメントの現状と Docker の導入はてなにおける継続的デプロイメントの現状と Docker の導入
はてなにおける継続的デプロイメントの現状と Docker の導入Yu Nobuoka
 
Osc fukuoka xAI Meetup
Osc fukuoka xAI MeetupOsc fukuoka xAI Meetup
Osc fukuoka xAI Meetupru pic
 
ヤギにサーバーを管理してもらう話
ヤギにサーバーを管理してもらう話ヤギにサーバーを管理してもらう話
ヤギにサーバーを管理してもらう話Masaki Kobayashi
 
Node予備校 vol.1 名古屋
Node予備校 vol.1 名古屋Node予備校 vol.1 名古屋
Node予備校 vol.1 名古屋Mori Shingo
 
Cloud Foundry: Open Platform as a Service
Cloud Foundry: Open Platform as a ServiceCloud Foundry: Open Platform as a Service
Cloud Foundry: Open Platform as a ServiceShunsuke Kurumatani
 
TripleOの光と闇
TripleOの光と闇TripleOの光と闇
TripleOの光と闇Manabu Ori
 
PaaSの作り方 Sqaleの場合
PaaSの作り方 Sqaleの場合PaaSの作り方 Sqaleの場合
PaaSの作り方 Sqaleの場合hiboma
 
serverspecを使用したサーバ設定テストの実例
serverspecを使用したサーバ設定テストの実例serverspecを使用したサーバ設定テストの実例
serverspecを使用したサーバ設定テストの実例Koichi Shimozono
 
Docker ComposeでMastodonが必要なものを梱包する話
Docker ComposeでMastodonが必要なものを梱包する話Docker ComposeでMastodonが必要なものを梱包する話
Docker ComposeでMastodonが必要なものを梱包する話Masahito Zembutsu
 

Similar to 成長を加速する minne の技術基盤戦略 (20)

シラサギハンズオン 1015 1016
シラサギハンズオン 1015 1016シラサギハンズオン 1015 1016
シラサギハンズオン 1015 1016
 
Cloudstack user group meeting in osaka
Cloudstack user group meeting in osakaCloudstack user group meeting in osaka
Cloudstack user group meeting in osaka
 
Server side Swift & Photo Booth
Server side Swift & Photo Booth Server side Swift & Photo Booth
Server side Swift & Photo Booth
 
マイクロサービス時代の生存戦略 with HashiCorp
マイクロサービス時代の生存戦略 with HashiCorpマイクロサービス時代の生存戦略 with HashiCorp
マイクロサービス時代の生存戦略 with HashiCorp
 
恋に落ちるデプロイツール
恋に落ちるデプロイツール恋に落ちるデプロイツール
恋に落ちるデプロイツール
 
ラズパイ2で動く Docker PaaS
ラズパイ2で動く Docker PaaSラズパイ2で動く Docker PaaS
ラズパイ2で動く Docker PaaS
 
Dockerを使ったローカルでの開発から本番環境へのデプロイまで
Dockerを使ったローカルでの開発から本番環境へのデプロイまでDockerを使ったローカルでの開発から本番環境へのデプロイまで
Dockerを使ったローカルでの開発から本番環境へのデプロイまで
 
Wasm blazor and wasi 2
Wasm blazor and wasi 2Wasm blazor and wasi 2
Wasm blazor and wasi 2
 
はてなにおける継続的デプロイメントの現状と Docker の導入
はてなにおける継続的デプロイメントの現状と Docker の導入はてなにおける継続的デプロイメントの現状と Docker の導入
はてなにおける継続的デプロイメントの現状と Docker の導入
 
Open Source x AI
Open Source x AIOpen Source x AI
Open Source x AI
 
Osc fukuoka xAI Meetup
Osc fukuoka xAI MeetupOsc fukuoka xAI Meetup
Osc fukuoka xAI Meetup
 
ヤギにサーバーを管理してもらう話
ヤギにサーバーを管理してもらう話ヤギにサーバーを管理してもらう話
ヤギにサーバーを管理してもらう話
 
Node予備校 vol.1 名古屋
Node予備校 vol.1 名古屋Node予備校 vol.1 名古屋
Node予備校 vol.1 名古屋
 
Cloud Foundry: Open Platform as a Service
Cloud Foundry: Open Platform as a ServiceCloud Foundry: Open Platform as a Service
Cloud Foundry: Open Platform as a Service
 
TripleOの光と闇
TripleOの光と闇TripleOの光と闇
TripleOの光と闇
 
PaaSの作り方 Sqaleの場合
PaaSの作り方 Sqaleの場合PaaSの作り方 Sqaleの場合
PaaSの作り方 Sqaleの場合
 
hbstudy37 doc
hbstudy37 dochbstudy37 doc
hbstudy37 doc
 
serverspecを使用したサーバ設定テストの実例
serverspecを使用したサーバ設定テストの実例serverspecを使用したサーバ設定テストの実例
serverspecを使用したサーバ設定テストの実例
 
Docker ComposeでMastodonが必要なものを梱包する話
Docker ComposeでMastodonが必要なものを梱包する話Docker ComposeでMastodonが必要なものを梱包する話
Docker ComposeでMastodonが必要なものを梱包する話
 
Hadoop on LXC
Hadoop on LXCHadoop on LXC
Hadoop on LXC
 

More from Hiroshi SHIBATA

Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Deep dive into Ruby's require - RubyConf Taiwan 2023
Deep dive into Ruby's require - RubyConf Taiwan 2023Deep dive into Ruby's require - RubyConf Taiwan 2023
Deep dive into Ruby's require - RubyConf Taiwan 2023Hiroshi SHIBATA
 
How resolve Gem dependencies in your code?
How resolve Gem dependencies in your code?How resolve Gem dependencies in your code?
How resolve Gem dependencies in your code?Hiroshi SHIBATA
 
How resolve Gem dependencies in your code?
How resolve Gem dependencies in your code?How resolve Gem dependencies in your code?
How resolve Gem dependencies in your code?Hiroshi SHIBATA
 
Ruby コミッターと歩む Ruby を用いたプロダクト開発
Ruby コミッターと歩む Ruby を用いたプロダクト開発Ruby コミッターと歩む Ruby を用いたプロダクト開発
Ruby コミッターと歩む Ruby を用いたプロダクト開発Hiroshi SHIBATA
 
Why ANDPAD commit Ruby and RubyKaigi?
Why ANDPAD commit Ruby and RubyKaigi?Why ANDPAD commit Ruby and RubyKaigi?
Why ANDPAD commit Ruby and RubyKaigi?Hiroshi SHIBATA
 
RailsGirls から始める エンジニアリングはじめの一歩
RailsGirls から始める エンジニアリングはじめの一歩RailsGirls から始める エンジニアリングはじめの一歩
RailsGirls から始める エンジニアリングはじめの一歩Hiroshi SHIBATA
 
How to develop the Standard Libraries of Ruby?
How to develop the Standard Libraries of Ruby?How to develop the Standard Libraries of Ruby?
How to develop the Standard Libraries of Ruby?Hiroshi SHIBATA
 
The details of CI/CD environment for Ruby
The details of CI/CD environment for RubyThe details of CI/CD environment for Ruby
The details of CI/CD environment for RubyHiroshi SHIBATA
 
Dependency Resolution with Standard Libraries
Dependency Resolution with Standard LibrariesDependency Resolution with Standard Libraries
Dependency Resolution with Standard LibrariesHiroshi SHIBATA
 
Roadmap for RubyGems 4 and Bundler 3
Roadmap for RubyGems 4 and Bundler 3Roadmap for RubyGems 4 and Bundler 3
Roadmap for RubyGems 4 and Bundler 3Hiroshi SHIBATA
 
The Future of library dependency management of Ruby
 The Future of library dependency management of Ruby The Future of library dependency management of Ruby
The Future of library dependency management of RubyHiroshi SHIBATA
 
Ruby Security the Hard Way
Ruby Security the Hard WayRuby Security the Hard Way
Ruby Security the Hard WayHiroshi SHIBATA
 
OSS Security the hard way
OSS Security the hard wayOSS Security the hard way
OSS Security the hard wayHiroshi SHIBATA
 
The Future of library dependency manageement of Ruby
The Future of library dependency manageement of RubyThe Future of library dependency manageement of Ruby
The Future of library dependency manageement of RubyHiroshi SHIBATA
 
The Future of Dependency Management for Ruby
The Future of Dependency Management for RubyThe Future of Dependency Management for Ruby
The Future of Dependency Management for RubyHiroshi SHIBATA
 
The Future of Bundled Bundler
The Future of Bundled BundlerThe Future of Bundled Bundler
The Future of Bundled BundlerHiroshi SHIBATA
 
Productive Organization with Ruby
Productive Organization with RubyProductive Organization with Ruby
Productive Organization with RubyHiroshi SHIBATA
 

More from Hiroshi SHIBATA (20)

Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Deep dive into Ruby's require - RubyConf Taiwan 2023
Deep dive into Ruby's require - RubyConf Taiwan 2023Deep dive into Ruby's require - RubyConf Taiwan 2023
Deep dive into Ruby's require - RubyConf Taiwan 2023
 
How resolve Gem dependencies in your code?
How resolve Gem dependencies in your code?How resolve Gem dependencies in your code?
How resolve Gem dependencies in your code?
 
How resolve Gem dependencies in your code?
How resolve Gem dependencies in your code?How resolve Gem dependencies in your code?
How resolve Gem dependencies in your code?
 
Ruby コミッターと歩む Ruby を用いたプロダクト開発
Ruby コミッターと歩む Ruby を用いたプロダクト開発Ruby コミッターと歩む Ruby を用いたプロダクト開発
Ruby コミッターと歩む Ruby を用いたプロダクト開発
 
Why ANDPAD commit Ruby and RubyKaigi?
Why ANDPAD commit Ruby and RubyKaigi?Why ANDPAD commit Ruby and RubyKaigi?
Why ANDPAD commit Ruby and RubyKaigi?
 
RailsGirls から始める エンジニアリングはじめの一歩
RailsGirls から始める エンジニアリングはじめの一歩RailsGirls から始める エンジニアリングはじめの一歩
RailsGirls から始める エンジニアリングはじめの一歩
 
How to develop the Standard Libraries of Ruby?
How to develop the Standard Libraries of Ruby?How to develop the Standard Libraries of Ruby?
How to develop the Standard Libraries of Ruby?
 
The details of CI/CD environment for Ruby
The details of CI/CD environment for RubyThe details of CI/CD environment for Ruby
The details of CI/CD environment for Ruby
 
Dependency Resolution with Standard Libraries
Dependency Resolution with Standard LibrariesDependency Resolution with Standard Libraries
Dependency Resolution with Standard Libraries
 
Roadmap for RubyGems 4 and Bundler 3
Roadmap for RubyGems 4 and Bundler 3Roadmap for RubyGems 4 and Bundler 3
Roadmap for RubyGems 4 and Bundler 3
 
The Future of library dependency management of Ruby
 The Future of library dependency management of Ruby The Future of library dependency management of Ruby
The Future of library dependency management of Ruby
 
Ruby Security the Hard Way
Ruby Security the Hard WayRuby Security the Hard Way
Ruby Security the Hard Way
 
OSS Security the hard way
OSS Security the hard wayOSS Security the hard way
OSS Security the hard way
 
The Future of library dependency manageement of Ruby
The Future of library dependency manageement of RubyThe Future of library dependency manageement of Ruby
The Future of library dependency manageement of Ruby
 
The Future of Dependency Management for Ruby
The Future of Dependency Management for RubyThe Future of Dependency Management for Ruby
The Future of Dependency Management for Ruby
 
The Future of Bundled Bundler
The Future of Bundled BundlerThe Future of Bundled Bundler
The Future of Bundled Bundler
 
What's new in RubyGems3
What's new in RubyGems3What's new in RubyGems3
What's new in RubyGems3
 
Productive Organization with Ruby
Productive Organization with RubyProductive Organization with Ruby
Productive Organization with Ruby
 
Gems on Ruby
Gems on RubyGems on Ruby
Gems on Ruby
 

成長を加速する minne の技術基盤戦略

  • 2. self.introduce => { name: “SHIBATA Hiroshi”, nickname: “hsbt”, title: “Chief engineer at GMO Pepabo, Inc.”, commit_bits: [“ruby”, “rake”, “rubygems”, “rdoc”, “tdiary”, “hiki”, “railsgirls”, “railsgirls-jp”, …], sites: [“hsbt.org”, ruby-lang.org”, “rubyci.com”, “railsgirls.com”, “railsgirls.jp”], }
  • 3.
  • 5. 2014/11 の minne の状況 • IaaS の上で動くシンプルな Rails アプリケーション • Rails が動いているサーバーは 6 台 • デプロイは capistrano 2 を使用 • ジョブワーカーは Web サーバーに同居 • 用途不明なサーバーもちらほら…
  • 6. オペレーションは心温まる手作業 • 動いているサーバーを LB から外して “Golden Image” を 作成し、インスタンスを複製 • 複製したインスタンスの設定変更は手順書をもとに手作 業で実施 • おおよそ 4-6 時間の工程…
  • 7. No ssh “No SSH” ルールを作成し、Packer でイメージ構築を自動化
  • 8. “No SSH” のコンセプト ある程度の規模のサービスにとっては 1 サーバーは UNIX でいう 1 プロセスと同等である プロセスに gdb でアタッチしたりしない → インスタンスに ssh ログインしない プロセスのメモリを書き換えて変数を変えたりしない → インスタンスの設定ファイルを変えたりしない
  • 9. 遅い処理 OS 起動 puppet/chef 実行 Rails アプリケーションの デプロイ No SSH によるサーバー構築の流れ 速い処理 OS 設定の変更 Capistrano の準備 LB に接続(サービスイン)
  • 10. Packer によるイメージ作成 • 公式 OS イメージ • プラットフォーム提供 • Minimal イメージ(phase 1) • Network, User, Package 設定のみ実行 • puppet/chef, プラットフォームの cli ツールを追加 • Role 専用イメージ(phase 2) • 起動するだけで Role 特有のアプリケーションが起動
  • 11. Minimal イメージ cloud-init provisioner #cloud-config repo_update: true repo_upgrade: none packages: - git - curl - unzip users: - default locale: ja_JP.UTF-8 timezone: Asia/Tokyo rpm -ivh http://yum.puppetlabs.com/ puppetlabs-release-el-7.noarch.rpm yum -y update yum -y install puppet yum -y install python-pip pip install awscli sed -i 's/name: centos/name: cloud-user/' /etc/ cloud/cloud.cfg echo 'preserve_hostname: true' >> /etc/cloud/ cloud.cfg
  • 12. www イメージ cloud-init provisioner #cloud-config preserve_hostname: false puppet agent -t set -e monit stop unicorn /usr/local/bin/globefish -w rm -rf /var/www/deploys/minne/releases/* rm -f /var/www/deploys/minne/current # tar xf するだけで動くRails アプリケーションを取得 (snip) # mackerel のホスト設定が packer 実行時のものとかぶらないように初期化 rm /var/lib/mackerel-agent/id # cloud-init をもう一度動かすようにする準備 rm -rf /var/lib/cloud/sem /var/lib/cloud/instances/*
  • 13. packer の実行は ruby の thor から実行 $ some_cli_tool ami build-minimal $ some_cli_tool ami build-www $ some_cli_tool ami build-www —init $ some_cli_tool ami build-www -a ami-id module SomeCliTool class Ami < Thor method_option :ami_id, type: :string, aliases: "-a" method_option :init, type: :boolean desc 'build-www', 'wwwの最新イメージをビルドします' def build_www … end end end thor でオペレーションをコード化 $ some_cli_tool instances launch -c … $ some_cli_tool mackerel fixrole $ some_cli_tool scale up $ some_cli_tool deploy blue-green イメージ作成 その他 IaaS 操作コマンド
  • 15. インフラCIの導入 サーバーにインストール済みのパッケージや起動している プロセスなどの詳細は Serverspec を用いて継続的にテスト を実行 Puppet + Drone CI(with Docker) + Serverspec = WIN CIがあれば何でも(puppet マニフェストをアグレッシブにリ ファクタリング)できる!
  • 16. Serverspec “RSpec tests for your servers configured by CFEngine, Puppet, Ansible, Itamae or anything else.” http://serverspec.org/ % rake -T rake mtest # Run mruby-mtest rake spec # Run serverspec code for all rake spec:base # Run serverspec code for base.minne.pbdev rake spec:batch # Run serverspec code for batch.minne.pbdev rake spec:db:master # Run serverspec code for master db rake spec:db:slave # Run serverspec code for slave db rake spec:gateway # Run serverspec code for gateway.minne.pbdev (snip)
  • 17. Drone CI “CONTINUOUS INTEGRATION FOR GITHUB AND BITBUCKET THAT MONITORS YOUR CODE FOR BUGS” https://drone.io/ Drone CI は nyah と呼ばれる Openstack の上に構築
  • 18. Integration tests with Packer Packer の実行後にも Serverspec でテスト実行 (by @udzura) "provisioners": [ (snip) { "type": "shell", "script": "{{user `project_root`}}packer/minimal/provisioners/run-serverspec.sh", "execute_command": "{{ .Vars }} sudo -E sh '{{ .Path }}'" } ] yum -y -q install rubygem-bundler cd /tmp/serverspec bundle install --path vendor/bundle bundle exec rake spec packer configuration run-serverspec.sh
  • 20. Blue-Green デプロイの手順 1.起動するインスタンスを Packer で作成し、hakata コマ ンドで起動 2.LB に接続して、“InService” となるまで待機 3.古いインスタンスを廃棄
  • 21. B-G デプロイの hakata コマンド class deploy < Thor def blue_green old_instances = running_instances(load_balancer_name) invoke Instances, [:launch], options.merge(:count => old_instances.count) catch(:in_service) do sleep_time = 60 loop do instances = running_instances(load_balancer_name) throw(:in_service) if (instances.count == old_instances.count * 2) && instances.all?{|i| i.status == 'InService'} sleep sleep_time sleep_time = [sleep_time - 10, 10].max end end old_instances.each do |oi| oi.delete end end end
  • 23. Mackerel “A Revolutionary New Kind ofApplication Performance Management. Realize the potential in Cloud Computingby managing cloud servers through “roles”” https://mackerel.io
  • 24. consul + consul-alerts Disposable なインスタンスのプロ セス監視は consul と consul-alerts で実行 https://github.com/hashicorp/consul https://github.com/AcalephStorage/consul- alerts
  • 25. td-agent と log collector 動的に変化するイン スタンスのログは td- agent で集約 <match nginx.**> type forward send_timeout 60s recover_wait 10s heartbeat_interval 1s phi_threshold 16 hard_timeout 60s <server> name aggregate.server host aggregate.server weight 100 </server> <server> name aggregate2.server host aggregate2.server weight 100 standby </server> </match> <match nginx.access.*> type copy <store> type file (snip) </store> <store> type tdlog apikey api_key auto_create_table true database database table access use_ssl true flush_interval 120 buffer_path /data/tmp/td-agent-td/access </store> </match>
  • 27. 2015/11 現在の minne の状況 • Rails 4.2.4 and Ruby 2.2.3, MySQL 5.6.23 • Capistrano 3, stretcher + consul • solr(with sunspot), delayed_job • Models: 136, Controllers 143, Code to Test Ratio: 1:1.7 • サーバー台数 100台弱
  • 28. capistrano によるデプロイ問題 • ある日、社内の GHE が不定 期に重くなるという報告 • GHE にログインしてプロセス リストを見てみると… • git…git…git…(100個くらい) • minne がデプロイすると全 サーバーが GHE に git clone/ fetch を実行する
  • 29. consul with stretcher • トリガとして consul/serf のイベントを受け取って動 作するプログラム • インスタンスが自律的にコー ド更新を実行 • 更新するコードは s3 から 取得 https://github.com/fujiwara/stretcher
  • 30. Bundled package of Rails application Rails アプリケーションを Ruby だけあれば起動するような tgz を作成(bundle install/assets precompile 済み) capistrano を用いてビルド専用サーバーで各種タスクを実 行後に s3 へアップロード $ bundle exec cap production archive_project desc "Create a tarball that is set up for deploy" task :archive_project => [:ensure_directories, :checkout_local, :bundle, :npm_install, :bower_install, :asset_precompile, :create_tarball, :upload_tarball, :cleanup_dirs]
  • 31. consul の event を通知するために consul watch で stretcher を systemd でデーモン化 consul watch と stretcher [Unit] Description=Stretcher Deamon with Consul Documentation=https://github.com/fujiwara/stretcher [Service] User=rails Group=rails EnvironmentFile=-/etc/sysconfig/consul Environment="AWS_CONFIG_FILE=/home/rails/.aws/config" ExecStart=/usr/bin/consul watch -type event -name <%= @event_name %> stretcher ExecReload=/bin/kill -HUP $MAINPID KillSignal=SIGINT [Install] WantedBy=multi-user.target
  • 32. systemd への完全移行 supervisord や monit で動かしていた consul などを全て OS 標準の systemd へと移行 [Unit] Description=Rack HTTP server for fast clients and Unix Documentation=http://unicorn.bogomips.org/ [Service] User=rails Group=rails EnvironmentFile=-/etc/sysconfig/unicorn WorkingDirectory=/var/www/rails_applicaiton PIDFile=/var/www/rails_application/shared/pids/unicorn.pid ExecStart=/usr/local/rbenv/shims/bundle exec unicorn -c config/unicorn.conf -E <%= @environment %> ExecReload=/bin/kill -USR2 $MAINPID ExecStop=/bin/kill -QUIT $MAINPID KillSignal=SIGINT [Install] WantedBy=multi-user.target
  • 33. rails 向け stretcher manifests src: s3://your-buckets-name/production/application-<%= env.now %>.tgz checksum: <%= checksum %> dest: /var/www/rails/releases/<%= env.now %> commands: pre: - post: - ln -nfs /var/www/rails/releases/<%= env.now %> /var/www/rails/current - rm -rf /var/www/rails/current/log - ln -nfs /var/www/rails/shared/log /var/www/rails/current/log - mkdir -p /var/www/rails/current/tmp - ln -nfs /var/www/rails/shared/pids /var/www/rails/current/tmp/pids - ln -nfs /var/www/rails/shared/data /var/www/rails/current/data success: - <%= h[:cmd] %> && rm-releases /var/www/rails/releases 5 failure: - cat >> /tmp/failure - (slack に失敗メッセージを通知) - "*.pid" - "*.socket" yaml を erb から生成 し、s3 にアップロー ドする cap task を作 成 tgz 作成後に実行
  • 34. capistrano との統合 namespace :minne do desc 'Deploy via Stretcher' task :deploy do set :deploying, true invoke "minne:archive_project" (ENV['ROLES'] || fetch(:minne_deploy_roles)).split(',').each do |target_role| on application_builder_roles do opts = ["-name deploy_#{target_role}_#{fetch(:stage)}"] opts << "-node #{ENV['HOSTS']}" if ENV['HOSTS'] opts << “s3://your-buckets-name/manifest_#{target_role}.yml" execute :consul, :event, *opts end end end before 'minne:deploy', 'slack:deploy:starting' after 'minne:deploy', ‘slack:deploy:finished' end
  • 35. stretcher を用いて cap からデプロイ 1. build サーバーで rails + bundler gems + node modules + assets 入りの tgz を作成、s3 にアップロード 2. stretcher 用の manifests を作成して s3 にアップロード 3. consul event を指定した roles に対して発行 4. event を受け取った role に所属するインスタンスで stretcher が起動、コードの更新 $ bundle exec cap production minne:deploy
  • 37. 今後に向けた技術基盤の刷新 検索によるユーザー価値の創造 • solr から elasticsearch への移行 • ハンドメイドならではの検索結果の表示 高速なサイトを目指して • 高可用性ジョブキュー(sidekiq)への変更 効果的なモバイルUIの構築に向けて • モバイルログ基盤の構築
  • 38. IaaS のハイブリッド利用 • OpenStack への段階的な移行 • 10/21 時点で1-2割のサーバーが OpenStack で稼働中 完全オートスケールの導入 • OpenStack 上で実現するツールの開発 今後に向けた技術基盤の刷新