Ultimate puppet walkthrough guide! (in German)
AGPL-3.0 License
puppet
in Ruby geschrieben ist)
Nheres dazu unter puppetlabs_spec_helper.
Unit Tests
sind Tests, welche einzelne Funktionen / minimale Codeblcke testenrspec-puppet
validiert, ob bestimmte Puppet Resourcen so im Katalog sind, wie man sie erwartet
Minimales Beispiel
# import a helper
require 'spec_helper'
# class we want to test
describe 'borg' do
# mock an FQDN
let :node do
'rspec.puppet.com'
end
let :facts do
{
"operatingsystem": "CentOS",
"operatingsystemmajversion": 7
}
end
# mock class params if required
# bad practice, a module should work with default data
let :params do
{
backupserver: 'localhost'
}
end
context 'with all defaults' do
it { is_expected.to compile.with_all_deps }
end
end
Prfen der einzelnen Resources:
require 'spec_helper'
describe 'borg' do
let :node do
'rspec.puppet.com'
end
on_supported_os.each do |os, facts|
context "on #{os} " do
let :facts do
facts
end
let :params do
{
backupserver: 'localhost'
}
end
context 'with all defaults' do
it { is_expected.to compile.with_all_deps }
it { is_expected.to contain_file('/etc/backup-sh-conf.sh') }
it { is_expected.to contain_file('/etc/borg') }
it { is_expected.to contain_file('/etc/profile.d/borg.sh') }
it { is_expected.to contain_file('/usr/local/bin/borg-backup') }
it { is_expected.to contain_file('/usr/local/bin/borg_exporter') }
it { is_expected.to contain_file('/etc/borg-restore.cfg') }
it { is_expected.to contain_class('borg::install') }
it { is_expected.to contain_class('borg::config') }
it { is_expected.to contain_class('borg::service') }
it { is_expected.to contain_ssh__client__config__user('root') }
it { is_expected.to contain_borg__ssh_keygen('root_borg') }
it { is_expected.to contain_exec('ssh_keygen-root_borg') }
end
case facts[:os]['name']
when 'Archlinux'
context 'on Archlinux' do
it { is_expected.to contain_package('borg') }
it { is_expected.to contain_package('perl-app-borgrestore') }
end
when 'Ubuntu'
context 'on Ubuntu' do
it { is_expected.to contain_package('borgbackup') }
it { is_expected.to contain_package('borgbackup-doc') }
it { is_expected.to contain_package('gcc') }
it { is_expected.to contain_package('make') }
it { is_expected.to contain_package('cpanminus') }
it { is_expected.to contain_package('libdbd-sqlite3-perl') }
if facts[:os]['release']['major'] == '16.04'
it { is_expected.to contain_apt__ppa('ppa:costamagnagianfranco/borgbackup') }
end
end
when 'RedHat', 'CentOS'
context 'on osfamily Redhat' do
it { is_expected.to contain_package('perl-local-lib') }
it { is_expected.to contain_package('perl-Test-Simple') }
it { is_expected.to contain_package('perl-App-cpanminus') }
it { is_expected.to contain_package('gcc') }
it { is_expected.to contain_exec('install_borg_restore') }
it { is_expected.to contain_file('/opt/BorgRestore') }
it { is_expected.to contain_file('/usr/local/bin/borg-restore.pl') }
end
when 'Gentoo'
context 'on osfamily Gentoo' do
it { is_expected.to contain_package('App-cpanminus') }
end
when 'Fedora'
context 'on osfamily Fedora' do
it { is_expected.to contain_package('perl-Path-Tiny') }
it { is_expected.to contain_package('perl-Test-MockObject') }
it { is_expected.to contain_package('perl-Test') }
it { is_expected.to contain_package('perl-autodie') }
end
end
end
end
end
Quelle ist das puppet-borg modul
$facts
HashCentOS
vs centos
) in allen Modulen seinrspec-puppet-facts macht genau das!
require 'spec_helper'
describe 'borg' do
let :node do
'rspec.puppet.com'
end
on_supported_os.each do |os, facts|
context "on #{os} " do
let :facts do
facts
end
let :params do
{
backupserver: 'localhost'
}
end
context 'with all defaults' do
it { is_expected.to compile.with_all_deps }
end
end
end
end
Es ist wichtig das alle Betriebssysteme, auf denen ein Modul genutzt wird, auch in der metadata.json stehen!
Fr alle genutzten Betriebssysteme sollten in dem Projekt factsets sein!
require 'spec_helper_acceptance'
describe 'zabbix::server class' do
context 'default parameters' do
# Using puppet_apply as a helper
it 'works idempotently with no errors' do
# this will actually deploy apache + postgres + zabbix-server + zabbix-web
pp = <<-EOS
class { 'postgresql::server': } ->
class { 'zabbix::database': } ->
class { 'zabbix::server': }
EOS
shell('yum clean metadata') if fact('os.family') == 'RedHat'
# Run it twice and test for idempotency
apply_manifest(pp, catch_failures: true)
apply_manifest(pp, catch_changes: true)
end
# do some basic checks
describe package('zabbix-server-pgsql') do
it { is_expected.to be_installed }
end
describe service('zabbix-server') do
it { is_expected.to be_running }
it { is_expected.to be_enabled }
end
end
end
Quelle der Tests ist das voxpupuli/zabbix Modul.
Langfristig wird OnyxPoint die Entwicklung von beaker bernehmen
Puppet Inc. arbeitet an Litmus, einer Ruby Bibliothek um VMs/Container zu starten
Liste der aktuell empfohlenen plugins:
Gemfile:
gem 'puppet-lint-leading_zero-check', :require => false
gem 'puppet-lint-trailing_comma-check', :require => false
gem 'puppet-lint-version_comparison-check', :require => false
gem 'puppet-lint-classes_and_types_beginning_with_digits-check', :require => false
gem 'puppet-lint-unquoted_string-check', :require => false
gem 'puppet-lint-variable_contains_upcase', :require => false
gem 'puppet-lint-absolute_classname-check', '>= 2.0.0', :require => false
gem 'puppet-lint-topscope-variable-check', :require => false
gem 'puppet-lint-legacy_facts-check', :require => false
gem 'puppet-lint-anchor-check', :require => false
man kann in der Puppet DSL gezielt einzelne Linter deaktivieren, sofern sie ein False/Positive liefern:
# lint:ignore:case_without_default
Fr Fehlermeldungen in einem sinnvollen Format kann man folgendes in seinem Rakefile
eintragen:
PuppetLint.configuration.log_format = '%{path}:%{line}:%{check}:%{KIND}:%{message}'
Fr neue Komponentenmodule sollte man auch puppet-lint-param-docs nutzen. Dies erzwingt Dokumentation fr jeden Parameter.
Ausgabe mit Fehler:
$ bundle exec rake lint
manifests/init.pp:106:arrow_on_right_operand_line:WARNING:arrow should be on the right operand's line
Ausgabe mit Autokorrektur:
$ bundle exec rake lint:auto_correct
manifests/init.pp:106:arrow_on_right_operand_line:FIXED:arrow should be on the right operand's line
puppet parser
puppet
Beispielhafte Ausgabe vom Rake Task wenn es keine Fehler gibt:
$ bundle exec rake syntax
---> syntax:manifests
---> syntax:templates
---> syntax:hiera:yaml
Ausgabe mit Syntaxfehlern:
$ bundle exec rake syntax
---> syntax:manifests
rake aborted!
Could not parse for environment production: Syntax error at end of file at demo.pp:2
Tasks: TOP => syntax => syntax:manifests
(See full trace by running task with --trace)
Ausgabe mit Fehlern:
$ bundle exec rake rubocop
Running RuboCop...
Inspecting 4 files
..C.
Offenses:
spec/spec_helper.rb:8:1: C: Layout/EmptyLines: Extra blank line detected. (https://github.com/bbatsov/ruby-style-guide#two-or-more-empty-lines)
4 files inspected, 1 offense detected
RuboCop failed!
Mit Autokorrektur:
bundle exec rake rubocop:auto_correct
Running RuboCop...
Inspecting 4 files
Parser::Source::Rewriter is deprecated.
Please update your code to use Parser::Source::TreeRewriter instead
..C.
Offenses:
spec/spec_helper.rb:8:1: C: [Corrected] Layout/EmptyLines: Extra blank line detected. (https://github.com/bbatsov/ruby-style-guide#two-or-more-empty-lines)
4 files inspected, 1 offense detected, 1 offense corrected
puppetlabs_spec_helper
einbindenGemfile:
source ENV['GEM_SOURCE'] || "https://rubygems.org"
gem 'puppetlabs_spec_helper'
Rakefile:
require 'puppetlabs_spec_helper/rake_tasks'
Alle Rake Tasks ausgeben:
bundle exec rake -T
rake beaker # Run beaker acceptance tests
rake beaker:sets # List available beaker nodesets
rake beaker:ssh[set,node] # Try to use vagrant to login to the Beaker node
rake build # Build puppet module package
rake build:pdk # Build Puppet module with PDK
rake build:pmt # Build Puppet module package with PMT (Puppet < 6.0.0 only)
rake check:dot_underscore # Fails if any ._ files are present in directory
rake check:git_ignore # Fails if directories contain the files specified in .gitignore
rake check:symlinks # Fails if symlinks are present in directory
rake check:test_file # Fails if .pp files present in tests folder
rake clean # Clean a built module package
rake compute_dev_version # Print development version of module
rake help # Display the list of available rake tasks
rake lint # Run puppet-lint
rake lint_fix # Run puppet-lint
rake parallel_spec # Run spec tests in parallel and clean the fixtures directory if successful
rake parallel_spec_standalone # Parallel spec tests
rake release_checks # Runs all necessary checks on a module in preparation for a release
rake rubocop # rubocop is not available in this installation
rake spec # Run spec tests and clean the fixtures directory if successful
rake spec:simplecov # Run spec tests with ruby simplecov code coverage
rake spec_clean # Clean up the fixtures directory
rake spec_clean_symlinks # Clean up any fixture symlinks
rake spec_list_json # List spec tests in a JSON document
rake spec_prep # Create the fixtures directory
rake spec_standalone # Run RSpec code examples
rake syntax # Syntax check Puppet manifests and templates
rake syntax:hiera # Syntax check Hiera config files
rake syntax:manifests # Syntax check Puppet manifests
rake syntax:templates # Syntax check Puppet templates
rake validate # Check syntax of Ruby files and call :syntax and :metadata_lint
Anforderungen:
Dies lsst sich mit dem Roles and Profiles Pattern lsen
lookup()
Aufrufe oder Automatic Class Parameter Lookup Pattern
(Copyright Craig Dunn)
include modul
funktioniert und installiert mir eine Komponente mit sinnvollen und sicheren Standardwertenpuppet-strings
dokumentiertEs kommt vor, dass man ein ffentliches Modul patchen muss. Man muss versuchen diese Patches Upstream gemerged zu bekommen. Andernfalls difft der Fork immer mehr von Upstream ab und man landet in der Abhngigkeitshlle. Bei Modulen von Vox Pupuli / Puppet wird tendenziell schneller reagiert als bei Modulen mit einzelnen Maintainern. Puppet hat viele Mitarbeiter mit Commit Rechten fr Ihre Module, Vox Pupuli hat > 140 (unregelmige) Maintainer. Auerdem gibt es hier Esakalationsmglichkeiten.
puppet module list --environment production --tree
/var/log/puppetlabs/puppetserver/puppetserver.log
nach Warnungen / Fehlern schauenSSH Multiplexing aktivieren um git clone
s zu beschleunigen:
class profiles::ssh2git {
# /root/.ssh/config entry to access git.internal
ssh::client::config::user { 'gitaccess':
ensure => present,
user => 'root',
user_home_dir => '/root',
options => {
'Host git.internal' => {
'User' => 'git',
'IdentityFile' => '~/.ssh/id_ed25519...',
'ControlMaster' => 'auto',
'ControlPath' => '~/.ssh/ssh-%r@%h:%p',
'ControlPersist' => '10m'
},
},
}
sshkey { 'git.internal':
ensure => 'present',
target => '/root/.ssh/known_hosts',
type => 'ecdsa-sha2-nistp256',
key => 'DATA',
}
}
r10k mit mehreren Workern starten:
# puppet/r10k from Vox Pupuli
class { 'r10k':
version => '3.5.0',
pool_size => 10,
}
Es gibt viele Mglichkeiten Puppet Module zu speichern.
Folgende Projekte untersttzen Puppet Modul Releases(.tar.gz Archive):
Alternativ kann man mit git tags / commit ids im Puppetfile arbeiten.
Mit Puppet eine groe Menge an Scripten als File Resources verteilen ist ein Antipattern. Diese sollte man als Artefakte Paketieren. Puppet richtet dann das Repository auf den Zielsystemen ein. Dies gillt fr alle Artefakte, welche Puppet deployen soll.
Bei vielen Projekten bietet sich ein gitflow-workflow an:
Dies funktioniert sehr gut fr intern entwickelte Anwendungen die auf anderen internen Tools aufsetzen und wiederum von anderen Teams genutzt werden. Fr jede Umgebung bentigt man eigene Repositories und Maschinen/Server/Docker Images. Puppet kann solche Umgebungen deployen. Puppet Code selbst mit so einem Workflow zu verwalten funktioniert in der Regel nicht / bringt viel zu viel Overhead mit sich.
Fr Puppet hat sich in den meisten Organisationen ein Git Feature Branch Workflow als beste Lsung etabliert.
production
. Dieser wird als Environment auf normalen Nodes genutztDedizierter Vortrag ber Puppetserver Skalierung
Hiera Tuningoptionen fr puppetlabs/puppetdb:
---
puppetdb::server::java_args:
'-Xmx': '8192m'
'-Xms': '2048m'
puppetdb::server::node_ttl: '14d',
puppetdb::server::node_purge_ttl: '14d',
puppetdb::server::report_ttl: '999d'
# default is 50
puppetdb::server::max_threads: 100
# default is processorcount / 2
puppetdb::server::command_threads: %{facts.processors.count}
# default is 4, have your database in mind
puppetdb::server::concurrent_writes: 8
puppetdb::server::automatic_dlo_cleanup: true
Optionen fr puppetlabs/postgresql:
Anzahl der Verbindungen erhhen:
postgresql::server::config_entry{'max_connections':
value => 400,
}
Laufenden PostgreSQL Server analysieren und eine optimierte Konfiguration generieren:
pgtune -i /var/lib/pgsql/10/data/postgresql.conf -o postgresql.conf
Fr PostgreSQL empfiehlt sich deren eigenes Yum Repository. Die Upstream Pakete erlauben es beliebige Versionen parallel zu installieren. Auerdem bekommt das Yum Repository am schnellsten Sicherheitsupdates. PostgreSQL hat in jeder neuen Version viele Geschwindigkeitsoptimierungen. Es sollte immer geprft werden mit welcher neusten PostgreSQL Version PuppetDB funktioniert und diese dann genutzt werden. PuppetDB 6 und 7 in Puppet Enterprise nutzen PostgreSQL 11. Nutzer von PuppetDB 7 haben auch berichtet, dass sie erfolgreich PostgreSQL 13 einsetzen.
Neben dem autovacuum, welches als gelscht markierte Tuples entfernt, bietet
sich auch die Nutzung von pg_repack an.
Fr Puppet Enterprise wird dies mit dem
pe_databases Modul
konfiguriert. pg_repack
kann Tabellen und Indexe aufrumen sowie die
PostgreSQL Daten im Dateisystem neu ordnen. Somit bentigen Queries weniger IO.
Hier die 3 Timer + Services aus einer PE Umgebung extrahiert.
# /etc/systemd/system/pe_databases-catalogs.service
[Unit]
Description=Service to repack PE database tables
Wants=pe_databases-catalogs.timer
[Service]
User=pe-postgres
Group=pe-postgres
Type=oneshot
ExecStart=/opt/puppetlabs/server/apps/postgresql/11/bin/pg_repack -d pe-puppetdb --jobs 3 -t catalogs -t catalog_resources -t catalog_inputs -t edges -t certnames
[Install]
WantedBy=multi-user.target
# /etc/systemd/system/pe_databases-catalogs.timer
[Unit]
Description=Timer to trigger repacking PE database tables
[Timer]
OnCalendar=Sun,Thu *-*-* 04:30:00
Persistent=true
[Install]
WantedBy=timers.target
# /etc/systemd/system/pe_databases-facts.service
[Unit]
Description=Service to repack PE database tables
Wants=pe_databases-facts.timer
[Service]
User=pe-postgres
Group=pe-postgres
Type=oneshot
ExecStart=/opt/puppetlabs/server/apps/postgresql/11/bin/pg_repack -d pe-puppetdb --jobs 3 -t factsets -t fact_paths
[Install]
WantedBy=multi-user.target
# /etc/systemd/system/pe_databases-facts.timer
[Unit]
Description=Timer to trigger repacking PE database tables
[Timer]
OnCalendar=Tue,Sat *-*-* 04:30:00
Persistent=true
[Install]
WantedBy=timers.target
# /etc/systemd/system/pe_databases-other.service
[Unit]
Description=Service to repack PE database tables
Wants=pe_databases-other.timer
[Service]
User=pe-postgres
Group=pe-postgres
Type=oneshot
ExecStart=/opt/puppetlabs/server/apps/postgresql/11/bin/pg_repack -d pe-puppetdb --jobs 3 -t producers -t resource_params -t resource_params_cache
[Install]
WantedBy=multi-user.target
# /etc/systemd/system/pe_databases-other.timer
[Unit]
Description=Timer to trigger repacking PE database tables
[Timer]
OnCalendar=*-*-20 05:30:00
Persistent=true
[Install]
WantedBy=timers.target
Hiera Optionen fr theforeman/foreman:
---
# default is 5
foreman::db_pool: 20
foreman::keepalive: true
foreman::max_keepalive_requests: 1000
foreman::keepalive_timeout: 180
Foreman luft via Passenger. Dieser wird mit puppetlabs/apache aufgesetzt. Multithreading hochdrehen:
---
apache::mod::passenger::passenger_max_pool_size: %{facts.processors.count}
apache::mod::passenger::passenger_min_instances: %{facts.processors.count}
Foreman kann memcached als Cache nutzen:
Via Puppet installieren:
# https://forge.puppet.com/saz/memcached
include memcached
include foreman::plugin::memcache
Via Hiera einstellen:
---
# 50GB of cache
memcached::max_memory: 51200
foreman::plugin::memcache::hosts:
- 127.0.0.1
Puppetlabs bietet im Modul puppetlabs/puppet_metrics_dashboard einen Monitoring Stack fr Puppetserver. Dieser bietet JVM Metriken via JMX und Puppetserver Metriken via Graphite.
file
Reports sind unntig und bentigen oft IO/s und Inodes (grep ^reports /etc/puppetlabs/puppet/puppet.conf
)file
Ressource mit einer Puppetserver URL (puppet:///
) kann zu einem eigenen HTTP Request vom Agent zum Puppetserver fhren
source => puppet:///modules/...
durch content => file(${module_name}/)
ersetzenHiera Optionen fr theforeman/puppet:
$cpu_count_twice = $facts['processors']['count'] * 2
$cpu_count = $facts['processors']['count'] * 1
class{'puppet':
server_jvm_min_heap_size => "${cpu_count}G",
server_jvm_max_heap_size => "${cpu_count_twice}G",
server_max_requests_per_instance => 500000,
server_max_queued_requests => $cpu_count,
server_environment_class_cache_enabled => true,
server_jvm_extra_args => ['-XX:ReservedCodeCacheSize=2G'],
}
Folgende Puppet Komponenten sind untereinander Kompatibel
Puppet Agent | Puppetserver | PuppetDB |
---|---|---|
6.x | 6.x | 6.x |
5.x | 6.x | 6.x |
4.x | 6.x | 6.x |
7.0.0 | 6.14.1 | 6.13.1 |
7.0.0 | 6.14.1 | 7.0.0 |
6.19.1 | 6.14.1 | 7.0.0 |
Es empfiehlt sich folgender Upgrade Pfad:
Liste an bekannten Bugs, welche groe Auswirkungen haben knnten bei einem Upgrade (Stand 2020-11-24):
Seit Q2 2021 sind keine offenen Bugs bekannt die ein Upgrade von Puppet 6 zu Puppet 7 behindern
Auf sehr vielen System wird das Puppet Agent Zertifikat fr einen lokalen Webserver zweckentfremdet. Oft ebenfalls mit Klientzertifikatsvalidierung. Dies funktioniert nur sinnvoll mit einer aktuellen CRL (Certificate Revocation List
Es gibt viele Mythen ber die korrekten Optionen fr die JVM. Die Kurzfassung:
-XX:ReservedCodeCacheSize=2G
sollte immer der Puppetserver JVM mitgegeben
werden. Details dazu gibt es unter PUP-10225
sowie SERVER-2771. Dies
behebt 99% der Performanceprobleme die Leute nach dem Upgrade von Puppetserver
5 haben. Langfristig soll die Option standardmig im Puppetserver gesetzt
sein. Puppet Inc ist leider etwas trge was das updaten der Doku/Pakete angeht.
Nhere Informationen zu der Option gibt es in der
offiziellen Java Dokumentation.
Auerdem hat Baeldung dazu noch einen Artikel
Der Blog ist eine sehr gute Anlaufstelle fr Artikel ber Java, JVM und Spring.
Der Default Wert betrgt, je nach Java Version, 48MB. Dies ist fr Java Applikationen oftmals vollkommen ausreichend. Fr Jruby wird allerdings wesentlich mehr bentigt.
Um die Ramnutzung etwas transparenter zu gestalten kann man die JVM Option
-XX:+PrintCodeCache
setzen. Damit loggt diese die Nutzung/Auslastung des
Code Caches.
Puppetserver und PuppetDB werden innerhalb der JVM ausgefhrt. Diese fhrt
regelmig eine Garbage Collection durch. Hierbei werden nicht mehr bentigte
Objekte aus dem Arbeitspeicher entfernt. Je mehr Aktivit innerhalb der JVM
existiert und je nher der genutzte Ram an der Heap Grenze ist, desto
agressiver und fter arbeitet der Garbage Collector. In der Regel luft dieser
periodisch zum Puppetserver/PuppetDB. Sollte er Ram nicht freigeben knnen kann
es vorkommen, dass er die Applikation kurzzeitiig pausiert. All diese
Informationen kann die JVM in eine Logdatei schreiben. Dies ist ntzlich um
die Arbeitspeichernutzung zu prfen und ggf den Heap zu vergrern/verringern.
Aktiviert wird es mit folgender Option:
-Xlog:gc*:file=/gc.log::filecount=16,filesize=20m
Dies aktiviert das Logging in die Datei gc.log. Sobald die Datei 20MB Gre
erreicht wird die rotiert. Es werden 16 Datein vorgehalten. Fr Puppetserver
empfiehlt sich der Pfad /var/log/puppetlabs/puppetserver/puppetserver_gc.log
,
fr PuppetDB /var/log/puppetlabs/puppetdb/puppetdb_gc.log
.
Es gibt verschiedene Tools, welche die Logs auswerten knnen. Eine simple Version ist der Upload auf https://gceasy.io/.
Sobald die JVM versucht mehr Arbeitsspeicher zu nutzen als verfgbar/Heap
erlaubt, luft die JVM in einen Out of Memory Fehler und wird beendet. Sofern
dies passiert kann die JVM ein Abbild des Heaps auf das Dateisystem schreiben.
Out of Memory Fehler werden provoziert wenn Heap massiv zu klein konfiguriert
ist oder ein Puppet Modul irgendeine Funktion bereitstellt die Memory Leaks
verursacht. Wenn max_requests_per_instance
im Puppetserver gesetzt ist werden
Memory Leaks eventuell verschleiert weil die einzelnen JVM Instanzen regelmig
neugestartet werden. Die erzeugten Abbilder knnen mit verschiedenen Tools
analysiert und visualisiert werden.
Damit mindestens Webbrowser TLS Zertifikate als valide empfinden muss ein FQDN
als Subject Alternative Name im Zertifikat gesetzt werden. Chrome erfordert
dies seit Version 58.
Puppet setzt bis Puppetserver 6.15.3 ausschlielich den alten Common Name. Als
Workaround kann man den initialen Puppet run starten mit:
puppet agent -t --dns_alt_names=$(hostname -f)
. Sofern ein Server mehrere FQDNs
hat die auf ihn zeigen kann man der Option auch eine Kommaseparierte Liste
mitgeben. Seit Puppetserver 6.15.3 bzw. 7.1.0
setzt die Puppetserver CA den Common Name ebenfalls als Subject Alternative
Name.
Je nach Version vom Puppetserver und PuppetDB werden diese mit Java 8 ausgefhrt. Diese Version ist sehr sehr alte. Puppetserver 6 und PuppetDB 6 untersttzen diese auch Java 11. Dies sollte unbedingt genutzt werden. Es empfiehlt sich regelmig die Release Notes zu prfen. Sobald eine neuere Java Version untersttzt wird sollte auf diese gewechselt werden. Beide Dienste funktionieren sehr gut mit OpenJDK/AdoptJDK. Es wird kein Java von Oracle bentigt.
$trusted['certname']
und nicht $facts['networking']['fqdn']
nutzenOftmals wird innerhalb der Puppet DSL der FQDN vom Agent bentigt. Hierzu gibt es viele Optionen. Veraltet sind:
$fqdn
$::fqdn
$facts['fqdn']
Diese drei optionen sind veraltet. Alternativ soll $facts['networking']['fqdn']
genutzt werden. Dies liefert den FQDN zurck. Dieser kann aber auf dem Quellsystem
sehr einfach gendert und manipuliert werden. In den meisten Fllen ist
$trusted['certname']
die bessere Option. Dies ist der Common Name aus dem
Zertifikat des Agents. In der Regel entspricht dies dem FQDN des Agents
whrend des ersten Puppet runs.
Oft hat man Innerhalb einer Firma ein zentrales Inventarsystem. Leider meistens
sogar mehrere. Oft enthalten diese Informationen die man auch innerhalb einer
Puppet Umgebung nutzen mchte. Oft werden z.b. die Teamzugehrigkeit oder
offene Problemtickets in der motd eines Servers verlinkt. Mit der
trusted_external_command
Option kann man auf dem Puppetserver ein Script hinterlegen. Diesem wird als
erster Parameter der Common Name des anfragenden Agents bergeben. Das Script
kann sich dann zu externen Systemen verbinden und dort die Informationen
ermitteln. Puppet erwartet als Antwort einen JSON Hash. Dieser wird
in den Hash $trusted['externa']
eingefgt und ist innerhalb des Puppet Codes
verfgbar. Puppet Code kann $trusted
nicht berschreiben, nur lesen.
Ein gutes Beispiel hierfr ist das servicenow Modul von Puppet Inc. ServiceNow
ist ein cloudbasiertes Inventarsystem. Das Script fr den
trusted_external_command
gibt es
hier.
Achtung: Die Lizenz erlaubt nur eine Nutzung mit Puppet Enterprise.
Jeder Prozess darf unter Linux eine bestimmte Anzahl offener Dateideskriptoren
haben. Dies sind zum groen Teil geffnete Datein und TCP Sockets. Das Limit
lsst sich mit ulimit -Sn
auslesen und betrgt auf den meisten Systemen 1024
fr normale Benutzer (Soft Limit). Diese knnen es manuell auf den Wert von
ulimit -Hn
erhhen (Hard Limit). Ein Puppetserver mit vielen JVM Instanzen,
der eventuell mit mehreren externen Diensten (Report Prozessor,
trusted_external_command...) kommuniziert, bentigt oftmals mehr offene
Dateideskriptoren. Die aktuell offenne Dateideskriptoren lassen sich wie folgt
ermitteln:
find /proc/$(pgrep -f puppetserver)/fd | wc -l
Mit dem puppetserver Puppet Modul lsst sich das limit erhhen:
puppet::server_max_open_files: 16384
Es gibt noch ein globales Limit welches der Linux Kernel vorgibt. Dies erhlt
man mit sysctl fs.file-max
. Es kann ebenfalls ber Puppet erhht werden:
sysctl { 'fs.file-max':
ensure => 'present',
value => '9923372036854775807',
target => '/etc/sysctl.d/99-puppet.conf',
Sofern dies ntig ist deuted es immer auf ein Problem auf dem Server hin! Weitere Informationen findet man in der Linux Kernel Dokumentation.
digest_algorithm bestimmt das Hashverfahren mit dem Datein vergleichen werden. Puppetserver erzeugt Prfsummen fr Datein auf dem Puppetserver. Der Agent fhrt das gleiche lokal durch und genderte Datein zu erkennen. Bis einschlielich Puppet 6 wird hier das veraltete md5 genutzt. Seit Puppet 7 ist der Standardwert sha256. ltere Puppet 4/5/6 Umgebungen sollten ebenfalls auf sha256 gendert werden. Sofern bentigt, kann man dies auch auf sha512 ndern. Dies ist eventuell fr einige Zertifizierungen/Audits notwendig. Die Option wird in der puppet.conf gesetzt.
Standardmig nutzt Puppet Agent veraltete Zertifikate mit dem RSA Verfahren.
Seit Puppet 6.5.0
kann man aber aber Zertifikate auf Basis von Elliptischen Kurven nutzen. Dafr
muss in der puppet.conf vor dem ersten Puppet Run (Bevor ein Zertifikat
vorhanden ist) die Option key_type
auf ec
gesetzt werden. Zertifikate auf
Basis Elliptischer Kurven gelten als Zukunftssicher und bentigen weniger
Speicherplatz.
Der Puppet agent wendet bei jedem Lauf einen Katalog an, den zuvor der Puppetserver kompiliert hat. Dieser besteht aus einem gerichteten Graphen. Alle Ressources die angewendet werden sollen werden untereinander auf implizite und explizite Abhngigkeiten geprft und in eine Reihenfolge gebracht. Manchmal gibt es Probleme den Katalog auf einem Node anzuwenden. Dazu kann der Agent den Graph lokal speichern in verschiedenen Formaten. Die Option ist standardmig deaktiviert, sollte aber aktiviert sein um auch einmalig aufgetretene Fehler im nachhinein noch zu analysieren.
Directed acyclic Graph bei Wikipedia
Wenn Puppet eine Datei ndern, sei es mit der Concat Resource oder weil die
ganze Datei vom Puppetserver kommt oder aus einem Template generiert wird, kann
Puppet einen diff anzeigen, wenn show_diff=true gesetzt ist. In dem Fall wird
der diff aber auch im Report gespeichert und damit zum Puppetserver
zurckgeschickt. Wenn man Reports verarbeitet, z.b. mit Foreman, kann man sich
hier die diffs anzeigen lassen. ist show_diff nicht gesetzt oder false
kann
man im Report nur erkennen das eine Datei gendert wurde, aber nicht wie. Es
empfiehlt sich daher die Option zu aktivieren. Reports sollten dann allerdings
nicht unverschlsselt bertragen werden da diffs potentiell sensitive
Informationen enthalten knnen.
In einer Agent/Server Umgebung werden Facts auf dem Agent ermittelt und zum Server geschickt. Im Gegenzug bekommt der Agent den kompilierten Katalog zurck und wendet ihn an. Am Ende wird ein Report zum Server geschickt. Es ist mglich, dass der Katalog Einfluss auf Werte irgendwelcher Facts hat (z.B. die Anzahl offener Updates wenn der Katalog Updates bestimmter Pakete erzwingt). Somit sind Facts in der PuppetDB eventuell nicht aktuell nachdem ein Katalog angewand wurde. Sofern man viel mit PuppetDB Queries innerhalb der Puppet Codebasis agiert und Facts anderer Node ausliest, oder sich viele Reports mit eigenen PuppetDB Queries erzeugt ist es sinnvoll dem Agent mitzuteilen, dass er Facts nach dem anwenden des Katalogs nochmal zum Server schicken soll. Dies kann man mit der Option resubmit_facts aktivieren. Somit verdoppelt sich allerdings die Last durch Facts auf der Puppetdb.
Damit wird am Ende eines Agent runs eine Zusammenfassung ausgegeben
Application:
Initial environment: function
Converged environment: function
Run mode: user
Changes:
Total: 1
Events:
Success: 1
Total: 1
Resources:
Changed: 1
Out of sync: 1
Total: 826
Time:
Concat file: 0.00
Concat fragment: 0.00
Schedule: 0.00
User: 0.00
Mount: 0.00
Ssh authorized key: 0.00
Notify: 0.00
Exec: 0.00
Cron: 0.00
Pam: 0.00
Ini setting: 0.01
Shellvar: 0.06
Sysctl: 0.09
File: 0.20
Package: 0.27
Service: 0.32
Config retrieval: 1.21
Vcsrepo: 1.47
Last run: 1649238895
Transaction evaluation: 3.93
Catalog application: 4.01
Filebucket: 0.00
Total: 4.05
Version:
Config: 4d3c463 - Tim Meusel, Fri Apr 1 14:42:05 2022 +0200 : Add test foo
Puppet: 7.14.0
Damit legt Puppet
/opt/puppetlabs/puppet/cache/state/{last_run_report,last_run_summary}.yaml
an. Beide Datein enthalten Informationen ber den letzten Puppet Run, die
Laufzeit einzelner Ressourcen und vorhandene Tags.
Wenn die Option aktiv ist, wird ein Compile Error bei der Verwendung nicht initialisierter Puppet Variablen erzeugt. Upstream Doku
Damit wird Puppet Code validiert und ein Compile Error erzeugt, sofern es Fehler gibt. Upstream Doku
Sollte es irgendwelche Ruby Fehler geben, wird ein Trace davon ausgegeben.
Standardmig luft Puppet als Agent, in einem 30 Minuten Interval. Mit der splay Option lassen sich die Agents auch etwas verteilen, es kommt aber trotzdem oft zu einem Schwarmverhalten. Dem kann man entgegen wirken, in dem man den Puppet Agent nicht als Daemon, sondern mit System Timern laufen lsst.
$puppet_timer_runinterval = 30 # run interval in minutes
$puppet_timer_command = '/opt/puppetlabs/bin/puppet agent --onetime --summarize --no-splay --verbose --no-daemonize --detailed-exitcode --show-diff'
$first_run = fqdn_rand($puppet_timer_runinterval)
$second_run = $first_run + $puppet_timer_runinterval
# lint:ignore:strict_indent
$_timer = @("EOT")
# THIS FILE IS MANAGED BY PUPPET
[Unit]
Description=Systemd Timer for Puppet Agent
[Timer]
Persistent=true
OnCalendar=*-*-* *:${first_run},${second_run}:00
[Install]
WantedBy=timers.target
| EOT
$_service = @("EOT")
# THIS FILE IS MANAGED BY PUPPET
[Unit]
Description=Systemd Timer Service for Puppet Agent
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=${puppet_timer_command}
SuccessExitStatus=2
User=root
Group=root
| EOT
# lint:endignore:strict_indent
# we should not use the name puppet or puppet-agent. That .service might already exist
systemd::timer { 'puppet-timer.timer':
timer_content => $_timer,
service_content => $_service,
active => true,
enable => true,
}
pandoc
ermglicht es aus dieser markdown Datei eine pdf zu generieren. Die
gngigen Linux Distributionen haben pandoc in ihren Repositories. Der simpelste
Aufruf lautet wie folgt:
pandoc --from markdown README.md --output puppet.pdf
Und fr die puppet.pdf hier im Repo:
pandoc README.md --output puppet.pdf "-fmarkdown-implicit_figures -o" --from=markdown -V geometry:margin=.4in --toc --highlight-style=espresso
Dieses Dokument steht unter der CC BY-NC-SA 4.0 Lizenz. Codebeispiele sind unter der GNU Affero General Public License v3.0 lizensiert. Fr kommerzielle Anfragen, Nachfragen zu Consulting oder Feedback kontaktieren sie bitte [email protected].