Heute werden wir darüber sprechen, was SCM ist, und einige Geschichten erzählen, durch deren Prisma wir Ansible, SaltStack, Chef und Puppet betrachten und die beste Option für eine bestimmte Aufgabe auswählen.
Das Material basiert auf einer Abschrift eines
Berichts von Andrei Filatov , leitender Systemingenieur bei EPAM Systems, von unserer DevOops 2017-Konferenz im Oktober.
Was ist SCM und womit isst es?

Was ist SCM? Erstens ist es eine Sache, die es unserer Infrastruktur von Zustand A aus ermöglicht, Zustand B durch Ausführen einer Art Code auszuführen. Viele Entwickler, die in der Praxis keine DevOps-Ingenieure sind, glauben, dass etwas auf eine „automatische“ Weise geschieht auf die Infrastruktur.
Die "automatische" Methode implementiert uns SCM (System Configuration Management). Wofür ist das? In erster Linie, um wiederholbare und konsistente Infrastrukturen aufzubauen. SCM erweitert CI / CD-Prozesse gut. Da dies Code ist, kann er in jedem Versionskontrollsystem gespeichert werden: Git, Mercurial. Es ist ganz einfach zu entwickeln und zu warten.
Das letzte ist ein geschlossener Automatisierungszyklus: Alles kann automatisch erledigt werden, von der Erstellung der Infrastruktur über die Bereitstellung bis hin zur Bereitstellung des Codes.
Was ist SCM: Ansible

Betrachten Sie unsere Bewerber. Der erste ist Ansible. Es hat eine agentenlose Architektur, wenn es sich um eine Open-Source-Version handelt, es ist in Python geschrieben, es hat ein Yaml-ähnliches DSL, es ist aufgrund der in Python geschriebenen Module leicht erweiterbar, es ist sehr einfach und leicht. Ansible hat die niedrigste Einstiegsschwelle - Sie können jeden unterrichten.
Es gibt Erfahrung, als eine Person, die Python nicht kannte und nichts über SCM wusste, in nur zwei Tagen Ansible betrat und bereits anfing, etwas zu tun.
Unten sehen Sie ein Beispiel für ChatOps: einen Notifier in Slack. Der Ansible-Code, der Yaml gesehen hat, ist nichts Neues.
- block: - name: "SlackNotify : Deploy Start" local_action: module: slack token: "{{ slack_url }}" attachments: - title: "Deploy to {{ inventory_hostname }} has been Started" text: "<!here> :point_up_2:" color: "#551a8b" - include: configure.yml tags: - configure - include: remote-fetch.yml tags: - remote - include: assets.yml
Was ist SCM: Chef

Chef ist eine Client-Server-Architektur, es gibt einen Chef-Server und einen Chef-Client. Die in Ruby geschriebene suchbasierte Konfiguration verfügt über Ruby DSL. Dementsprechend können Sie in Ihren Kochbüchern und Rezepten die volle Leistung von Ruby nutzen, aber ich rate nicht dazu. Chefkoch hat eine riesige Community und die größte Auswahl an Tools unter allen SCMs. So sieht Chef-Code aus, dies ist Jetty-Bereitstellung.
Was ist SCM: SaltStack

SaltStack verfügt sowohl über eine agentenlose Architektur, die im Push-Modus mit Salt-SSH arbeitet, als auch über eine Client-Server-Architektur, wenn Salt-Master und Salt-Minion vorhanden sind. Der Schwerpunkt liegt auf der Echtzeitautomatisierung, der sofortigen parallelen Ausführung aller Prozesse und der in Python geschriebenen. Der Code ist ebenfalls eine Yaml-ähnliche Sprache und Ansible sehr ähnlich.
#ntp-packages: pkg.installed: - pkgs: - ntp - ntpdate #/etc/ntp.conf: file: - managed - source: salt:
Was ist SCM: Marionette

