Using Stored Configuration

Version 1 (Anonymous, 03/13/2010 08:02 pm)

1 1
# Using Stored Configurations
2 1
3 1
Puppet uses a technique called stored configuration, enabled with
4 1
the storeconfigs configuration option, to store data in a database.
5 1
This technique makes use of the Ruby on Rails framework and one of
6 1
three database back-ends: SQLite (the default), MySQL or
7 1
PostgreSQL. Additionally, a message queue can be used to improve a
8 1
puppetmaster's client response time. Currently stored
9 1
configurations are principally used by exported resources.
10 1
11 1
It is important to note that once a node is in the stored
12 1
configuration database it will not be automatically purged - even
13 1
if you remove the corresponding node from your configuration. If
14 1
you wish to purge nodes from your database you will need to do this
15 1
manually. There is a script in the ext directory that purges nodes
16 1
from stored configuration.
17 1
18 1
Contents
19 1
20 1
-   [[Using\_Stored\_Configuration#installing-prerequisites|Using
21 1
    Stored Configuration]]
22 1
    -   [[Using\_Stored\_Configuration#rails|Using Stored
23 1
        Configuration]]
24 1
    -   [[Using\_Stored\_Configuration#mysql|Using Stored
25 1
        Configuration]]
26 1
    -   [[Using\_Stored\_Configuration#sqlite3|Using Stored
27 1
        Configuration]]
28 1
    -   [[Using\_Stored\_Configuration#postgresql|Using Stored
29 1
        Configuration]]
30 1
31 1
-   [[Using\_Stored\_Configuration#configuring-basic-storeconfigs|Using
32 1
    Stored Configuration]]
33 1
-   [[Using\_Stored\_Configuration#configuring-storeconfigs-for-mysql|Using
34 1
    Stored Configuration]]
35 1
-   [[Using\_Stored\_Configuration#configuring-storeconfigs-for-postgresql|Using
36 1
    Stored Configuration]]
37 1
-   [[Using\_Stored\_Configuration#installing-queuing-support-for-storeconfigs|Using
38 1
    Stored Configuration]]
39 1
    -   [[Using\_Stored\_Configuration#installing-stompserver|Using
40 1
        Stored Configuration]]
41 1
    -   [[Using\_Stored\_Configuration#installing-activemq|Using Stored
42 1
        Configuration]]
43 1
44 1
-   [[Using\_Stored\_Configuration#configuring-queuing-storeconfigs|Using
45 1
    Stored Configuration]]
46 1
    -   [[Using\_Stored\_Configuration#configuring-the-queuing-broker|Using
47 1
        Stored Configuration]]
48 1
        -   [[Using\_Stored\_Configuration#configuring-stompserver|Using
49 1
            Stored Configuration]]
50 1
        -   [[Using\_Stored\_Configuration#configuring-activemq|Using
51 1
            Stored Configuration]]
52 1
53 1
    -   [[Using\_Stored\_Configuration#configuring-puppet|Using Stored
54 1
        Configuration]]
55 1
56 1
-   [[Using\_Stored\_Configuration#bootstrapping-into-stored-configuration|Using
57 1
    Stored Configuration]]
58 1
59 1
# Installing Prerequisites
60 1
61 1
To make use of stored configuration you will need to install some
62 1
prerequisites principally the database back-end you wish to use and
63 1
the Rails framework.
64 1
65 1
## Rails
66 1
67 1
**Puppet 0.24.8 and older**
68 1
69 1
Rails version 2.2.2 or earlier.
70 1
71 1
**Puppet 0.25**
72 1
73 1
Rails version 2.2.2 or greater.
74 1
75 1
**Installation**
76 1
77 1
We start by installing the rails Ruby Gem, either with the
78 1
distribution's package management (e.g. Debian/Ubuntu have a
79 1
'rails' package) or as a ruby gem.
80 1
81 1
To ensure a specific version of rails (not the latest available
82 1
from RubyForge) specify the optional '-v' parameter with the
83 1
version number you wish to install:
84 1
85 1
    gem install rails -v 2.2.2
86 1
87 1
## MySQL
88 1
89 1
For MySQL you will need to install a number of packages. For Red
90 1
Hat/Fedora the typical packages required would be:
91 1
92 1
    mysql
93 1
    mysql-devel
94 1
    mysql-server
95 1
96 1
Or for Debian/Ubuntu you would need the following packages.
97 1
libmysql-ruby provides the mysql gem, so installing via gems is
98 1
unneccesary:
99 1
100 1
    mysql-server
101 1
    libmysql-ruby
