Aujourd'hui, nous parlerons de ce qu'est le SCM et raconterons quelques histoires à travers le prisme dont nous considérerons Ansible, SaltStack, Chef et Puppet, en choisissant la meilleure option pour une tâche spécifique.
Le matériel est basé sur la transcription d'un
rapport d'Andrei Filatov , ingénieur système en chef chez EPAM Systems, de notre conférence d'octobre DevOops 2017.
Qu'est-ce que le SCM et avec quoi mange-t-il?

Qu'est-ce que le SCM? Tout d'abord, c'est une chose qui permet à notre infrastructure de l'état A d'exécuter l'état B en exécutant du code. De nombreux développeurs qui ne sont pas des ingénieurs DevOps dans la pratique pensent que quelque chose se passe d'une manière «automatique». sur les infrastructures.
La méthode "automatique" nous implémente SCM (System Configuration Management). À quoi ça sert? Principalement pour construire des infrastructures reproductibles et cohérentes. SCM étend bien les processus CI / CD. Puisqu'il s'agit de code, il peut être stocké dans n'importe quel système de contrôle de version: Git, Mercurial. Il est assez simple à développer et à maintenir.
La dernière est un cycle d'automatisation fermé: tout peut être fait automatiquement, de la création de l'infrastructure au déploiement et au déploiement du code.
Qu'est-ce que SCM: Ansible

Considérez nos candidats. Le premier est Ansible. Il a une architecture sans agent, si nous parlons d'une version open source, il est écrit en Python, il a une DSL de type Yaml, il est facilement extensible grâce aux modules écrits en Python, il est très simple et léger. Ansible a le seuil d'entrée le plus bas - vous pouvez enseigner à n'importe qui.
Il y a de l'expérience lorsqu'une personne, ne connaissant pas Python, ne connaissant rien au SCM, est entrée dans Ansible en seulement deux jours et a déjà commencé à faire quelque chose.
Ci-dessous, un exemple de ChatOps: un notifiant dans Slack. Le code Ansible qui a vu Yaml n'a rien de nouveau.
- 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
Qu'est-ce que SCM: Chef

Chef est une architecture client-serveur, il y a un serveur Chef et un client Chef. La configuration basée sur la recherche, écrite en Ruby, a Ruby DSL. Par conséquent, dans vos livres de recettes et recettes, vous pouvez utiliser toute la puissance de Ruby, mais je ne vous conseille pas de le faire. Chef possède une énorme communauté et le plus grand ensemble d'outils parmi tous les SCM. Voici à quoi ressemble le code Chef, c'est le déploiement de Jetty.
Qu'est-ce que SCM: SaltStack

SaltStack possède à la fois une architecture sans agent qui fonctionne en mode push avec Salt-SSH et une architecture client-serveur lorsqu'il y a Salt-master et Salt-minion. L'accent est mis sur l'automatisation en temps réel, l'exécution parallèle prête à l'emploi de tous les processus et écrite en Python. Également un langage de type Yaml, le code est très similaire à Ansible.
#ntp-packages: pkg.installed: - pkgs: - ntp - ntpdate #/etc/ntp.conf: file: - managed - source: salt:
Qu'est-ce que SCM: Puppet