Der letzte unserer Bieter ist Puppet. Es hat auch eine Client-Server-Architektur, wie Chef, die Konfiguration basiert nicht auf der Suche, sondern auf den "Fakten", die mit dem in Ruby geschriebenen Puppet-Master kommen, hat ein Ruby-ähnliches DSL. Aber die Puppet-Jungs dürfen in ihren Manifesten keinen reinen Ruby-Code verwenden. Dies ist sowohl ein Plus als auch ein Minus. So sieht der Puppet-Manifestcode aus:
class { 'mysql::server' : root_password => 'password' } mysql::db{ ['test', 'test2', 'test3']: ensure => present, charset => 'utf8', require => Class['mysql::server'], } mysql::db{ 'test4': ensure => present, charset => 'latin1', } mysql::db{ 'test5': ensure => present, charset => 'binary', collate => 'binary', }
SCM in der Praxis
SaltStack in einer entmilitarisierten Umgebung
Zunächst möchte ich ein Projekt teilen, das auf SaltStack geschrieben wurde. Dies ist unser vorheriges Projekt und der frischeste Schmerz, und der frischeste Schmerz ist immer der schmerzhafteste. Unser Kunde beschäftigt sich mit Datenspeicherung - dies ist die Herstellung von Eisenservern zum Speichern von Daten auf GPFS, GlusterFS, aber kundenspezifischen Builds. Er kam mit folgenden Aufgaben zu uns:
- Erstellen eines USB / DVD-Installationsprogramms. Sie müssen ein Medium erstellen, auf dem alles installiert ist. Dies geschieht für Kunden, die in geschlossenen Räumen leben, in denen die Server meist nicht über das Internet verfügen. Wir müssen eine ISO einpacken und an Außendiensttechniker senden, die alles Notwendige vor Ort bereitstellen.
- Stellen Sie einen Produktcluster bereit. Kunden haben mehrere große Produkte. Wir müssen sie im Cluster-Modus bereitstellen können.
- Verwaltung, Konfiguration und Wartung des Clusters mit dem CLI-Dienstprogramm. Unser Framework soll Außendiensttechnikern bei der Verwaltung des Clusters helfen.
Der Kunde hatte mehrere Anforderungen. Erstens verfügt er über eine große Menge an Python-Fachwissen, in der Tat nur C- und Python-Entwickler. Der Kunde sagte sofort: „Wir wollen SaltStack“ und ließ keine Wahl.
Was stehen wir vor? Der Kunde hat mehrere Produkte in der Installation, alle müssen mit Salt-Masters sein. Wir stehen jedoch vor dem Problem, die Multi-Master-Konfiguration zu skalieren. In NODE Info (dem Status eines bestimmten Servers) haben wir beispielsweise Millisekunden mit einer Zwei-Master-Konfiguration ausgewählt, Sekunden mit drei Mastern und mit fünf haben wir nie auf den Abschluss des Vorgangs gewartet. MultiMaster ist eine gute Funktion, lässt sich aber nicht gut skalieren.
Das zweite Problem war die Teamarbeit: SaltStack verfügt über Runner und Module. Das Modul ist eine Erweiterung, die maschinenseitig auf Salt Minion ausgeführt wird. Runner wird auf der Serverseite ausgeführt. Wir hatten oft Schlachten: Was tun Runner und was tun Module?
Dann stießen wir auf eine kleine Überraschung von cache.mine:
ime = ImeActions() id = __grains__['id'] if id == ime.master_id: ret = __salt__['mine.get'](id, 'ime_actions.make_bfs_uuid') ime_dict = ret.get(id, None) if not ime_dict: try: result = __salt__['mine.send']('ime_actions.make_bfs_uuid') except Exeption, e: log.error("Failed to generate uuid: {0}.".format(str(e))) result = False else:
Wir haben ein Dienstprogramm, das in C geschrieben ist. Wir führen es aus, es generiert eine zufällige ID. Es muss unter allen Teilnehmern des Clusters eindeutig sein. Wir müssen dies einmal auf dem Master tun und es dann auf die Maschinen verteilen. Wir haben dafür cache.mine verwendet. Wie sich herausstellte, wird kein Neustart durchgeführt.

"Rennzustand." Die Parallelisierung ist gut, aber in der Grundkonfiguration wird state.orchestrate in state.sls ausgeführt, wenn lange Prozesse auftreten. Bis zum Timeout glaubt er, dass der Staat bereits abgeschlossen ist, obwohl er noch läuft, und versucht, den nächsten zu starten. Ein Fehler tritt auf. Und dieses Problem wurde noch nicht behoben.

Sie können
sich GitHub ansehen .
Was könnten wir außer SaltStack verwenden?
SaltStack in einer DMZ-Umgebung