102 1
103 1
You may also need to install the mysql Ruby Gem (not required on
104 1
Debian/Ubuntu). You may need to specify the --with-mysql-config
105 1
option to tell Gems where to find your MySQL libraries and
106 1
headers:
107 1
108 1
    # gem install mysql -- --with-mysql-config=/usr/bin/mysql_config
109 1
110 1
You may require the ruby-devel package in order to install this
111 1
gem.
112 1
113 1
A word of warning - it is possible to be using stored
114 1
configurations with MySQL without installing the mysql gem. This is
115 1
because rails includes with it a simple Ruby based MySQL connector.
116 1
Relying on this connector is strongly discouraged, as it has been
117 1
observed to leak filehandles, leave open network and database
118 1
connections, and eventually cause puppetmasterd to become
119 1
completely unresponsive.
120 1
121 1
In order to check if you are using the unreliable Ruby based
122 1
connector, examine the rails.log file produced by puppetmasterd. If
123 1
you are using the Ruby one, you will find a message like this:
124 1
125 1
    WARNING: You're using the Ruby-based MySQL library that ships with Rails.
126 1
    This library is not suited for production. Please install the C-based MySQL
127 1
    library instead (gem install mysql).
128 1
129 1
If you find that warning, make sure you install the mysql gem,
130 1
which is based on the native MySQL libraries, before you begin
131 1
using stored configurations in production.
132 1
133 1
## SQLite3
134 1
135 1
For SQLite you will need to install the database package. For Red
136 1
Hat/Fedora the package required would be:
137 1
138 1
    sqlite
139 1
140 1
For Ubuntu/Debian, the packages required are (libsqlite3-ruby
141 1
contains the appropriate gem):
142 1
143 1
    sqlite3
144 1
    libsqlite3-ruby
145 1
146 1
You may also need to install the sqlite3-ruby Ruby Gem (not
147 1
required on Debian/Ubuntu):
148 1
149 1
    # gem install sqlite3-ruby
150 1
151 1
## PostgreSQL
152 1
153 1
For PostgreSQL you will need to install a number of packages. For
154 1
Red Hat/Fedora the typical packages required would be:
155 1
156 1
    postgresql
157 1
    postgresql-server
158 1
    postgresql-devel
159 1
160 1
You will also need to install the postgres Ruby Gem:
161 1
162 1
    # gem install postgres
163 1
164 1
If you fail to install the postgres gem then you will receive the
165 1
following error:
166 1
167 1
    err: Could not retrieve configuration: Uncaught exception no such file to load -- postgres in method puppetmaster.getconfig
168 1
169 1
For PostgreSQL you will also need to create the database and create
170 1
an appropriate role and password.
171 1
172 1
# Configuring basic storeconfigs
173 1
174 1
Now we need to configure stored configuration in Puppet itself.
175 1
There are three types of database adapters available for us, the
176 1
default sqlite3, MySQL and PostgreSQL. For the latter back-end
177 1
databases we also have available a number of options that let us
178 1
specify a particular user, password and the location of a database
179 1
socket. Let's walk through the steps required to configure the most
180 1
basic SQLite backend.
181 1
182 1
-   Configure puppet.conf:
183 1
184 1
        [puppetmasterd]
185 1
        storeconfigs = true
186 1
        dbadapter = sqlite3
187 1
        dblocation = /var/lib/puppet/storeconfigs.sqlite
188 1
189 1
-   "Thin" stored configuration (optional) - from 0.25.0 we can
190 1
    also use the "thin" stored configuration option. This only collects
191 1
    and stores to the database exported resources, tags and host facts.
192 1
    To use "thin" stored configuration configure it in your
193 1
    puppet.conf:
194 1
195 1
        [puppetmasterd]
196 1
        storeconfigs = true
197 1
        thin_storedconfigs = true
198 1
        dbadapter = sqlite3
199 1
        dblocation = /var/lib/puppet/storeconfigs.sqlite
200 1
201 1
-   Start the puppetmasterd daemon
202 1
203 1
-   Start the puppetd client
204 1
205 1
206 1
Now storeconfigs should be enabled and running.
207 1
208 1
Note that if you intend to use PuppetShow, you may need to include
209 1
a dblocation setting under puppetmasterd, pointing to the default
210 1
location. Also note that SQLite is not very happy with high volume
211 1
usage (more than 5 or 10 hosts), and will report locking failures
212 1
during operation.
213 1
214 1
# Configuring storeconfigs for MySQL
215 1
216 1
-   Create a puppet database, and grant privileges. Replace
217 1
    password below with an appropriate password:
218 1
219 1
        # mysql -u root -p
220 1
        mysql> create database puppet;
221 1
        mysql> grant all privileges on puppet.* to puppet@localhost identified by 'password';
222 1
223 1
-   Configure your [puppetmasterd] section to reflect these
224 1
    settings:
