Debian 8 : Configure Nginx and Passenger to supercharge your PuppetMaster
Par Mathieu le mercredi 22 juin 2016, 21:16 - Hacks - Lien permanent
The Puppet master comes by default with a basic WEBrick server. It allow a quick start for those that are not familiar with Puppet, but when the number of Puppet nodes grows, the performances of the default WEBrick server are going down quickly.
The Puppet documentation show how to configure Apache and Passenger to replace the default WEBrick server, but what if you have a lot of nodes ? What if you want to apply your configuration within minutes, instead of the default half-hour threshold before the agent asks the master if something changed ?
Or you may just want a fancy Nginx instead of your plain-old-reliable Apache.
Here is how.
Check your hostname
Your hostname is the base configuration for your node, you should check that it's correct, otherwise you will run into problems after Puppet installation.
# hostname -f
If everything is okay, check your hosts file
# cat /etc/hosts
If your hostname is inside your host file, carry on. Otherwise, set it.
Install Puppet and Puppetmaster
I suppose that you also need the puppet agent installed on the Puppetmaster server.
Install Puppet and Puppetmaster :
# apt-get install puppet puppetmaster
Stop the Puppetmaster :
# service puppetmaster stop
Prevent the puppetmaster from starting. Nginx will spawn on the right port instead of the WEBrick server, previously spawn by Puppetmaster service. Edit the file /etc/defaults/puppetmaster :
# Start puppetmaster on boot? START=no
Configure the Puppet agent : edit the file /etc/puppet/puppet.conf to point your agent on the master (for instance puppetmaster.example.com).
Also, comment the two lines that are "needed for passenger", our configuration don't need them. Actually, if you keep it, it will not work.
[main] logdir=/var/log/puppet vardir=/var/lib/puppet ssldir=/var/lib/puppet/ssl rundir=/var/run/puppet factpath=$vardir/lib/facter prerun_command=/etc/puppet/etckeeper-commit-pre postrun_command=/etc/puppet/etckeeper-commit-post server=puppetmaster.example.com [master] # These are needed when the puppetmaster is run by passenger # and can safely be removed if webrick is used. #ssl_client_header = SSL_CLIENT_S_DN #ssl_client_verify_header = SSL_CLIENT_VERIFY [agent] report = true
Enable your puppet agent :
# puppet agent --enable
Install Nginx and Passenger
We will install the bundle Nginx+Passenger shipped by Phusion repositories.
Add the key to your keyring :
# apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
The Phusion repository uses HTTPS, add HTTPS transport to APT :
# apt-get install apt-transport-https ca-certificates
Finally, install Nginx and Passenger :
# apt-get update # apt-get install nginx-extras passenger
Configure Nginx and Puppetmaster application
Edit /etc/nginx/nginx.conf and uncomment the reference to passenger config :
## # Phusion Passenger config ## # Uncomment it if you installed passenger or passenger-enterprise ## include /etc/nginx/passenger.conf;
Create the file /etc/nginx/nginx/sites-available/puppet.conf with the following content :
server { listen 8140 ssl; server_name puppet puppetmaster puppetmaster.example.com; passenger_enabled on; passenger_app_env production; passenger_set_header X-Client-Verify $ssl_client_verify; passenger_set_header X-Client-DN $ssl_client_s_dn; passenger_set_header X-SSL-Subject $ssl_client_s_dn; passenger_set_header X-SSL-Issuer $ssl_client_i_dn; access_log /var/log/nginx/puppet_access.log; error_log /var/log/nginx/puppet_error.log; root /etc/puppet/rack/public; ssl_certificate /var/lib/puppet/ssl/certs/puppetmaster.example.com.pem; ssl_certificate_key /var/lib/puppet/ssl/private_keys/puppetmaster.example.com.pem; ssl_crl /var/lib/puppet/ssl/ca/ca_crl.pem; ssl_client_certificate /var/lib/puppet/ssl/certs/ca.pem; ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; ssl_prefer_server_ciphers on; ssl_verify_client optional; ssl_verify_depth 1; ssl_session_cache shared:SSL:128m; ssl_session_timeout 5m; }
Remove the default virtual host from Nginx as we don't need it :
# rm /etc/nginx/sites-enabled/default
And enable your newly created server :
# ln -s /etc/nginx/sites-available/puppet.conf /etc/nginx/sites-enabled/puppet.conf
Before restarting Nginx, we will configure the Ruby application for Puppetmaster.
Create the directory /etc/puppet/rack and its subdirectories /etc/puppet/rack/public and /etc/puppet/rack/tmp
# mkdir -p /etc/puppet/rack/public /etc/puppet/rack/tmp
Create the file /etc/puppet/rack/config.ru with the following content :
# 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: # $LOAD_PATH.unshift('/opt/puppet/lib') $0 = "master" # Set the PATH in environment variable ENV['PATH'] = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" # if you want debugging: # ARGV << "--debug" ARGV << "--rack" # Rack applications typically don't start as root. Set --confdir, --vardir, # --logdir, --rundir to prevent reading configuration from # ~/ based pathing. ARGV << "--confdir" << "/etc/puppet" ARGV << "--vardir" << "/var/lib/puppet" ARGV << "--logdir" << "/var/log/puppet" ARGV << "--rundir" << "/var/run/puppet" #ARGV << "--codedir" << "/etc/puppet/code" # always_cache_features is a performance improvement and safe for a master to # apply. This is intended to allow agents to recognize new features that may be # delivered during catalog compilation. ARGV << "--always_cache_features" # NOTE: it's unfortunate that we have to use the "CommandLine" class # here to launch the app, but it contains some initialization logic # (such as triggering the parsing of the config file) that is very # important. We should do something less nasty here when we've # gotten our API and settings initialization logic cleaned up. # # Also note that the "$0 = master" line up near the top here is # the magic that allows the CommandLine class to know that it's # supposed to be running master. # # --cprice 2012-05-22 require 'puppet/util/command_line' # we're usually running inside a Rack::Builder.new {} block, # therefore we need to call run *here*. run Puppet::Util::CommandLine.new.execute
Chown the file for Puppet user :
# chown puppet:puppet /etc/puppet/rack/config.ru
And finally, restart Nginx :
# service nginx restart
Then, test you configuration by running the agent :
# puppet agent --test
Troubleshooting and errors
Error 500
Warning: Error 500 on SERVER: Internal Server Error
Read the logs at /var/log/nginx/error.log and /etc/nginx/puppet_error.log
Error 403
Warning: Error 403 on SERVER: Forbidden request: localhost(127.0.0.1) access to /node/puppetmaster.example.com [find] at :119
Check that your hostname resolves, and that your host file is clean. In particular, you should have the host name of your server on the same line than localhost :
127.0.0.1 localhost puppetmaster puppetmaster.example.com
Also check that your Puppet configuration is correct, in particular check that the two lines "required for Passenger" are commented.
Sources
- [Puppet Doc] Configuring a Puppet Master Server with Passenger and Apache
- [Linode] Ruby on Rails with Nginx on Debian 8
- [Phusion Passenger] Installing Passenger + Nginx
- [Ask Puppet] Puppet Master - Could not retrieve fact fqdn/ipaddress
- Puppet master REST API returns 403 when running under passenger