PuppetをPassengerで動かして大規模サイトに対応させる
大規模サイトでPuppetを運用する場合、複数のノードに同時にmanifestを適用すると思います。しかし、同時接続数5台を超えたあたりからクライアントのリクエストを捌けなくなり適用時にエラーが発生することがよくあります。その場合、同時接続数を減らしたり接続時間をずらしたりして対応していると思います。ただ、そんなのやってられねーって人に、Passengerを使ったパフォーマンスの改善を紹介します。
前提
Passengerってなに?
上記で説明されている通りApache等でRubyアプリケーションを動かすための動作環境です。インストールと設定が楽で、RailsにおいてはほとんどApacheの設定だけで動作環境の設定が済んでしまいます。
注意事項
- puppet v0.25系環境で、rack,passengerの最新版をインストールしても動作しません。
上記でも書かれているように、何も考えずrackとpassengerの最新版をインストールしても動作しません。
Ruby v1.8.5(CentOS5系のデフォルトバージョン)では、
Remove rack 1.2.1 first and then install rack 1.1.0. It seems that rack
1.1.0 and passenger 2.2.9 have been the magic combination (at least for me).
- Gary
って、言ってるのでおとなしくrack v1.1.0とpassenger v2.2.9をインストールしましょう。
Railsアプリケーションを既に動かしている場合は、別のサーバを用意するかした方がいいです。
Ruby v1.8.7系では最新版でも問題なく動作するかもしれません。(未検証)
手順
必要なソフトウエアのインストール
$ sudo yum install httpd httpd-devel ruby-devel rubygems mod_ssl $ sudo gem rack -v 1.1.0 $ sudo gem Passenger -v 2.2.9
Passenger-Apacheモジュールのビルドとインストール
対話形式なので、指示に従って進めます。
$ sudo passenger-install-apache2-module
途中で必要なパッケージがインストールされていなければ、下記のように親切に指示されますので指示に従ってインストールした後、再実行しましょう。
Installation instructions for required software * To install Curl development headers with SSL support: Please run yum install curl-devel as root. * To install OpenSSL development headers: Please run yum install openssl-devel as root.
Rackの設定
Rack用のディレクトリと設定ファイルを作成します。Puppet v0.25系からはconfig.ruのテンプレートが用意されているのでそれをコピーして使うだけでいいです。
$ mkdir -p /usr/share/puppet/rack/puppetmasterd
$ mkdir /usr/share/puppet/rack/puppetmasterd/public /usr/share/puppet/rack/puppetmasterd/tmp
$ cp /usr/share/puppet/ext/rack/files/config.ru /usr/share/puppet/rack/puppetmasterd/
$ chown puppet /usr/share/puppet/rack/puppetmasterd/config.ru
Apacheの設定
インストール時に指示されたように、passenger-Apacheモジュールの設定を組み込みます。
$ sudo vim /etc/httpd/conf.d/passenger.conf
# passenger.conf LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.2.9/ext/apache2/mod_passenger.so PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.2.9 PassengerRuby /usr/bin/ruby
puppetmasterを動かすためのVirtualHostの設定を行います。
SSL証明書ファイルの名前はssl配下のディレクトリに作成されているサーバ用証明書のファイル名に置き換えてください。
$ sudo vim /etc/httpd/conf.d/puppetmaster.conf
# puppetmaster.conf # Performance #PassengerPoolIdleTime 300 # default: 300 PassengerUseGlobalQueue on PassengerMaxPoolSize 60 Listen 8140 <VirtualHost *:8140> SSLEngine on SSLCipherSuite SSLv2:-LOW:-EXPORT:RC4+RSA SSLCertificateFile /var/lib/puppet/ssl/certs/puppet-001.example.com.pem SSLCertificateKeyFile /var/lib/puppet/ssl/private_keys/puppet-001.example.com.pem SSLCertificateChainFile /var/lib/puppet/ssl/certs/ca.pem SSLCACertificateFile /var/lib/puppet/ssl/certs/ca.pem # CRL checking should be enabled; if you have problems with Apache complaining about the CRL, disable the next line SSLCARevocationFile /var/lib/puppet/ssl/ca/ca_crl.pem SSLVerifyClient optional SSLVerifyDepth 1 SSLOptions +StdEnvVars # The following client headers allow the same configuration to work with Pound. RequestHeader set X-SSL-Subject %{SSL_CLIENT_S_DN}e RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e PassengerHighPerformance on # DO NOT USE Global config!!(disable mod_rewrite) RackAutoDetect On RackBaseURI / DocumentRoot /usr/share/puppet/rack/puppetmasterd/public/ CustomLog /puppet/logs/puppet_access_log combined ErrorLog /puppet/logs/puppet_error_log <Directory /usr/share/puppet/rack/puppetmasterd/> Options None AllowOverride None Order Allow,Deny Allow from all </Directory> </VirtualHost>
後はApacheを起動するだけです。
動作確認
クライアントから、puppetd等でアクセスするとpassengerはpuppetmasterのインスタンスを起動し通常通りpuppetmasterにアクセスできるようになります。
$ sudo /usr/sbin/puppetd --verbose --no-daemonize --onetime --noop
サーバで下記のコマンドを実行すると、passengerがpuppetmasterを起動していることを確認できます。
$ sudo passenger-status ----------- General information ----------- max = 15 count = 1 active = 1 inactive = 0 Waiting on global queue: 0 ----------- Domains ----------- /usr/share/puppet/rack/puppetmasterd: PID: 8897 Sessions: 1 Processed: 1 Uptime: 12s
Tips
通常の/etc/init.d/puppetmasterdスクリプトを使用した方法では、/etc/sysconfig/puppetmasterの内容をデーモン実行時のコマンドライン引数として読み込めたのですが、この方法でも同じことが可能です。
config.ruに記述することで実現できます。
# config.ru # a config.ru, for use with every rack-compatible webserver. # SSL needs to be handled outside this, though. # if puppet is not in your RUBYLIB: # $:.unshift('/opt/puppet/lib') $0 = "puppetmasterd" require 'puppet' # if you want debugging: # ARGV << "--debug" ARGV << "--rack" ARGV << "--confdir=/puppet/etc" ARGV << "--logdest=/var/log/puppet/puppetmaster.log" require 'puppet/application/puppetmasterd' # we're usually running inside a Rack::Builder.new {} block, # therefore we need to call run *here*. run Puppet::Application[:puppetmasterd].run
上記の通り、ARGV変数に追加したいオプションを記述するだけです。
終わりに
Passengerを使用することにより、悩みどころだった大規模サイトでのpuppet運用がこれで可能になります。
''passenger-status''や''sudo passenger-memory-stats''を使うことによりモニタリングが可能ですし、
Passengerのチューニング可能でApacheの設定に記述するだけなので、手軽に運用できると思います。