225 1
226 1
        [puppetmasterd]
227 1
        storeconfigs = true
228 1
        dbadapter = mysql
229 1
        dbuser = puppet
230 1
        dbpassword = password
231 1
        dbserver = localhost
232 1
        dbsocket = /var/run/mysqld/mysqld.sock
233 1
234 1
-   Start the puppetmasterd daemon
235 1
236 1
-   Start the puppetd client
237 1
238 1
239 1
You can also find some information on
240 1
[[My\_Sql\_Stored\_Configuration\_Patterns|Recipes/MySQLStored
241 1
Configuration]] .
242 1
243 1
To optimize some often run Puppet queries on your MySQL database,
244 1
use the following index:
245 1
246 1
    create index exported_restype_title on resources (exported, restype, title(50));
247 1
248 1
# Configuring storeconfigs for PostgreSQL
249 1
250 1
By default (on RHEL/CentOS, other distros unknown), you will have
251 1
to su - to the postgres user to do any administrative work such as
252 1
database creation.
253 1
254 1
-   Set up the database:
255 1
256 1
        # su - postgres
257 1
        $ psql template1
258 1
        template1=# create database puppet;
259 1
        CREATE DATABASE
260 1
        create user puppet with unencrypted password 'password';
261 1
        CREATE ROLE
262 1
        template1=# grant create on database puppet to puppet;
263 1
264 1
265 1
Note that Puppet requires the CREATE right to do automatic table
266 1
creation to initialize the database.
267 1
268 1
-   Configure your [puppetmasterd] section to reflect these
269 1
    settings:
270 1
271 1
        [puppetmasterd]
272 1
        storeconfigs = true
273 1
        dbadapter = postgresql
274 1
        dbuser = puppet
275 1
        dbpassword = password
276 1
        dbserver = localhost
277 1
        dbname = puppet
278 1
279 1
-   Start the puppetmasterd daemon
280 1
281 1
-   Start the puppetd client
282 1
283 1
-   Check /var/log/messages (or wherever you have Puppet set to
284 1
    log) for the message for an ''Initialized database'' message when
285 1
    the first client checks in.
286 1
287 1
288 1
# Installing Queuing Support for Storeconfigs
289 1
290 1
Puppet queueing is a feature which is designed to take some load
291 1
off of the Puppet master by transferring the task of updating the
292 1
database to a separate program which is named puppetqd (the Puppet
293 1
Queue Daemon).
294 1
295 1
To add support for queuing to an existing storeconfigs
296 1
configuration, you only need to install a queue broker, configure
297 1
your Puppet master, and configure your puppetqd.
298 1
299 1
While many message queue services exist, currently Puppet only
300 1
supports the Stomp protocol. We have tested using StompServer and
301 1
ActiveMQ. While StompServer is easy to set up and configure, we
302 1
suggest you use ActiveMQ -- if you need queueing, you need it
303 1
because of scalability, and StompServer simply isn't built for
304 1
scaling up to enterprise needs.
305 1
306 1
Queuing is available from release 0.25.0 onwards. It is NOT
307 1
available in the 0.24.x releases.
308 1
309 1
## Installing StompServer
310 1
311 1
First make sure you have the Ruby development package. On a Red
312 1
Hat-based system, this would be:
313 1
314 1
    yum install ruby-devel
315 1
316 1
Or on a Debian or Ubuntu-based system:
317 1
318 1
    apt-get install ruby1.8-dev
319 1
320 1
StompServer is available as a gem, so you can install via:
321 1
322 1
    gem install stompserver
323 1
324 1
## Installing ActiveMQ
325 1
326 1
Download and install ActiveMQ: e.g.,:
327 1
328 1
    $ wget http://www.apache.org/dyn/closer.cgi/activemq/apache-activemq/5.2.0/apache-activemq-5.2.0-bin.tar.gz
329 1
    $ tar zxvf apache-activemq-5.2.0-bin.tar.gz
330 1
331 1
# Configuring queuing storeconfigs
332 1
333 1
## Configuring the queuing broker
334 1
335 1
### Configuring StompServer
336 1
337 1
Configuration can either be done on the command line or via a
338 1
config file. For example, the following command-line:
339 1
340 1
    stompserver -q dbm
341 1
342 1
will start the stompserver on the default port of 61613 and use a
343 1
DBM file as its backing store (i.e., while messages have not yet
344 1
been picked up by puppetqd, they will be stored in a DBM file).
345 1
346 1
The configuration file:
347 1
348 1
    $ cat /etc/puppet/puppet-queue.conf
349 1
    :daemon: true
350 1
    :working_dir: /tmp/stompserver
