484 lines
27 KiB
TeX
484 lines
27 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. Chef übernimmt
|
|
dabei Aufgaben der Provisionierung (Installation der grundlegenden Dienste,
|
|
Resourcenverwaltung, Einrichtung und Konfiguration von Middleware) bis hin zu
|
|
Deployment (Verteilung der eigentlichen Business-Anwendung).
|
|
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}
|
|
\altentry{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}
|
|
\altentry{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 - \ref{sec:initsysteme}). 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 ebenfalls weit 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 von Puppet beeinflusst. 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, wuchs 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
|
|
begann er an ein neues Deploymentsystem zu schreiben. Damals trug es noch den
|
|
Namen \emph{Marionette}. Dabei verwendete er ebenfalls, wie schon bei Puppet,
|
|
die Programmiersprache Ruby zur Implementierung des Clients. Ein wichtiges
|
|
Designziel seines neuen System war es, bessere Abstraktionsmöglichkeiten zu
|
|
schaffen, um damit die Wiederverwendbarkeit zu erhöhen (Quelle:
|
|
\cite{chefhistory}). Anzumerken ist, dass 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 speziell 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. Es wird häufig auf umfangreiche Standardbibliotheken und Sprachkonstrukte
|
|
verzichtet, die in General-Purpose-Languages üblich sind. Puppets Sprache wurde
|
|
an das Konfigurationsformat der Überwachungssoftware 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}. Diese können in Variablen gespeichert werden. Die
|
|
\href{https://forge.puppetlabs.com/puppetlabs/stdlib}{Standardbibliothek} von
|
|
Puppet stellt Funktionen bereit, 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 \emph{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 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. Andere wiederum bevorzugen die
|
|
Flexibilität von Ruby. Facebook gab dies als einen der Grund an für einen
|
|
Umstieg im Jahre 2013 von \emph{CFEngine2} auf \emph{Chef 11}
|
|
\cite{facebooklikeschef}.
|
|
|
|
Das strukturelle Gegenstück zu \emph{Cookbooks} in Chef ist das
|
|
\emph{Puppet-Module} in Puppet. Diese werden in der Community entwickelt. Da
|
|
Puppet älter ist, ist anzunehmen, dass hierfür mehr Puppet-Module zur Verfügung
|
|
stehen, als 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} zur 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 Begriffe
|
|
``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 wurden alle Sprachen
|
|
in beiden Projekte mit weniger als 100 Suchtreffer aus Übersichtlichkeitsgründen
|
|
nicht in das Diagramm übernommen (siehe Tabelle). Eine Stichproben der
|
|
Ergebnisse, dass die Suchtreffer sich überwiegend mit den eigentlichen Projekten
|
|
Chef und Puppet beschäftigen. Anzumerken ist, dass Zielgruppe von Puppet
|
|
überwiegend Systemadminstratoren aus besteht, während Chef auch von vielen
|
|
Entwicklern genutzt wird. Letztere verwenden bevorzugt Github.
|
|
|
|
\begin{figure}[h]
|
|
\pgfplotstableread{
|
|
Puppet Ruby Shell Python Javascript Perl Andere
|
|
0 9902 321 148 124 42 260
|
|
7315 3108 751 207 157 137 211
|
|
}\dataset
|
|
\definecolor{bblue}{HTML}{4F81BD}
|
|
\definecolor{rred}{HTML}{C0504D}
|
|
\definecolor{ggreen}{HTML}{9BBB59}
|
|
\definecolor{ppurple}{HTML}{9F4C7C}
|
|
\begin{tikzpicture}
|
|
\begin{axis}[ybar stacked,
|
|
width=12cm,
|
|
enlarge x limits=0.5,
|
|
height=10cm,
|
|
ymin=0,
|
|
ymax=17000,
|
|
scaled x ticks = false,
|
|
scaled y ticks = false,
|
|
ylabel={Anzahl der Suchtreffer},
|
|
xtick=data,
|
|
xticklabels = {
|
|
\strut Chef (Gesamt: 12661),
|
|
\strut Puppet (Gesamt: 14325)
|
|
},
|
|
major x tick style = {opacity=0},
|
|
every node near coord/.append style={
|
|
anchor=west,
|
|
rotate=90
|
|
},
|
|
legend entries={Puppet, Ruby, Shell, Python, Javascript, Perl, Andere},
|
|
legend columns=13,
|
|
]
|
|
|
|
\addplot[draw=black,fill=rred] table[x index=0,y index=0] \dataset;
|
|
\addplot[draw=black,fill=ggreen] table[x index=0,y index=1] \dataset;
|
|
\addplot[draw=black,fill=bblue] table[x index=0,y index=2] \dataset;
|
|
\addplot[draw=black,fill=ppurple] table[x index=0,y index=3] \dataset;
|
|
\addplot[draw=black,fill=magenta] table[x index=0,y index=4] \dataset;
|
|
\addplot[draw=black,fill=yellow] table[x index=0,y index=5] \dataset;
|
|
\addplot[draw=black,fill=black] 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}
|
|
|
|
\begin{table}[h]
|
|
\caption{Ausgangsdaten für das Diagramm}
|
|
\begin{tabular}{l|c|c|c|c|c|c|c|c|c|c|c|c}
|
|
Sprache & \textbf{Ruby} & \textbf{Puppet} & \textbf{Shell} & \textbf{Python} & \textbf{Javascript} & \textbf{Perl} & PHP & Java & VimL & CSS & C & C++ \\\hline
|
|
\textbf{Chef} & 9,902& - & 321 & 148 & 124 & 42 & 56 & 88 & - & 31 & 48& 37 \\\hline
|
|
\textbf{Puppet} & 3,108& 7,315 & 751 & 207 & 157 & 137 & 82 & 42 & 64 & 23 & - & - \\
|
|
\end{tabular}
|
|
\end{table}
|
|
|
|
\vspace{0.5cm}
|
|
|
|
Eine weitere wichtige Statistik für Opensourceprojekte ist die Anzahl der
|
|
Abonnenten auf den jeweiligen Mailinglisten.
|
|
|
|
\begin{description}
|
|
\item[chef@lists.opscode.com] Community-Mailingliste, 1620 Abonnenten, \href{http://lists.opscode.com/sympa/info/chef}{Quelle}, Stand: 31.03.2014
|
|
\item[chef-dev@lists.opscode.com] Entwickler-Mailingliste, 652 Abonnenten, \href{http://lists.opscode.com/sympa/info/chef-dev}{Quelle}, Stand: 31.03.2014
|
|
\item[puppet-users@googlegroups.com] Community-Mailingliste,
|
|
\textasciitilde{}7000 Abonnenten, Quelle: \href{https://twitter.com/puppetlabs/status/450760644329881600}{Anfrage per Twitter}, Stand: 01.04.2014
|
|
\end{description}
|
|
|
|
Mailinglisten eignen sich, um qualitiv die aktiven Nutzer beider Projekte zu
|
|
vergleichen. Neben dem Bugtracker ist stellt die Mailingliste ein wichtiges
|
|
Kommunikationsmittel dar.
|
|
|
|
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 den Suffix .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''. Eine Ausnahme 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.pp} lautet die Datei \emph{default.rb}).
|
|
Allerdings werden in Recipes keine separaten 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 Standardwerte besitzen. Chef besitzt
|
|
mit \emph{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 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 \emph{Hieradb}
|
|
gesucht und gegebenfalls überschrieben. Hiera-Attribute können spezifisch für
|
|
einzelne Nodes oder für die gesamte Organisation gesetzt werden. 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 bereits eine Reihe
|
|
von Types mit. Diese werden Core-Types genannt. 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 weiteres häufig genutztes Pattern, um Resources zu gruppieren, ist der
|
|
\emph{Defined-Type}. Dieser ist das Äquivalent zur aus Chef bekannte
|
|
\emph{Definition}. Ein Defined-Type kann im Gegensatz zum Custom-Type auch
|
|
direkt in der Puppet-Sprache mit dem Schlüsselwort \emph{define} erstellt
|
|
werden.
|
|
|
|
Vor der eigentlichen Provisionierung werden Informationen über das System zu
|
|
gesammelt. Dabei wird auf die Bibliothek
|
|
\href{http://puppetlabs.com/facter}{Facter} zurückgegriffen. In frühen Versionen
|
|
von Chef wurde die gleiche Bibliothek verwendet, bevor später
|
|
\href{http://docs.opscode.com/ohai.html}{Ohai} integriert wurde.
|
|
|
|
Chef benutzt die gleiche Template-Syntax wie Puppet (eRuby). Der einzige
|
|
Unterschied bei Chef ist die Funktion für verschiedene Plattformen und
|
|
-versionen verschiedene Template-Varianten der gleichen Datei im Cookbook
|
|
vorzuhalten. Die Varianten werden durch Unterordner im Verzeichnis
|
|
\emph{templates/} unterschieden (z.B. \emph{templates/windows} oder
|
|
\emph{templates/ubuntu-12.04}). Falls kein der Plattform entsprechende Ordner
|
|
existiert sucht Chef im Verzeichnis \emph{templates/default}.
|
|
|
|
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 spricht man von modelbasiertem Konfigurationsmanagment,
|
|
während Chef ein \href{http://www.getchef.com/solutions/configuration-management/}{codebasiertes
|
|
Konfigurationsmanagment} ist. Da manche Resources voneinander abhängen, kann durch die Angabe der
|
|
Parameter \emph{before} und \emph{require} die Reihenfolge 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 Parameter \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 werden Passenger oder
|
|
Mongrel als Applikationsserver empfohlen, wobei Nginx als Load-Balancer fungiert. Ein
|
|
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, soll sich dabei
|
|
vervierfacht haben und kann somit bis zu 10.000 Nodes bedienen (Quelle:
|
|
\cite{chefscale}). Für Puppet wurden keine Statistiken gefunden, die eine Aussage
|
|
darüber treffen, wieviele Nodes pro Server betreut werden können. Allerdings ist
|
|
anzunehmen, dass die Anzahl der Server, bedingt durch die genutzte Architektur,
|
|
kleiner ist als bei Chef.
|
|
|
|
Zu den, von offiziell von Chef unterstützten, Plattformen gehören Windows, MacOS X,
|
|
verschiedene Linuxderivate (Debian, Ubuntu, Redhat, \ldots) und Solaris. Puppet
|
|
bietet breiteren Support und unterstützt zusätzlich Free- und OpenBSD sowie
|
|
HP-UX und AIX.
|
|
|
|
Zusammenfassend lässt sich feststellen, dass Chef und Puppet den gleichen
|
|
Funktionsumfang bieten. Die Grundkonzepte sind ähnlich, so ein Anwender des
|
|
einen Systems mit wenig Aufwand auch das andere System lernen kann. Die beiden
|
|
Firmen, Puppet Labs und Chef, enwickeln beide ihr Produkt stetig weiter und
|
|
bieten kommerziellen Support. Während Puppet auf den klassischen
|
|
Systemadminstrator abzielt, ist Chef ein Produkt der
|
|
\href{http://www.getchef.com/solutions/devops/}{DevOps}-Bewegung, bei welcher
|
|
der (operative) adminstrative Teil einer Organisation stärker mit der
|
|
Entwicklung verzahnt wird.
|
|
|
|
% vim: set spell spelllang=de_de
|