2014-02-20 12:15:55 +00:00
<!--
Abstract:
2014-01-22 09:30:19 +00:00
2014-02-20 12:15:55 +00:00
Konfigurationsmanagement Chef - eine praktische Einführung
Mit wachsender Infrastruktur steigt der Bedarf nach Automatisierung. Dies soll durch Konfigurationsmanagement gelöst werden. In diesem Vortrag wird Chef[1] vorgestellt werden. Nach einem kurzen Vergleich mit dem artverwandten Konfigurationsmanagement Puppet[2], wird auf die Grundkonzepte in Chef eingangen. Es wird gezeigt, wie einfache Cookbooks in Chef aufgebaut sind und diese geschrieben und getestet werden. Zum Schluss folgt eine kurze Vorführung des Programms.
[1] http://www.getchef.com/
[2] http://puppetlabs.com/
-->
2014-02-18 19:10:16 +00:00
2014-03-02 23:00:40 +00:00
<!--
Multi-Monitor-Shortcuts:
Ctrl-O: Move Window to next screen
Mod4 + Control + j/k: Focus next/previous screen
reveal.js-Shortcuts:
o: Öffne Übersicht
s: Öffne Vortragsmonitor
-->
2014-03-02 07:41:50 +00:00
<!-- .slide: data - state="intro" -->
# Linux Cluster in Theorie und Praxis
## Konfigurationsmanagement Chef - Eine praktische Einführung
von Jörg Thalheim
2014-03-04 12:04:01 +00:00
4\. März 2014
2014-03-02 07:41:50 +00:00
2014-03-06 15:41:20 +00:00
< img src = "img/ugly_penguin.png" alt = "Penguin" >
2014-03-02 07:41:50 +00:00
< a class = "email" href = "s5245332@mail.zih.tu-dresden.de" > s5245332@mail.zih.tu-dresden.de< / a >
2014-03-02 23:00:40 +00:00
Note:
- Vorstellen
- Thema
2014-03-02 07:41:50 +00:00
2014-01-22 09:30:19 +00:00
## Inhaltsübersicht
2014-02-10 19:43:48 +00:00
- Was ist Konfigurationsmanagement
2014-02-03 21:59:11 +00:00
- Was ist Chef/Puppet
2014-01-27 15:08:01 +00:00
- Einführung in Chef
2014-02-18 19:10:16 +00:00
- Tests
2014-01-22 09:30:19 +00:00
- Demo
2014-01-27 15:08:01 +00:00
2014-03-02 23:00:40 +00:00
Note:
- Vortrag hier mal die wichtigsten Punkte kurz im Überblick
- Wozu brauche ich Chef und andere Konfigurationsmanagements
- Danach Vergleich der 2 Rivalen Chef/Puppet
- Zeige wie Chef funktioniert
- Wie sieht der Arbeitsablauf beim Entwickeln mit Hilfe von Tests aus
- Zum Schluss: Ergebnis meiner Abschlussaufgabe - Einrichtung von
Netzwerkdiensten mit Chef
2014-01-27 15:08:01 +00:00
2014-02-18 19:10:16 +00:00
2014-02-10 19:43:48 +00:00
## Was ist Konfigurationsmanagement?
2014-01-27 15:08:01 +00:00
2014-02-03 21:59:11 +00:00
- Konfigurationsmanagement
- Beispiele: Chef, Puppet, Salt, Ansible, CFEngine
2014-03-06 15:41:20 +00:00
< img src = "img/chef_logo.png" height = "150" alt = "Chef" >
< img src = "img/puppet_logo.png" height = "150" alt = "Puppet" >
< img src = "img/saltstack_logo.jpg" height = "150" alt = "Salt" >
< img src = "img/ansible_logo.png" height = "150" alt = "Ansible" >
< img src = "img/cfengine_logo.jpg" height = "150" alt = "CFEngine" >
2014-02-03 21:59:11 +00:00
Note:
- in der Praxis mehr Knoten
2014-03-02 23:00:40 +00:00
- Teams mit wechselnde Mitarbeiter, geografisch verteilt
2014-02-03 21:59:11 +00:00
- Dokumentation veraltet schnell
- sowohl bestehende Knoten müssen aktuell gehalten werden,
als auch neue eingerichtet
2014-03-02 23:00:40 +00:00
- Häufig Shell-Skripte für Automatisierung:
-> schnell komplex und schlecht maintainbar,
-> häufig nicht portable und langsam
2014-02-03 21:59:11 +00:00
- Problem wird durch Konfigurationsmanagements gelöst.
eingehen.
2014-03-02 23:00:40 +00:00
- Hier ein paar Beispiele gelistet: -> Puppet/Chef
- Grundidee:
- Zustand durch Konfigurationsdatei/Sprache beschrieben
- Konfigurationsmanagement: Herstellung des Zustands.
2014-02-03 21:59:11 +00:00
2014-02-18 19:10:16 +00:00
2014-02-10 19:43:48 +00:00
## Was ist Chef/Puppet?
2014-02-03 21:59:11 +00:00
< table class = "reveal" >
< thead >
< tr >
< th > Kriterium< / th >
< th > Chef< / th >
< th > Puppet< / th >
< / tr >
< / thead >
< tbody >
< tr >
< th > Programmiersprache< / th >
< td > Ruby< / td >
< td > Ruby< / td >
< / tr >
< tr >
< th > Konfigurationsprache< / th >
< td > Ruby< / td >
< td > eigene DSL (Ruby)< / td >
< / tr >
< tr >
< th > Paradigma< / th >
< td > Prozedural< / td >
< td > Model-Driven< / td >
< / tr >
2014-03-04 12:04:01 +00:00
<!--
2014-02-03 21:59:11 +00:00
< tr >
< th > Codezeilen< / th >
< td > 108,726< sup > [1][1]< / sup > < / td >
< td > 353,651< sup > [2][2]< / sup > < / td >
< / tr >
2014-03-04 12:04:01 +00:00
-->
2014-02-03 21:59:11 +00:00
< tr >
< th > Community< / th >
2014-03-04 12:04:01 +00:00
< td > 11,270 Repositories auf Github< sup > [1][1]< / sup > < / td >
< td > 13.020 Repositories auf Github< sup > [2][2]< / sup > < / td >
2014-02-03 21:59:11 +00:00
< / tr >
< tr >
< th > kommerzieller Support< / th >
< td > ✓ < / td >
< td > ✓ < / td >
< / tr >
< / tbody >
< / table >
2014-03-04 12:04:01 +00:00
[1]: https://github.com/search?q=chef
[2]: https://github.com/search?q=puppet
<!--
2014-02-03 21:59:11 +00:00
[1]: https://www.ohloh.net/p/puppet
[2]: https://www.ohloh.net/p/chef
2014-03-04 12:04:01 +00:00
-->
2014-02-03 21:59:11 +00:00
Note:
- Beide Projekte sind in Ruby geschrieben.
2014-03-02 23:00:40 +00:00
- Chef: Konfigurations in Ruby
- Puppet: eine auf Puppet optimierte, vereinfachte Sprache
-> einfacher für Einsteiger und Nicht-Programmieren
-> Grund für manche Firmen -> wird um Umschulung zu sparen
-> weniger flexible als Ruby (Grund bei Facebook, mehre Cluster mit mehr als 10.000 Nodes mit Chef provisionier)
2014-02-10 19:43:48 +00:00
- Während die Regeln und Beschreibung in Chef standartmäßig in der Reihenfolge abgearbeitet
wird in der sie geladen werden, sortiert Puppet diese um. In beiden kann die
Reihenfolge durch Spezifikation von Abhängigkeiten umsortiert werden (Später
ein Beispiel)
- Puppet: eigene Sprache -> komplexere Codebasis
- Um die Größe der Community abzuschätzen (schwierig): Suchtreffer für Repositories bei Github
- Alter(Puppet) > Alter(Chef)
2014-03-02 23:00:40 +00:00
- Hinter beiden Projekten stehen Firmen, Weiterentwicklung des Produkt, bieten Support und Hosting an
- Resume: Ähnliche Projekte, lösen das gleiche Problem auf unterschiedliche
Weise
2014-02-10 19:43:48 +00:00
2014-02-18 19:10:16 +00:00
2014-02-10 19:43:48 +00:00
## Einführung in Chef
2014-02-18 19:10:16 +00:00
2014-02-11 19:33:32 +00:00
### Chef-Einführung: Grundbegriffe
2014-02-10 19:43:48 +00:00
- Node, z.B.: node100.tu-dresden.de
2014-02-11 19:33:32 +00:00
- Role, z.B.: headnode, ldap
- Cookbook, z.B. slurm
- Recipe, slurm::slurmctld oder slurm::slurmd
- Resource, z.B.: package["slurm"], template["/etc/slurm.conf"], service["slurmctld"]
2014-02-10 19:43:48 +00:00
2014-02-11 19:33:32 +00:00
Note:
- Zunächst ein paar wichtige Begriffe:
2014-03-02 23:00:40 +00:00
- chef: engl. für Koch
- viele Begriffe vom Kochen abgeleitet
2014-02-11 19:33:32 +00:00
- Jede Maschine wird in chef Node genannt.
- Nodes können Rollen zugewiesen werden, um welche bestimmte Aufgaben und
Attribute zusammenfassen.
- Die grundlegende Verwaltungseinheit ist das cookbook. Ein cookbook
beschreibt alles was eingerichtet und konfiguriert werden muss um eine bestimmte Aufgabe zu erledigen. z.B. dem Einrichten des
Batchsystems slurm
2014-03-04 12:04:01 +00:00
- In einem cookbook können wiederum mehrere Recipes enthalten sein, um bestimmte
2014-02-11 19:33:32 +00:00
Unteraufgaben zu erfüllen. So könnte im Falle von slurm, auf der Headnode das
Recipe für den Slurm-Kontrolldaemon zugewiesen werden, während auf dem
Computenodes jeweils ein slurmd eingerichtet wird.
- In einem Recipe werden wiederum verschiedene Resourcen beschrieben.
- chef überprüft, bei jeder Resource, ob diese in dem gewünchten Zustand ist.
Dabei ist für jede Resource definiert, wie man vom aktuellen Zustand in den
gewünschten Zustand kommt.
- Im Falle des Slurmctld könnten das z.B.:
- das Packet slurm, welches installiert werden soll
- die Konfiguration /etc/slurm.conf
- der Dienst slurmctld, welcher gestartet werden soll.
2014-02-18 19:10:16 +00:00
2014-02-11 19:33:32 +00:00
### Chef-Einführung: Aufbau eines Cookbook
2014-02-15 16:36:34 +00:00
```bash
2014-03-02 23:00:40 +00:00
▾ modules/
2014-02-15 16:36:34 +00:00
▾ attributes/
default.rb
▾ files/
▾ default/
modules-load.conf
modules-load_header
▸ libraries/
▾ providers/
default.rb
multi.rb
▾ recipes/
config.rb
default.rb
install_attributes.rb
▾ resources/
default.rb
multi.rb
▾ templates/
▾ default/
modules.conf.erb
metadata.json
metadata.rb
Rakefile
README.md
```
Note:
- Hier ein Beispiel, wie ein cookbook aufgebaut ist.
- modules cookbook: Linux Kernel Module nachladen, maintained auf github
- Verzeichnisstruktur vorgeben - Vorteil man findet sich in neuen Cookbooks
sofort zu recht
- Für das entwickeln: Editor mit Verzeichnisfunktion empfohlen
- hier nochmal kurz ein paar wichtige Verzeichnisse:
- attributes: setzt Standartwerte für das Cookbook, können von Roles/Nodes
oder anderen Cookbooks überschrieben werden
- resourcen & providers: Chef liefert schon eine Menge sinnvoller Resourcen
mit, man kann in seinem cookbooks weitere erstellen, in diesem Fall -
modules resource mit der man in anderen cookbooks bestimmte kernel module laden
kann
2014-03-04 12:04:01 +00:00
- recipes: enthält die genannten Recipes, wenn man nichts an gibt wird die
2014-02-15 16:36:34 +00:00
default.rb geladen
2014-02-15 19:14:07 +00:00
- files: Im files-Verzeichnis können statische Konfigurations-Dateien abgelegt werden
2014-02-15 16:36:34 +00:00
- templates: meistens jedoch will Konfigurationsdateien dynamisch
2014-02-15 19:14:07 +00:00
generieren - dazu mit Templates man mithilfe mit der Markupsprache ERB generieren,
2014-02-15 16:36:34 +00:00
vergleichbar mit erzeugen von Webseiten, gleich ein Beispiel dazu
2014-02-10 19:43:48 +00:00
2014-02-11 19:33:32 +00:00
2014-02-18 19:10:16 +00:00
2014-02-11 19:33:32 +00:00
### Chef-Einführung: Code-Beispiel
2014-02-15 19:14:07 +00:00
```ruby
# attributes/default.rb
default.ntp.server = "de.pool.ntp.org"
2014-02-16 19:22:16 +00:00
default.ntp.subnets = ["::1", "127.0.0.1"]
2014-02-15 19:14:07 +00:00
```
```ruby
2014-03-04 12:04:01 +00:00
# recipes/default.rb
2014-02-15 19:14:07 +00:00
package 'ntp'
template "/etc/ntp.conf" do
owner "root"
group "root"
source "ntp.conf.erb"
notifies :restart, "service[ntp]"
end
2014-02-16 19:22:16 +00:00
service "ntp" do
action [:enable, :start]
end
2014-02-15 19:14:07 +00:00
```
2014-02-16 19:22:16 +00:00
Note:
- das beliebte Hello-World für Provisionierungssysteme: Einrichten eines
NTP-Servers
- Hier ein Beispiel, welches ich für die Abschlussaufgabe geschrieben habe
- attribute: In der Attribute-Datei - Standwerte für ntp: upstream server,
subnets auf dem ntp lauscht
2014-03-02 23:00:40 +00:00
2014-02-16 19:22:16 +00:00
2014-03-02 07:41:50 +00:00
### Chef-Einführung: Code-Beispiel
2014-03-02 23:00:40 +00:00
```ruby
2014-03-04 12:04:01 +00:00
# recipes/default.rb
2014-03-02 23:00:40 +00:00
package 'ntp'
template "/etc/ntp.conf" do
owner "root"
group "root"
source "ntp.conf.erb"
notifies :restart, "service[ntp]"
end
service "ntp" do
action [:enable, :start]
end
```
2014-03-02 07:41:50 +00:00
```ruby
# templates/default/ntp.conf.erb
# Crontab for <%= @node.name %> managed by Chef. Changes will be overwritten.
server < %= @node .ntp.server %>
restrict default noquery nopeer
< % @node .ntp.subnets.each do |net| -%>
restrict < %= net %>
< % end -%>
driftfile /var/lib/ntp/ntp.drift
```
2014-03-02 23:00:40 +00:00
Note:
- recipe:
- package: Packet per apt installieren
- template: Konfiguration aus template generieren
- zum Schluss: Dienst aktivieren und starten
- hier Abhängigkeiten zwischen Resourcen, wenn Template sich ändert -> NTP neustarten
- template:
- Beispiel für ERB-Template
- Tags -> Ruby-Code, wird interpoliert
- Verzweigungen und Schleifen möglich
## Tests
2014-03-06 15:41:20 +00:00
< img src = "img/dont_always.jpg" alt = "I don't always test my code" >
2014-03-02 23:00:40 +00:00
Note:
- Infrastruktur: schwierig zu testen, viele externe Abhängigkeiten, langsam
- Ruby: dynamische Programmiersprache -> Tippfehler, keine Compilerwarnung beim
Refactoring
- 2 Testframeworks angeschaut
2014-02-11 19:33:32 +00:00
2014-02-18 19:10:16 +00:00
## Tests: Chef Spec
```ruby
# spec/cookbooks/ntp_spec.rb
2014-02-16 19:22:16 +00:00
require_relative '../spec_helper'
describe 'ntp::default' do
let(:chef_run) do
ChefSpec::Runner.new do |node|
2014-02-18 19:10:16 +00:00
subnets = ["::1", "127.0.0.1",
"172.28.128.0 mask 255.255.255.0 nomodify notrap nopeer"]
node.set["ntp"]["subnets"] = subnets
2014-02-16 19:22:16 +00:00
end.converge(described_recipe)
end
it "should setup ntp" do
chef_run.should install_package("ntp")
chef_run.should render_file("/etc/ntp.conf").with_content("172.28.128.0")
end
end
```
Note:
2014-02-18 19:10:16 +00:00
- Chef: 2 Phasen der Ausführung: Converging und eigentliche Ausführungsphase
- Converging: Einlesen aller Resourcen -> Abhängigkeitsbaum
- Chefspec: Nur Convergingphase
-> Vorteil: sehr schnell (1s), keine Abhängigkeiten beim Testen außer Chef
-> Nachteil: es wird nichts ausgeführt
- gut für schnelle Validierung, Testen vom Zusammenspiel verschiedener
Module, einfache Logik testen, Tippfehler
- chef\_run: Attribute des Nodes
- it-block: Eigentliche Assertions
2014-03-02 23:00:40 +00:00
Chefspec Geschwindigkeit zeigen:
- bundle exec rspec spec
2014-02-18 19:10:16 +00:00
## Tests: Minitest Chef Handler
```ruby
# ntp/files/default/test/default_test.rb
require 'minitest/spec'
describe_recipe 'ntp::default' do
it "starts the ntp daemon" do
assert_sh("service ntp status")
end
it "should sync the time" do
assert_sh("ntpq -p")
end
end
```
Note:
- Minitest: werden nach jedem Deployment gestartet
2014-03-02 23:00:40 +00:00
-> Integrationstests
2014-02-18 19:10:16 +00:00
- Ähnliche Healtschecks wie bei Monitoringsystemen oder unserem Test während des Praktikum
2014-03-02 23:00:40 +00:00
-> Benachrichtung via Chefhandler möglich z.B. per Email, Jabber, ...
2014-02-18 19:10:16 +00:00
2014-02-11 19:33:32 +00:00
## Demo
2014-02-18 19:10:16 +00:00
Note:
- Abschlussaufgabe: Einrichten von 2 beliebigen Netzwerksdiensten wie im Praktikum
- In meinen Fall: NTP, Dns mit Bind, DHCP
- Vagrant: Starten einer Headnode: mehre Computenodes bekommen über das interne
Netzwerk per DHCP eine IP, nutzen das DNS und NTP des Headnode, Headnode als
Router
2014-03-02 23:00:40 +00:00
Vorbereitung
- ssh-add -d # SSH-Schlüssel löschen
- vagrant up node0.lctp
- vagrant up node1.lctp
- vagrant up node2.lctp --no-provision
- vagrant provision node2.lctp --provision-with shell
2014-02-18 19:10:16 +00:00
Ablauf:
- Headnode: Schon provisioniert
2014-03-02 23:00:40 +00:00
node0:
- vagrant ssh node0.lctp
- ip a
2014-03-04 12:04:01 +00:00
- service isc-dhcp-server statu
2014-03-02 23:00:40 +00:00
- ntpq -p
- dig node0.lctp @localhost
2014-02-18 19:10:16 +00:00
- 1. Computenode: provisioniert
2014-03-02 23:00:40 +00:00
node0:
- vagrant ssh node1.lctp
- ip a
- ip route
- ntpq -p
2014-02-18 19:10:16 +00:00
- 2. Computenode: neu provisionieren
2014-03-02 23:00:40 +00:00
- auskommentieren
- vagrant up node2.lctp
- vagrant: Entwicklungsumgebung mit der gleichen Konfiguration wie Production
einrichten
- besonderheiten chef-solo/chef-server
- minitests zeigen
- Fehlermeldung -> vagrant
- ntpq -p
- mtr 8.8.8.8
2014-02-18 19:10:16 +00:00
- Headnode verkonfigurieren -> erneutes Provisioning
2014-03-02 23:00:40 +00:00
node0:
- sudo iptables -L -t na
- sudo iptables -F -t na
- sudo iptables -L -t na
node2: ping 8.8.8.8 # laufen lassen
node0:
- sudo vi /etc/ntp.conf # server de -> us
- sudo service bind9 stop
- vagrant provision node0.lctp # wechseln zu node2
2014-02-18 19:10:16 +00:00
- Fragen?