351 1
    :storage: .queue
352 1
    :queue: file
353 1
    :auth: false
354 1
    :debug: false
355 1
    :group:
356 1
    :user:
357 1
    :host: 127.0.0.1
358 1
    :port: 61613
359 1
360 1
configures the stompserver to use a file backing store.
361 1
362 1
Then run the stompserver:
363 1
364 1
    stompserver -C /etc/puppet/puppet-queue.conf
365 1
366 1
Consult the stompserver's README.txt for additional information on
367 1
installation and configuration.
368 1
369 1
### Configuring ActiveMQ
370 1
371 1
Create an activemq.xml file (based on the samples provided in the
372 1
source), and enable stomp. The sample configuration uses the
373 1
default backing store, AMQ, (which is a transactional journal in
374 1
ActiveMQ 5) and only requires the one-line change below to enable
375 1
stomp on port 61613:
376 1
377 1
    <transportConnectors> <transportConnector name="stomp" uri="stomp://localhost:61613"/> </transportConnectors>
378 1
379 1
You can then start ActiveMQ:
380 1
381 1
    activemq
382 1
383 1
You should consult the ActiveMQ documentation for additional
384 1
information on configuring ActiveMQ.
385 1
386 1
## Configuring Puppet
387 1
388 1
You need to configure both puppetmasterd and puppetqd to use
389 1
queuing.
390 1
391 1
In this example, we're keeping our stored configuration information
392 1
in sqlite3 -- if you're using PostgreSQL, MySQL, or others, your
393 1
dbadapter and dblocation information will differ).
394 1
395 1
Please refer to the basic stored configuration section on the wiki
396 1
for details about creating the database for MySQL or PostgreSQL.
397 1
398 1
First we need to install the Stomp client. You can do this from a
399 1
gem:
400 1
401 1
    gem install stomp
402 1
403 1
Next, we need to configure Puppet itself. Note that the
404 1
configuration of the Puppet master and the puppetqd is the same:
405 1
this is because they both need to read information out of the same
406 1
database (i.e., the database is a cache). Thus, a puppet.conf would
407 1
contain:
408 1
409 1
    [main]
410 1
      queue_type = stomp
411 1
      queue_source = stomp://localhost:61613
412 1
      dbadapter = sqlite3
413 1
      dblocation = /var/lib/puppet/storeconfigs.sqlite
414 1
    [puppetmasterd]
415 1
      async_storeconfigs = true
416 1
417 1
Note that these can all be put onto a command line:
418 1
419 1
    puppetmasterd --async_storeconfigs --queue_type=stomp --queue_source="stomp://localhost:61613" \
420 1
      --dbadapter sqlite3 --dblocation /var/lib/puppet/storeconfigs.sqlite
421 1
422 1
Also note that the dblocation is not needed for MySQL or PostgreSQL
423 1
dbadapters.
424 1
425 1
You then need to run the puppetqd daemon.
426 1
427 1
> puppetqd
428 1
429 1
# Bootstrapping into stored configuration
430 1
431 1
If you have a lot of hosts, turning on stored configuration might
432 1
crush your database server. The main problem is that data for every
433 1
host needs to be INSERTed into the database. Once you get past that
434 1
hurdle there's much less SQL activity. Here are some notes about
435 1
how we (usg.edu folks) got over the hurdle. The main bottleneck for
436 1
us was CPU--IO wait wasn't an issue.
437 1
438 1
First we tuned our MySQL server (all based on masterzen's
439 1
recommendations). We added these lines to the [mysqld] section of
440 1
my.cnf:
441 1
442 1
    innodb_buffer_pool_size=2G
443 1
    innodb_log_file_size=256M
444 1
    innodb_log_buffer_size=64M
445 1
    innodb_additional_mem_pool_size=20M
446 1
    innodb_flush_method = O_DIRECT
447 1
448 1
Next we stopped puppetd on half of our \~400 servers. This, plus
449 1
the MySQL changes above, allowed our server to survive the initial
450 1
stored configuration hit of our other 200 servers. After the first
451 1
200 were in stored configuration we ran puppetd --test --tags
452 1
SMALLMODULE on the second half of our hosts. Later we restarted
453 1
puppetd.
454 1
455 1
Our clients check in once an hour. About 15 hosts check in per
456 1
minute. The puppetmasterd and mysqld run on the same server (along
457 1
with a few other applications). Our server has 8 CPUs and 12G of
458 1
RAM.
459 1
460 1
Here's a fine blog post by masterzen about this issue:
461 1
[http://www.masterzen.fr/2009/03/18/omg-storedconfigs-killed-my-database/](http://www.masterzen.fr/2009/03/18/omg-storedconfigs-killed-my-database/)