ltcp/bericht/chef/chef-comparison.tex

468 lines
26 KiB
TeX

\subsection{Funktionsweise von Chef}
\label{ssub:funktionsweise_von_chef}
\href{http://www.getchef.com/chef/}{Chef} ist ein Framework, welches eine
automatisierte Serverkonfiguration und -verwaltung ermöglicht. (TODO -
Provisionierung und Deployment) Der Endanwender
beschreibt hierbei die Systemressourcen und ihre Zustände in der
Programmiersprache \href{https://www.ruby-lang.org/}{Ruby}. Diese Definitionen
werden von dem Program \emph{Chef-Client} eingelesen und in notwendige Aktionen
übersetzt, welche ausgeführt werden müssen, um den beschriebenen Zustand
umzusetzen.
Die Gesamtheit aller Definitionen/Einstellungen nennt man das \emph{Chef-repo}.
Ein solches untergliedert sich in mehrere \emph{Cookbooks}\label{cookbook}. Ein
Cookbook ist die Grundverwaltungseinheit in Chef. Es erfüllt einen bestimmten
Teilaspekt des Systems (z.B. die Einrichtung eines Webservers
\href{https://github.com/opscode-cookbooks/apache2}{Apache}). Cookbooks können
versioniert werden. Es können Abhängigkeiten zwischen mehreren Cookbooks
angegeben werden.
Physikalische oder virtuelle Maschinen werden als \emph{Nodes} bezeichnet.
Einer Node können \emph{Attributes}, \emph{Roles} und Cookbooks zugewiesen
werden. Roles und Cookbooks werden dazu in die sogenannte \emph{Run-List} der
Node eingefügt. Diese gibt die Reihenfolge an, in welcher Roles und Cookbooks
angewendet werden. Roles bieten eine Möglichkeit, Nodes zu gruppieren, welche die
gleichen Aufgaben in einer Organisation erfüllen (z.B. Webserver).
Es gibt mehrere Möglichkeiten \emph{Chef} zu betreiben:
\begin{description}
\item[Chef-Solo] Chef-Solo ist die einfachste Ausführungsform. Alle nötigen
Daten werden aus einem lokalen Verzeichnis geladen. Im Gegensatz zu
\emph{Chef-Server} und \emph{Enterprise Chef} wird bei Chef-Solo das
Programm \emph{chef-solo} an Stelle von \emph{chef-client} ausgeführt. Diese
Form wurde für die Umsetzung der Aufgabenstellung in
Abschnitt~\ref{sub:einrichtung-der-netzwerkdienste} gewählt.
\item[Chef-Server] Hierbei authentifiziert sich \emph{Chef-Client} über eine
\emph{REST-Api} zu einem \emph{Chef-Server} mittels eines privaten RSA-Keys.
Auf diesem wird das Chef-repo zentral verwaltet. Der Chef-Client bekommt von
diesem alle nötigen Informationen für die zu provisionierende \emph{Node}.
Chef-Server bietet eine webbasierte GUI für die Administration an. Die
Attributes aller Nodes sind über die eingebaute Suchmaschine
\href{https://lucene.apache.org/solr/}{\emph{Solr}} durchsuchbar.
\item[Enterprise-Chef/Hosted-Enterprise-Chef] Enterprise-Chef bietet
zusätzlich zu den Funktionen der Opensource-Version Chef-Server eine
rollenbasierte Benutzerverwaltung, bessere Überwachung, eine verbesserte
Weboberfläche sowie Push-Deployment an. Während bei Hosted-Enterprise-Chef
die Firma Chef den Serverteil betreibt und die Skalierung des Dienstes
übernimmt, ist bei Enterprise-Chef der Server in der eigenen
Organisation~\cite{chefenterprise}.
\end{description}
\subsubsection{Aufbau eines Cookbooks}
\label{aufbau_eines_cookbook}
Nachfolgend ist die Ordnerstruktur eines Cookbooks am Beispiel von
\href{https://github.com/opscode-cookbooks/apt}{apt} dargestellt.
\begin{tikzpicture}
\treeroot{apt-2.3.4}
\altentry{attributes}{1}
\altentry{default.rb}{2}
\altentry{files}{1}
\altentry{default}{2}
\treeentry{apt-proxy-v2.conf}{3}
\altentry{libraries}{1}
\altentry{helpers.rb}{2}
\altentry{network.rb}{2}
\altentry{providers}{1}
\altentry{preference.rb}{2}
\altentry{repository.rb}{2}
\altentry{recipes}{1}
\altentry{cacher-client.rb}{2}
\altentry{cacher-ng.rb}{2}
\altentry{default.rb}{2}
\altentry{resources}{1}
\altentry{preference.rb}{2}
\altentry{repository.rb}{2}
\altentry{templates}{1}
\altentry{debian-6.0}{2}
\altentry{default}{2}
\altentry{01proxy.erb}{3}
\altentry{acng.conf.erb}{3}
\altentry{ubuntu-10.04}{2}
\treeentry{acng.conf.erb}{3}
\altentry{CHANGELOG}{1}
\altentry{metadata.json}{1}
\altentry{metadata.rb}{1}
\altentry{README.md}{1}
\end{tikzpicture}
Die Verzeichnisnamen sind fest vorgeben. Jedes Verzeichnis hat seine eigene
Funktion. Dies hat den Vorteil, das man sich schnell in neuen Cookbooks zurecht
findet. Hier nochmal die einzelnen Verzeichnisse im Überblick:
\begin{description}
\item[attributes] Attributes sind einfache Schlüssel-Wert-Beziehungen und
setzen Standardwerte für das Cookbook. Die Schlüssel sind hierarchisch
organisiert. In der Regel ist die höchste Ebene der Name des Cookbooks (z.B.
\emph{normal.mysql.client.packages}). Werte können Strings, Zahlen oder
Arrays sein. Die gesetzten Attributes können in Roles, Nodes oder von
anderen Cookbooks überschrieben werden. Hierfür werden die Attributes mit
den verschiedenen Prioritäten default, force\_default, normal und override
gesetzt (aufsteigender Wertigkeit) gesetzt, wobei eine höhere Priorität eine
Niedrigere überschreibt.
\item[files] In diesem Verzeichnis können statische Dateien eingefügt werden,
welche auf dem Zielsystem in das entsprechende Verzeichnis kopiert werden
können.
\item[libraries] In diesem Pfad können Hilfsfunktionen und
Spracherweiterungen definiert werden.
\item[resources] Ressourcen beschreiben die Bestandteile eines Systems. Eine
Resource kann z.B. eine Datei, ein Prozess oder ein Paket sein. Man
beschreibt, welchen Zustand (Action in Chef genannt) diese Ressource haben
soll und Chef versucht, diesen Zustand herzustellen. Chef liefert bereits
viele wichtige Ressourcen mit. In Cookbooks können darüber hinaus eigene
Resources definiert werden.
\item[providers] Während Ressourcen nur die Schnittstelle mit allen Attributes
beschreiben, die gesetzt werden können, ist der Provider eine konkrete
Implementierung. Deswegen muss für jede Ressource mindestens ein Provider
existieren. Es kann mehrere Provider für eine Ressource geben, um zum
Beispiel um mehrere Plattformenvarianten oder Betriebssysteme abdecken zu
können (z.B. bei Paketmanagern oder Initsystemen TODO - Initsystemen
erklären). In eigenen Cookbooks erstellte Resources/Provider nennt man LWRP
(Lightweight-Resource/Provider).
\item[recipes] In Recipes werden Ressourcen instanziiert, welche nötig sind,
um die gewünschte Ziel zu erreichen. Dabei können Abhängigkeiten zwischen
Recipes angegeben werden.
\item[definitions] Ressources, welche häufiger in verschiedenen Recipes in
ähnlicher Form benötigt werden, können in eine \emph{Definition}
ausgelagert werden. Ein Beispiel ist das Generieren eines SSH-Schlüssels
für verschiedene Nutzer auf dem System. Für komplexere Konstrukte sollten
jedoch LWRPs (siehe oben) bevorzugt werden.
\item[templates] Häufig werden dynamisch generierte Dateien benötigt, um zum
Beispiel Konfigurationsdateien zu erzeugen. In Chef wird für diesen Zweck
die Templatesprache eRuby (Embedded Ruby) verwendet. In ERB-Templates wird
Rubycode ausgeführt, der sich zwischen den Tags \emph{<\%} und \emph{\%>}
befindet. Dies erlaubt es einerseits den Inhalt von Variablen oder den
Rückgabewert von Methoden zu interpolieren, andererseits können in Templates
Kontrollstrukturen wie If-Statements und Schleifen verwendet werden.
\item[metadata.rb] In der Datei \emph{metadata.rb} kann der Name des Cookbook,
die eigene Version, eine Beschreibung sowie Abhängigkeiten zu anderen
Cookbooks angegeben werden.
\end{description}
\begin{lstlisting}[caption={Beispiel ERB-Template:}]
Diese Zeile wird beim Rendern ohne Aenderung uebernommen
<%# Ein Kommentar%>
Diese Node heisst: <%= @node.name %>
<% if node[:platform] == "ubuntu" -%> <%# Bedingte Anweisung %>
Diese Zeile erscheint auf Ubuntu-basierten Nodes.
<% else %>
Diese Zeile erscheint auf nicht Ubuntu-basierten Nodes.
<% end -%>
<%# Listet in einer Schleife alle Blockdevices der Node auf %>
<% @node.block_device.each do |block_device, attributes| %>
<%= block_device %>: <%= attributes.join(", ") %>
<% end %>
\end{lstlisting}
\subsubsection{Ablauf einer Provisonierung}
\label{ablauf_einer_provisionierung}
Der genaue Ablauf wurde der Onlinedokumentation (\cite{chefrun}) von Chef
entnommen. Wie schon zu Beginn erwähnt, wird die Provisonierung von einem
Programm namens \emph{Chef-Client} durchgeführt. Je nach gewählter Umgebung kann
dieser periodisch vom Scheduler \emph{Cron} gestartet, permanent als
Systemdienst laufen (z.B. bei Enterprise Chef) oder manuell gestartet werden
(z.B. bei Vagrant - siehe~\ref{sub:einrichtung-der-netzwerkdienste}).
Als erstes lädt dieser Prozess seine Konfiguration aus der Datei
\emph{client.rb}. In dieser stehen beispielsweise die URL des Chef-Server, in
welchem Pfad temporäre Dateien gespeichert werden und der Name der Node.
Letzteres ist wichtig, um die Node in Chef einordnen zu können und die richtigen
Einstellungen zuzuweisen. Alternativ kann der Name auch von der Bibliothek
\href{http://docs.opscode.com/ohai.html}{Ohai} gesetzt werden, in dem auf den
Hostnamen oder der FQDN (Fully Qualified Domain Name) zurückgegriffen wird.
Ohai sammelt systemrelevante Daten wie Details über Hardwarekomponenten (Anzahl
der CPUs, Größe und Art des RAMs, Netzwerkanbindung, Festplatten/SSDs, \dots),
Informationen über die Plattform (Art des Betriebssystems und sowie dessen Version,
installierte Anwendungssoftware) und die laufenden Prozesse. Diese Informationen sind
durch eigene Ohai-Plugins erweiterbar und können im Provisionierungsprozess
genutzt werden, um weitere Entscheidungen zu treffen. Sie sind darüber hinaus
auch auf dem Server gespeichert und für andere Clients abrufbar.
Nach dem alle Einstellungen eingelesen sind, verbindet sich Chef-Client mit
Chef-Server. Die Authentifizierung erfolgt über den vorher auf der Node
abgelegten RSA-Schlüssel. Für Administratoren gibt es einen Validator-Key. Im
\href{http://docs.opscode.com/knife\_bootstrap.html}{Bootstraprozess}, in
welchem Chef initial auf der Node installiert, kann mit diesem eine Node auf dem
Server registriert werden und ein Clientkey generiert werden.
Anschließend werden alte gesetzte Attributes und die Run-List vom Server
übertragen. Im 1. Durchlauf oder bei Verwendung von Chef-Solo sind diese Daten
nicht vorhanden. Stattdessen kann eine Datei im JSON-Format angegeben werden,
um die Attributes und der Run-List für die Node zu spezifizieren. Außerdem ist
es möglich eine Run-List auf dem Chef-Server einzustellen, welche ausgeführt
wird, wenn die Node keine eigene Run-List besitzt.
Durch Auswertung der eingebunden Rollen und Recipes werden die benötigen
Cookbooks ermittelt. Der Client fordert eine Liste aller darin enthaltenen
Dateien und deren Checksumme an. Alle geänderten oder neuen Dateien werden
heruntergeladen und im lokalen Cache gespeichert.
Nun werden die Attribute zurückgesetzt und aus den Cookbooks, Roles und der Node
neu generiert und entsprechend ihrer Priorität gesetzt. Die, in den Cookbooks
definierten, Resources werden geladen und mit den, von Chef mitgelieferten,
Resources in der Resource-Collection zusammengefasst. Nachdem alle Definitions
und Libraries geladen wurden, werden schließlich die Recipes verarbeitet. Die
darin erstellten Resources beschreiben das System. Für jede Resource wird eine
Action festgelegt, was gleichbedeutend mit deren Zustand ist.
Im nächsten Schritt folgt das sogenannte Converging (englisch für
\emph{Angleichen}). Es werden alle Resources Schritt für Schritt abgearbeitet.
Dabei wird für jede Resource, der für die Plattform zugehörige, Provider
ausgewählt. Dieser überprüft den aktuellen Zustand der Resource und verändert,
wenn notwendig, das System, um den Sollzustand zu erreichen. Zum Schluss überträgt
Chef-Client die aktualisierten Attributes auf den Server, von welchem sie in
Solr indexiert werden.
Es besteht die Möglichkeit Handler vor oder nach dem Provisioning auszuführen.
Diese können im Fehlerfall Benachrichtigungen an das Monitoringssystem oder per
Email verschicken. In letzten Abschnitt (\ref{minitest_handler}) wird dieser
Mechanismus genutzt um Tests auszuführen.
\subsubsection{Vergleich mit puppet}
\label{vergleich_mit_puppet}
Ein anderes weiteres verbreitetes Konfigurationsmanagmentsystem ist Puppet. Es
ist das Ältere der beiden Projekte. Während das erste Puppetrelease bereits im
Jahr 2005 von den Puppet Labs veröffentlicht wurde, erschien Chef erst 4 Jahre
später im Jahre 2009. Chef wurde stark beeinflusst von Puppet. Der Erfinder von
Chef Adam Jacob war selbst langjähriger Puppetnutzer, bevor er Chef schrieb.
Seine damalige Konsultantfirma betreute mehrere Firmen bei der Provisionierung
der Infrastruktur bis hin zum Deployment der Anwendung. Dabei kam Puppet zum
Einsatz. Mit steigender Anzahl der Kunden, stieg nach Aussagen von Adam Jacob
der Aufwand bei der Verwaltung der Puppet-Konfiguration. Diese mussten häufig
für jeden Kunden stark angepasst oder neugeschrieben werden. Aus diesem Grund
began er an ein neues Deploymentsystem zu schreiben, damals unter dem Namen
\emph{Marionette}. Dabei verwendete ebenfalls wie schon bei Puppet die
Programmiersprache Ruby zur Implementierung des Clients. Ein wichtiges
Designziel seines neues System war es, bessere Abstraktionsmöglichkeiten zu
schaffen, um so die Wiederverwendbarkeit zu erhöhen (Quelle:
\cite{chefhistory}). Anzumerken ist, das seit der damals veröffentlichten
Puppetversion
(\href{https://github.com/puppetlabs/puppet/commit/ce964ecb6d6a38cb7fb9f0b13a7e6b2eb4c381c3}{0.24.5})
neue Funktionen und Spracherweiterungen zu Puppet hinzugefügt wurden um dieses
Problem zu adressieren.
(\cite{puppetlanguagechangelog})
Während bei Chef die Konfiguration in Ruby geschrieben wird, besitzt Puppet
seine eigene Konfigurationssprache. Puppets Sprache ist im Gegensatz zu
General-Purpose-Languages wie Ruby, Java oder C/C++ eine
Domain-Specific-Language (DSL). Eine DSL ist eine eigens für den Anwendungszweck
geschriebene und optimierte Sprache. Sie enthält häufig Elemente und Ausdrücke,
welche es erlauben Probleme der Anwendungsdomain effizient zu lösen. Auf der
anderen Seite wird verzichtet auf umfangreiche Standardbibliotheken und
Sprachkonstrukte verzichtet, die in General-Purpose-Language üblich sind.
Puppets Sprache wurde an das Konfigurationsformat von Nagios angelehnt
(\cite{puppetlanguage}). Sie ist deklarativ gehalten und soll möglichst einfach
erlernbar für Administratoren, auch ohne programmiertechnischen Hintergrund,
sein. Der Schwerpunkt liegt auf der Beschreibung von \emph{Resources}. Die
Sprache besitzt Kontrollstrukturen wie Case- und If-Statements. Es gibt
Datentypen wie \emph{Strings}, \emph{Booleans}, \emph{Arrays}, \emph{Reguläre
Ausdrücke} und \emph{Hashes}, welche Variablen zugewiesen werden können. Die
\href{https://forge.puppetlabs.com/puppetlabs/stdlib}{Standartbibliothek} von
Puppet stellt Funktionen, um auf diesen Datentypen einfache Operationen
auszuführen. Allerdings ist es nicht möglich Schleifen auszuführen. (Diese
\href{http://docs.puppetlabs.com/puppet/latest/reference/experiments_lambdas.html}{Funktion}
ist momentan als experimental markiert). Funktionen können nicht direkt in
Puppets Sprache definiert werden. Stattdessen werden diese als Erweiterung des
Parsers in Ruby implementiert, was wiederum den den Nachteil hat, dass dafür
eine weitere Sprachen erlernt werden muss. Manche Unternehmen und Organisationen
greifen bevorzugt auf Puppet zurück, weil es einfacher ist neue Mitarbeiter ohne
Rubykenntnisse in diesem Framework zu schulen (TODO - Beleg). Andere wie
bevorzugen die Flexibilität von Ruby. Facebook gab dies als Einen der Gründe an,
warum sie im Jahre 2013 von \emph{CFEngine2} (TODO - Link) auf \emph{Chef 11}
umgestiegen sind.
Das strukturelle Äquivalent zu \emph{Cookbooks} in Chef ist in Puppet das
Puppet-Module. Diese werden in der Community ausgetauscht und entwickelt. Da
Puppet älter ist, ist zu erwarten das hierfür mehr Puppet-Module zu Verfügung
stehen als für Cookbooks für Chef. Die primäre Distributionsquelle ist
\href{https://forge.puppetlabs.com/}{Puppet Forge} in dem \textbf{2206}
\href{https://forge.puppetlabs.com/modules?supported=yes}{Module} zu Verfügung
stehen (Stand: 31.03.2014). Für Chef gibt es eine ähnliche
\href{http://community.opscode.com/}{Community-Seite} mit \textbf{1368}
Modulen, (Stand: 31.03.2014 - ermittelt über die
\href{https://cookbooks.opscode.com/api/v1/cookbooks?start}{API}). Zu einer
weiteren wichtigen Quelle hat sich die Plattform
\href{https://github.com}{Github} für beide Projekte entwickelt. Für einen
Vergleich wurde die Anzahl der Suchtreffer für Projekte, die die Suchbegriffe
"Chef" und "Puppet" in der Suchmaschine auf Github herangezogen. Github filtert
Forks (Abspaltungen) von Projekten aus den Suchergebnissen heraus und
schlüsselt die Ergebnisse nach Programmiersprache auf. Es werden alle
Programmiersprachen in beide Projekte mit weniger als 100 Suchtreffer aus
Übersichtlichkeitsgründen nicht in das in Diagramm übernommen (siehe Tabelle). Kurze
Stichproben der Suchergebnisse, dass die Suchtreffer sich überwiegend mit den
eigentlichen Projekten Chef und Puppet beschäftigen. Anzumerken ist, das
Zielgruppe von Puppet eher Systemadminstratoren sind, während Chef auch von
vielen Entwicklern genutzt wird, wobei Letztere bevorzugt Github verwenden.
\begin{figure}[H]
\pgfplotstableread{
%Gesamt Puppet Ruby Shell Python Javascript Perl
12661 0 9902 321 148 124 42
14325 7315 3108 751 207 157 137
}\dataset
\definecolor{bblue}{HTML}{4F81BD}
\definecolor{rred}{HTML}{C0504D}
\definecolor{ggreen}{HTML}{9BBB59}
\definecolor{ppurple}{HTML}{9F4C7C}
\begin{tikzpicture}
\begin{axis}[ybar,
width=\textwidth,
enlarge x limits=0.5,
height=15cm,
ymin=0,
ymax=17000,
scaled x ticks = false,
scaled y ticks = false,
ylabel={Anzahl der Suchtreffer},
xtick=data,
xticklabels = {
\strut Chef,
\strut Puppet
},
%xticklabel style={yshift=-10ex},
major x tick style = {opacity=0},
every node near coord/.append style={
anchor=west,
rotate=90
},
legend entries={Gesamt, Puppet, Ruby, Shell, Python, Javascript, Perl},
legend columns=13,
legend style={ anchor=north west,at={(axis description cs:0,-0.1)}}
%legend style={draw=none,nodes={inner sep=10pt}},
]
\addplot[draw=black,fill=rred, nodes near coords] table[x index=0,y index=0] \dataset;
\addplot[draw=black,fill=ggreen, nodes near coords] table[x index=0,y index=1] \dataset;
\addplot[draw=black,fill=bblue, nodes near coords] table[x index=0,y index=2] \dataset;
\addplot[draw=black,fill=ppurple, nodes near coords] table[x index=0,y index=3] \dataset;
\addplot[draw=black,fill=magenta, nodes near coords] table[x index=0,y index=4] \dataset;
\addplot[draw=black,fill=yellow, nodes near coords] table[x index=0,y index=5] \dataset;
\addplot[draw=black,fill=black, nodes near coords] table[x index=0,y index=6] \dataset;
\end{axis}
\end{tikzpicture}
\caption{Anzahl der Suchtreffer auf Github aufgeschlüsselt nach
Programmiersprache für die Begriffe ``Chef'' und ``Puppet''}
\end{figure}
Rohdaten für das Diagramm
\begin{tabular}{l|c|c|c|c|c|c|c|c|c|c|c|c}
Sprache & Ruby & Puppet & Shell & Python & Javascript & Perl & PHP & Java & VimL & CSS & C & C++ \\\hline
Chef & 9,902& - & 321 & 148 & 124 & 42 & 56 & 88 & - & 31 & 48& 37 \\\hline
Puppet & 3,108& 7,315 & 751 & 207 & 157 & 137 & 82 & 42 & 64 & 23 & - & - \\
\end{tabular}
\vspace{0.5cm}
Eine andere wichtige Statistik für Opensourceprojekte ist die Subscriber auf den jeweiligen
Mailinglisten.
\begin{description}
\item[chef@lists.opscode.com] Community-Mailingliste, 1620 Leser, \href{http://lists.opscode.com/sympa/info/chef}{Quelle}, Stand: 31.03.2014
\item[chef-dev@lists.opscode.com] Entwickler-Mailingliste, 652 Leser, \href{http://lists.opscode.com/sympa/info/chef-dev}{Quelle}, Stand: 31.03.2014
\item[puppet-users@googlegroups.com] Community-Mailingliste, \textasciitilde{}7000 Leser, Quelle: \href{https://twitter.com/puppetlabs/status/450760644329881600}{Anfrage per Twitter}, Stand: 01.04.2014
\end{description}
Mailinglisten eigenen sich um qualitiv die aktive Nutzer beider Projekte zu
vergleichen. Sie ist neben dem Bugtracker ein wichtiges Mittel der
Kommmunikation.
Die Zahlen weisen darauf hin, dass Puppet nach wie vor eine größere Community
hat.
Anstelle von Recipes werden in Puppet Manifests geschrieben. Das sind Dateien,
die auf Endung .pp enden und sich in dem Ordner \emph{manifests} im
Puppet-Module befinden. Jedes Manifest definiert eine \emph{Class} eingeleitet
durch das Schlüsselwort \emph{class}. Der Namen dieser Klasse wird aus dem
Module-Namen und Manifest-Namen gebildet. Wenn das Module ``foo'' das Manifest
``bar'' enthält, ist der Name der Class ``foo::bar''. Außnahme bildet das
Manifest \emph{init.pp}, bei dem die Class nur ``bar'' lauten würde. Diese
Benennungskonvention wurde in Chef übernommen, um Recipes in Cookbooks zu
referenzieren (anstelle von \emph{init.rb} lautet die Datei \emph{default.rb}).
Allerdings werden in Recipes keine seperaten Objekt definiert und der ganze
Inhalt der Datei bildet das Recipe.
Eine Class in Puppet kann über Parameter konfiguriert werden. Parameter werden
im Kopfteil der Class deklariert und können Standartwerte besitzen. Chef besitzt
mit Attributes ein vergleichbares Konzept. Allerdings werden Attributes
getrennt von den Recipes definiert und sie werden dem Node-Objekte zugewiesen.
Die Attributes stehen somit allen Recipes zu Verfügung können und können an
verschiedenen Stellen überschrieben werden. In Puppet 3 wurde diese Trennung
von Code und organsationsspezifischen Daten durch die Erweiterung \emph{Hiera}
ebenfalls eingeführt. Class-Parameter werden automatisch in der hieradb gesucht
und gegebenfalls überschrieben. Hiera-Attribute können spezifisch für einzelne
Nodes gesetzt werden oder für die gesamte Organisation. In älteren Versionen von
\emph{Puppet} wurden Attributes und Module für die einzelnen Nodes in der
zentralen \emph{site.pp}-Manifest verwaltet. Hiera ersetzt die \emph{site.pp}
weitest gehend. Durch die Funktion \emph{hiera\_include} können Classes im
Hiera-Backend gesetzt werden (ähnlich der Run-List in Chef).
Resources heissen in Puppet Types. Puppet liefert wie Chef eine Reihe von
Resources/Types, die Core-Types. Wie auch in Chef können Types in Puppet mehrere
plattformspezifische Provider besitzen. Es ist möglich eigene Types zu
definieren, auch Custom-Types genannt (Ähnlich LRWP in Chef). Die
Implementierung der Types/Provider erfolgt in Ruby im Verzeichnis
\emph{lib/puppet}. Die Zustände einer Resource können in Puppet über das
Setzen des Parameters \emph{ensure} festgelegt werden (vergleichbar mit \emph{action} in
Chef).
Ein anderes häufig genutztes Pattern, um Resources zu gruppieren, ist die auch
schon aus Chef bekannte \emph{Definition}. Diese kann im Gegensatz zum
Custom-Type auch direkt in der Puppet-Sprache mit Schlüsselwort \emph{define}
definiert werden.
Chef benutzt die gleiche Template-Syntax wie Puppet (eRuby). Einziger
Unterschied bei Chef ist die Funktion für verschiedene
Plattformen/Plattformversionen verschiedene Templatevarianten der selben Datei
im Cookbook vorzuhalten. Die Varianten werden durch Unterordner im
\emph{templates/} unterschieden (z.B. \emph{templates/windows} oder
\emph{templates/ubuntu-12.04}). Falls kein der Plattform entsprechende Order
existiert fällt Chef auf \emph{templates/default} zurück.
Ein wesentlicher Unterschied zwischen Puppet und Chef ist die Reihenfolge der
Ausführung von Resources. Chef überprüft die Resources in der Reihenfolge, in
der sie in der Run-List und in den Recipes geladen werden. Puppet sortiert
Resources um. Bei Puppet deswegen spricht man von modelbasiertem
Konfigurationsmanagment. Da manche Resources voneinander kann durch die Angabe
von Abhängigkeiten mittels der Parameter \emph{before} und \emph{require}
festgelegt werden. Über die Parameter \emph{notify} und \emph{subscribe} können
darüber hinaus Resourcen aktualisiert werden, wenn sich eine Abhängigkeit
geändert hat (z.B. kann ein Dienst neugestartet werden, wenn sich die dazu
gehörige Konfiguration verändert hat). In Chef kann Letzeres über die
Paramether \emph{notifies} und \emph{subscribes} angegeben werden.
Wie auch Chef bietet Puppet verschiedene Betriebsmodi. Im einfachsten Fall wird
mit dem Befehl \emph{puppet apply} ein lokales Manifest geladen werden
(vergleichbar mit Chef-Solo). Das Äquivalent zu Chef-Server ist der
Puppetmaster, zu welchem sich der Client \emph{Puppetd} verbindet und mittels
SSL-Zertifikaten authentifiziert. In der Standarteinstellung setzt Puppetmaster
auf den verhältnismäßig einfachen Webserver WEBrick. Dieser skaliert allerdings
nicht über einen CPU-Core. Für größere Installationen wird Passenger oder
Mongrel als Applikationsserver empfohlen mit Nginx als Load-Balancer. Ein
anderer beliebter Ansatz zum Skalieren größerer Cluster ist das Verwalten der
Manifeste in einem Git-Repository, wobei Puppet periodisch über einen Cron-Job
aufgerufen wird und die ausgecheckten Manifeste ausführt. Während Chef-Server
bis zur Version 10 wie Puppet-Master in Ruby geschrieben war, wurde der API-Teil von
Chef-Server wurde in Version 11 in der Programmiersprache Erlang neugeschrieben.
Die Zahl der Nodes, die von einem Server bedient werden können soll vervierfacht
haben auf bis zu 10.000 Nodes pro Server (Quelle: \cite{chefscale}). Für Puppet
wurden keine verlässlichen Zahlen gefunden, wieviel Nodes pro Server betreut
werden können. Allerdings ist anzunehmen, dass die Zahl architekturbedingt unter
der von Chef liegt.
Zu den von offiziell von Chef unterstützt Plattformen gehören Windows, MacOS X,
verschiedene Linuxderivate (Debian, Ubuntu, Redhat...) und Solaris. Puppet
bietet breiteren Support und unterstützt zusätzlich Free- und OpenBSD sowie
HP-UX und AIX.
%- Resume: Ähnliche Projekte, lösen das gleiche Problem auf unterschiedliche Weise
% vim: set spell spelllang=de_de