- DMZ Chefkoch packt großartig, Puppet auch. Und bei Ansible besteht das Problem darin, dass es - wenn kein Tower vorhanden ist - keine Möglichkeit gibt, die Konfiguration im Pull-Modus von unseren Knoten aus zu starten, was in der entmilitarisierten Zone erfolgen muss.
- Framework für CLI (in Python). Chef und Puppet sind nicht sehr gut geeignet. Wenn Sie jedoch keine Einschränkungen haben, nur Python zu verwenden, können Sie in Ruby schreiben und die Chef- oder Puppet-APIs verwenden. Ansible Toolkit unterstützt dies nicht.
- Clusterverwaltung. Chef eignet sich gut für die Verwaltung von Clustern, auch für Puppet, und Ansible wurde ursprünglich für die Verwaltung von Clustern bei Amazon entwickelt.
Koch in einer großen und dynamischen Umgebung
Der Kunde hatte die Aufgabe, alle Ressourcen in einer Cloud zu konsolidieren - es war Openstack. Davor war alles verstreut: etwas in der Rackspace Cloud, etwas auf dedizierten Servern oder deren privaten Rechenzentren.
Sie wollten ein vollständig dynamisches Ressourcenmanagement und auch, damit ihre Anwendungen sich bei Bedarf selbst Kapazität hinzufügen können. Das heißt, wir brauchen eine vollständige dynamische Infrastruktur und eine vollständig dynamische Umgebung auf und ab.
Um den CD-Prozess ordnungsgemäß zu erstellen, benötigen Sie eine vollautomatisierte Umgebung. Wir haben für sie SDLC - Software Development Lifecycle erstellt und angewendet, auch für SCM. Sie bestehen Integrationstests nicht nur für Anwendungen, sondern auch für die Infrastruktur.
Dementsprechend sollten wir, wie die Leute von Netflix, in der Lage sein, defekte Ressourcen zu töten und frische und garantierte Arbeiter an ihren Platz zurückzubringen, wenn etwas mit uns schief geht.
Auf welche Probleme sind wir gestoßen:
- Es war 2013, Chef 10 verwendet, in dem eine langsame Suche. Wir begannen mit der Suche, gingen um alle Autos herum und es dauerte ewig. Wir haben versucht, das Problem mit der Namenskonvention sowie der Auswahl und Suche nach fqdn zu lösen. Dies verengte den Umfang der Suche, wodurch sie beschleunigt wurde.
Einige Operationen müssen jedoch für die gesamte Umgebung durchgeführt werden. Dementsprechend wurde die Suche zu Beginn einmal ausgeführt, das Ergebnis im Attribut gespeichert und mit Ruby die Ergebnisse gefiltert: Wir haben die benötigten Teile analysiert und das getan, was benötigt wurde.
if !Chef::Config[:solo] search(:node, "fqdn:*metro-#{node[:env]}-mongodb*").each do |mongo| @mongodbs << mongo.fqdn end else @mongodbs = ["lvs-metro-#{node[:env]}-mongodb3001.qa.example.com"] end
Fazit: Verwenden Sie Namenskonventionen, führen Sie die Suche einmal aus und filtern Sie die gewünschten Ergebnisse mit Ruby.
- Die Verwendung von "node.save" ist unsicher. Seien Sie vorsichtig und vorsichtig. Dieses Problem trat beim Bereitstellen von MySQL-Clustern auf und verwendete node.save innerhalb des Rezepts auf einem unvollständig konfigurierten MySQL-Knoten. Zum Zeitpunkt des Scale-up gaben einige Anwendungen einen Fehler von 500 an. Es stellte sich heraus, dass wir den Knoten zur falschen Zeit gespeichert haben: Er geht zum Chef-Server, genau dort nimmt der Chef-Client auf der Benutzeroberfläche einen neuen Knoten auf, der nicht vor dem Betriebsmodus konfiguriert wurde.
- Das Fehlen von "Spreizung" kann den Server des Küchenchefs töten. Splay ist ein Chef-Client-Parameter, mit dem Sie den Bereich festlegen können, wenn der Client zur Konfiguration zum Server wechselt. Wenn Sie bei hoher Last viele Knoten gleichzeitig bereitstellen müssen, wird der Server nicht zerstört.
Was können wir anstelle des Küchenchefs verwenden?

- Dynamische Bereitstellung SaltStack ist perfekt, weil es SaltCloud hat, das sich überall perfekt integrieren lässt. Puppet hat ähnliche Funktionen, ist jedoch nur in Puppet Enterprise für Geld erhältlich. Ansible ist gut geeignet, wenn das Unternehmen in Amazon "lebt", wenn etwas anderes - Sie können es in Alternativen einbinden, aber es ist nicht so bequem.
- SDLC. Chefkoch hat alles von Test Kitchen bis zur Auswahl von Tools für Integrationstests. SaltStack verfügt über alle Python-Tools, jetzt hat Puppet alles. Ansible hat eine Rollenspezifikation. Sie können Chef's Test Kitchen verwenden, aber es ist kein natives Tool.
- Ressourcenersatz. In Chef ist alles in Ordnung, in SaltStack können Sie SaltCloud bis zum gewünschten Status beenden, in Puppet-Tools nur in der Enterprise-Version und Ansible funktioniert nur mit Amazon.
EPAM Private Cloud mit Küchenchef
Eineinhalb Jahre vor dem Aufkommen von AWS OpsWorks wollten wir durch die Integration von Chef eine erweiterte Amazon CloudFormation erstellen, damit Ressourcen nicht nur bereitgestellt, sondern auch konfiguriert werden.
Die zweite globale Aufgabe besteht darin, einen Servicekatalog zu erstellen, damit Kunden und Benutzer die CLI verwenden können, um beispielsweise einen vollständig gebrauchsfertigen LAMP-Stack bereitzustellen.