Le dernier de nos soumissionnaires est Puppet. Il a également une architecture client-serveur, comme Chef, la configuration n'est pas basée sur la recherche, mais sur les "faits" qui viennent avec le Puppet-master, écrit en Ruby, a un DSL de type Ruby. Mais les gars de Puppet ne sont pas autorisés à utiliser du code Ruby pur dans leurs manifestes. C'est à la fois un plus et un moins. Voici à quoi ressemble le code manifeste Puppet:
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 en pratique
SaltStack dans un environnement démilitarisé
Tout d'abord, je voudrais partager un projet qui a été écrit sur SaltStack. C'est notre projet précédent et la douleur la plus fraîche, et la douleur la plus fraîche est toujours la plus douloureuse. Notre client est engagé dans le stockage de données - c'est la production de serveurs de fer pour stocker des données sur GPFS, GlusterFS, mais des constructions personnalisées. Il nous a confié les tâches suivantes:
- Création d'un programme d'installation USB / DVD. Vous devez créer un support à partir duquel tout est installé. Cela se fait pour les clients clients qui vivent dans des zones fermées, où les serveurs n'ont généralement pas Internet. Nous devons emballer dans un ISO, envoyer aux ingénieurs de terrain qui déploieront tout le nécessaire sur site.
- Déployez un cluster de produits. Les clients ont plusieurs gros produits, il faut pouvoir les déployer en mode cluster.
- Gestion, configuration et maintenance du cluster à l'aide de l'utilitaire CLI. Notre cadre devrait aider les ingénieurs de terrain à gérer le cluster.
Le client avait plusieurs exigences. Tout d'abord, il possède une énorme expertise Python, en fait uniquement des développeurs C et Python. Le client a immédiatement déclaré: «Nous voulons SaltStack», ne laissant aucun choix.
À quoi sommes-nous confrontés? Le client a plusieurs produits dans l'installation, tous doivent être avec Salt-Masters. Mais nous sommes confrontés au problème de la mise à l'échelle de la configuration Multi-Master. Par exemple, dans NODE Info (le statut d'un serveur spécifique), nous avons sélectionné des millisecondes avec une configuration à deux maîtres, des secondes avec trois maîtres et avec cinq, nous n'avons jamais attendu la fin de l'opération. MultiMaster est une bonne fonctionnalité, mais il ne s'adapte pas bien.
Le deuxième problème que nous avons rencontré était le travail d'équipe: SaltStack a Runner et Module. Le module est une extension qui fonctionne sur Salt Minion, côté machine. Runner s'exécute côté serveur. Nous avons souvent eu des batailles: que faire Runner et que faire des modules.
Ensuite, nous sommes tombés sur une petite surprise de 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:
Nous avons un utilitaire qui est écrit en C. Nous l'exécutons, il génère un ID aléatoire. Il doit être unique parmi tous les participants du cluster, respectivement, nous devons le faire une fois sur le maître, puis le répartir entre les machines. Nous avons utilisé cache.mine pour cela. En fait, il ne connaît pas de redémarrage.

"Condition de course." La parallélisation est bonne, mais dans la configuration de base, state.orchestrate entre dans state.sls s'exécute si de longs processus se produisent. À l'expiration du délai, il estime que l'État est déjà terminé, bien qu'il soit toujours en cours d'exécution, et essaie de démarrer le suivant. Une erreur se produit. Et ce problème n'est pas encore résolu.

Vous pouvez
regarder GitHub .
Que pourrions-nous utiliser en plus de SaltStack?
SaltStack dans un environnement DMZ

- DMZ Le chef est super, Puppet aussi. Et avec Ansible, le problème est - s'il n'y a pas de tour - il n'y a aucun moyen de démarrer la configuration en mode Pull à partir de nos nœuds, ce qui doit être fait dans la zone démilitarisée.
- Framework pour CLI (en Python). Chef et Puppet ne conviennent pas très bien, mais si vous n'avez aucune restriction pour utiliser uniquement Python, vous pouvez écrire en Ruby et utiliser les API Chef ou Puppet. La boîte à outils Ansible ne prend pas en charge cela.
- Gestion des clusters. Chef est bien adapté à la gestion des clusters, Puppet aussi, et Ansible a été initialement écrit pour gérer les clusters sur Amazon.
Chef dans un environnement vaste et dynamique
Le client a eu pour tâche de consolider toutes les ressources dans un seul cloud - c'était Openstack. Avant cela, tout était dispersé: quelque chose sur le Rackspace Cloud, quelque chose sur des serveurs dédiés ou leurs centres de données privés.
Ils souhaitaient une gestion des ressources entièrement dynamique, et aussi pour que leurs applications puissent s'ajouter de la capacité si nécessaire. Autrement dit, nous avons besoin d'une infrastructure dynamique complète et d'un environnement entièrement dynamique de haut en bas.
Pour construire correctement le processus du CD, vous avez besoin d'un environnement entièrement automatisé. Nous avons créé SDLC - Software Development Lifecycle pour eux, et l'avons appliqué, y compris pour SCM. Ils passent des tests d'intégration non seulement des applications, mais aussi des infrastructures.
En conséquence, lorsque quelque chose ne va pas chez nous, nous, comme les gars de Netflix, devrions être capables de tuer les ressources défectueuses et de restaurer les travailleurs frais et garantis à leur place.
Quels problèmes avons-nous rencontrés:
- C'était en 2013, utilisé Chef 10, dans lequel une recherche lente. Nous avons commencé la recherche, faisant le tour de toutes les voitures, et cela a pris une éternité. Nous avons essayé de résoudre le problème avec la convention de dénomination, ainsi que la sélection et la recherche de fqdn. Cela a réduit la portée de la recherche, raison pour laquelle elle a été accélérée.
Mais certaines opérations doivent être effectuées sur l'ensemble de l'environnement. En conséquence, la recherche a été exécutée une fois au tout début, le résultat a été stocké dans l'attribut et à l'aide de Ruby, nous avons filtré les résultats: nous avons analysé les éléments dont nous avions besoin et fait ce qui était nécessaire.
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
Conclusion: utilisez les conventions de dénomination, exécutez la recherche une fois, utilisez Ruby pour filtrer les résultats souhaités.
- L'utilisation de "node.save" n'est pas sûre, soyez prudent et prudent. Nous avons rencontré ce problème lors du déploiement de clusters MySQL et utilisé node.save dans la recette sur un nœud MySQL incomplètement configuré. Et au moment de la mise à l'échelle, certaines applications ont donné une erreur de 500. Il s'est avéré que nous sauvegardions le nœud au mauvais moment: il va au serveur Chef, là, le client Chef sur l'interface utilisateur récupère un nouveau nœud qui n'a pas été configuré avant le mode de fonctionnement.
- Le manque de "splay" peut tuer le serveur du chef. Splay est un paramètre client Chef qui vous permet de définir la plage lorsque le client se rend sur le serveur pour configuration. Avec une charge élevée, lorsque vous devez déployer plusieurs nœuds en même temps, cela ne tuera pas le serveur.
Que pouvons-nous utiliser à la place du chef?

- Provisionnement dynamique SaltStack est parfait car il a SaltCloud qui s'intègre parfaitement n'importe où. Puppet a des fonctionnalités similaires, mais il n'est disponible que dans Puppet Enterprise, pour de l'argent. Ansible est bien adapté si l'entreprise "vit" en Amazonie, sinon autre chose - vous pouvez l'associer à des alternatives, mais ce n'est pas si pratique.
- SDLC. Chef a tout, de la cuisine de test au choix des outils pour les tests d'intégration. SaltStack a tous les outils Python disponibles, maintenant Puppet a tout. Ansible a une spécification de rôle, vous pouvez utiliser la cuisine de test du chef, mais ce n'est pas un outil natif.
- Remplacement des ressources. Tout va bien dans Chef, dans SaltStack vous pouvez terminer SaltCloud à l'état souhaité, dans Puppet, les outils ne sont que dans la version Enterprise, et Ansible ne fonctionne bien qu'avec Amazon.
EPAM Private Cloud avec Chef
Un an et demi avant l'avènement d'AWS OpsWorks, nous voulions créer une Amazon CloudFormation avancée en intégrant Chef afin que les ressources soient non seulement déployées, mais également configurées.
La deuxième tâche globale consiste à créer un catalogue de services afin que les clients et les utilisateurs puissent utiliser la CLI pour déployer une pile LAMP complètement prête à l'emploi, par exemple.

Nous avons choisi Chef, mais le projet devait prendre en charge différents SCM. Nous avons commencé avec le Chef-Server intégré, et les utilisateurs pouvaient également utiliser leur propre Chef-Server, qui est hébergé quelque part avec eux. Autrement dit, nous n'avons pas eu accès aux ressources utilisateur et aux ordinateurs portables, mais cela a quand même fonctionné.

Tout SCM peut être utilisé pour implémenter CloudFormation + OpsWork, tout le monde convient. Pour créer un catalogue - tout le monde sauf SaltStack le fera bien. SaltStack a ses nuances: il est extrêmement difficile de trouver un spécialiste connaissant bien SaltStack et pouvant créer un service et remplir le catalogue.
La popularité de SCM dans EPAM

Ce sont des statistiques de popularité de SCM au sein d'EPAM. SaltStack est très loin derrière. En premier lieu Ansible, c'est la plus simple et avec un seuil d'entrée bas. Lorsque nous essayons de trouver quelqu'un sur le marché connaissant la SCM, le marché est à peu près le même.
Travailler avec Ansible
Conseils que je peux donner lorsque je travaille avec Ansible:
- Utilisez 'accélérer', il déploie des configurations 2 à 6 fois plus rapidement que SSH (pour el6). Pour tout le monde, il y a du «pipelining». Il est désactivé pour des raisons de compatibilité descendante, mais réactiver le pipelining est très facile, je recommande de le faire.
- Utilisez '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
Dans cet exemple, nous installons des packages, ce schéma peut être utilisé pour créer des utilisateurs et des opérations similaires.
- Utilisez soigneusement «local_action» et «delegated». Le premier vous permet d'obtenir quelque chose de similaire au SaltStack Runner, le second est capable de déléguer des tâches à des machines spécifiques.
- 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}}"
Il s'agit d'une création de base de données. Sans la dernière ligne, l'opération serait effectuée plusieurs fois et tomberait à la deuxième tentative de création de la même base de données.
- Optimisez vos rôles et performances avec des balises. Cela peut réduire considérablement le délai de livraison.
Conclusions
Pour moi, Ansible est un favori. SaltStack est très bon, très flexible, mais nécessite des connaissances en Python, sans eux SaltStack est préférable de ne pas l'utiliser. Chef est une solution miracle universelle pour toutes les tâches et toutes les échelles, mais nécessite plus de connaissances qu'Ansible. Et qui utilise Puppet - je ne sais pas. En principe, il est très similaire à Chef, mais avec ses propres nuances.
Minute de publicité. Si vous avez aimé ce rapport de la conférence DevOops - notez que le 14 octobre, le nouveau DevOops 2018 se tiendra à Saint-Pétersbourg, il y aura beaucoup de choses intéressantes dans son programme. Le site a déjà les premiers intervenants et rapports.