Wir haben uns für Chef entschieden, aber das Projekt musste verschiedene SCMs unterstützen. Wir haben mit dem eingebauten Chef-Server begonnen, und Benutzer können auch ihren eigenen Chef-Server verwenden, der irgendwo bei ihnen gehostet wird. Das heißt, wir haben keinen Zugriff auf Benutzerressourcen und Laptops erhalten, aber es hat trotzdem funktioniert.

Mit jedem SCM kann CloudFormation + OpsWork implementiert werden. Jeder ist geeignet. So erstellen Sie einen Katalog: Alle außer SaltStack tun dies gut. SaltStack hat seine Nuancen: Es ist äußerst schwierig, einen Spezialisten zu finden, der SaltStack gut kennt und einen Service erstellen und den Katalog füllen kann.
Die Popularität von SCM in EPAM

Dies sind Statistiken zur SCM-Popularität innerhalb von EPAM. SaltStack liegt sehr weit zurück. Erstens ist Ansible das einfachste und mit einer niedrigen Eintrittsschwelle. Wenn wir versuchen, jemanden auf dem Markt mit SCM-Kenntnissen zu finden, sieht der Markt ungefähr gleich aus.
Arbeite mit Ansible
Tipps, die ich bei der Arbeit mit Ansible geben kann:
- Verwenden Sie 'Beschleunigen', um Konfigurationen 2-6 mal schneller als SSH (für el6) bereitzustellen. Für alle anderen gibt es "Pipelining". Es ist aus Gründen der Abwärtskompatibilität ausgeschaltet, aber das Wiedereinschalten des Pipelining ist sehr einfach. Ich empfehle es.
- Verwenden Sie 'with_items'
- name: project apt dependencies installed apt: name: "{{ item }}" become: yes with_items: - build-essential - acl - git - curl - gnupg2 - libpcre3-dev - python-apt - python-pycurl - python-boto - imagemagick - libmysqlclient-dev
In diesem Beispiel installieren wir Pakete. Mit diesem Schema können Benutzer und ähnliche Vorgänge erstellt werden.
- Verwenden Sie vorsichtig 'local_action' und 'delegated'. Mit dem ersten können Sie etwas Ähnliches wie mit dem SaltStack Runner erhalten, mit dem zweiten können Sie Aufgaben an bestimmte Computer delegieren.
- name: create postgresql database postgresql_db: name: "{{ database_name }}" login_host: "{{ database_host }}" login_user: "{{ database_master_user }}" login_password: "{{ database_master_password }}" encoding: "UTF-8" lc_collate: "en_US.UTF-8" lc_ctype: "en_US.UTF-8" template: "template0" state: present delegate_to: "{{ groups.pg_servers|random}}"
Dies ist ein Teil der Datenbankerstellung. Ohne die letzte Zeile würde die Operation mehrmals ausgeführt und fiel beim zweiten Versuch, dieselbe Datenbank zu erstellen.
- Optimieren Sie Ihre Rollen und Leistung mit Tags. Dies kann die Vorlaufzeit erheblich verkürzen.
Schlussfolgerungen
Ansible ist für mich ein Favorit. SaltStack ist sehr gut, sehr flexibel, erfordert jedoch Python-Kenntnisse. Ohne sie ist SaltStack besser nicht zu verwenden. Chefkoch ist eine universelle Silberkugel für jede Aufgabe und jeden Maßstab, erfordert jedoch mehr Wissen als Ansible. Und wer Puppet benutzt - weiß ich nicht. Im Prinzip ist es dem Chef sehr ähnlich, aber mit seinen eigenen Nuancen.
Minute der Werbung. Wenn Ihnen dieser Bericht von der DevOops- Konferenz gefallen hat , beachten Sie, dass am 14. Oktober die neuen DevOops 2018 in St. Petersburg stattfinden werden. Das Programm enthält viele interessante Dinge. Die Seite hat bereits die ersten Redner und Berichte.