Affichage des articles dont le libellé est json. Afficher tous les articles
Affichage des articles dont le libellé est json. Afficher tous les articles

mardi 10 mars 2015

Activation du cache Ansible par fichier JSON

Lorsque vous lancez Ansible, vous avez déjà dû remarquer que le démarrage peut prendre un certain temps : il s'agit de la phase de récupération des informations sur la machine. Ceci se manifeste au début du lancement d'un playbook sous la forme suivante :

GATHERING FACTS ******************************************* 
ok: [localhost]

Pendant cette phase, Ansible va collecter tout un tas d'indicateur qui vont caractériser votre machine. On va y retrouver pêle-mêle le type de processeur, les disques de la machine, les adresses IP etc. Seul petit problème cette phase prend quelques secondes (voir plus certaines fois) et peut devenir vite agaçante dans le cas où vous mettez au point vos procédures d'installation.

Heureusement, les petits gars d'Ansible ont introduit un petit mécanisme de cache de ces éléments (des facts dans le jargon Ansiblien). Vous pouvez effectivement stocker ça dans un serveur redis.

Comme je n'ai pas trop l'habitude d'utiliser redis et que je n'avais pas envie de passer du temps à faire l'installation de ce nouvel élément sur mon poste perso, je me suis posé la question s'il ne serait pas possible d'utiliser quelque chose de plus simple ... Et la réponse est oui, avec des fichiers au format JSON.

Activation du cache via fichier JSON

Ouvrons notre fichier /etc/ansible/ansible.cfg et allons modifier la valeur du paramètre gathering pour le passer à la valeur smart :

# smart - gather by default, but don't regather if already gathered
# implicit - gather by default, turn off with gather_facts: False
# explicit - do not gather by default, must say gather_facts: True
gathering = smart

Si vous lancez maintenant Ansible, vous ne verrez pas trop de différence. Ce paramètre peut néanmoins être avantageux si vous lancez plusieurs rôles sur les mêmes machines. Dans ce cas, Ansible ne récupérera les caractéristiques de vos machines qu'une seule fois.

Allons un peu plus loin et modifions maintenant les valeurs de fact_caching :

# if set to a persistant type (not 'memory', for example 'redis') fact values
# from previous runs in Ansible will be stored.  This may be useful when
# wanting to use, for example, IP information from one group of servers
# without having to talk to them in the same playbook run to get their
# current IP information.
# fact_caching = memory
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible

Nous avons activé le stockage des fichiers d'inventaire dans le répertoire /tmp/ansible. Chaque serveur verra ses caractéristiques stockées au format JSON.

A noter l'existence d'un paramètre fact_caching_timeout qui vous permettra de contrôler la fraîcheur de vos inventaires.

Différence de vitesse d'exécution dû au cache

Voyons maintenant l'impact des performances avec le test tout simple suivant :

---
# Playbook de test

- name: "Test"
  hosts: "localhost"
  tasks:
    - debug: msg=Lancement réussi

On ne fait qu'afficher un message. Ansible procédera néanmoins à la phase d'inventaire ce qui nous permettra de mesurer ce temps.

Premier lancement

Lançons une première fois notre playbook à froid :

$ time ansible-playbook test.yml 

PLAY [Test] ************************************************* 

GATHERING FACTS ********************************************* 
ok: [localhost]

TASK: [debug msg=Lancement réussi] ************************** 
ok: [localhost] => {
    "msg": "Lancement"
}

PLAY RECAP ************************************************** 
localhost    : ok=2    changed=0    unreachable=0    failed=0   


real    0m2.300s
user    0m1.531s
sys     0m0.708s

Un coup d'oeil dans le répertoire /tmp/ansible :

$ ls /tmp/ansible/
localhost

Ansible a créé un fichier de cache. Un coup d'oeil nous permet de voir qu'il s'agit d'un fichier au format JSON.

Lancement avec cache

Maintenant que nous disposons d'un cache, mesurons à nouveau ce temps d'exécution :

$ time ansible-playbook test.yml 

PLAY [Test] ************************************************* 

TASK: [debug msg=Lancement réussi] ************************** 
ok: [localhost] => {
    "msg": "Lancement"
}

PLAY RECAP ************************************************** 
localhost    : ok=1    changed=0    unreachable=0    failed=0   


real    0m0.303s
user    0m0.242s
sys     0m0.044s

Nous venons de passer de 2,3 secondes à 0,3 seconde soit un gain de 2 secondes.

Pour conclure

Comme nous l'avons vu, le gain n'est pas négligeable (surtout en phase de mise au point) et surtout introduit une notion de persistance de l'information d'une exécution à l'autre. En effet, vous pouvez maintenant récupérer une information venant d'un autre serveur sans pour autant avoir à vous y connecter à chaque fois.

samedi 13 septembre 2014

Installation et présentation de puppetboard

Mais au fait, pourquoi puppetboard ?

Il était une fois un royaume dans lequel les devops étaient roi et n'avaient (presque plus) rien à faire. Passant par là, le développeur opensource du dit produit se dit qu'il fallait réveiller se peuple au bios dormant. C'est ainsi que naquis la notion de PuppetDB (bon OK, y'a d'autres raisons notamment le besoin d'avoir un mécanisme de stockage des faits un peu plus propre que ce qui était fait).

Concernant PuppetDB en lui même - dans les grandes lignes - sachez qu'il s'agit d'une base type NoSQL (notion à la mode) qu'on peut interroger à l'aide de requête de type REST (autre notion à la mode).

Pour la version un peu plus longue, sachez que le premier désigne un mécanisme de stockage d'objet au format JSON (et c'est là où je me rends compte que c'est pas forcément plus clair ...). En gros, c'est comme le SQL sauf qu'il n'y a pas de table et que les requêtes se font en javascript à la place du SQL. Si vous ne savez pas de quoi je parle là non plus, je ne peux plus rien faire pour vous.

Pour les requêtes REST (ou restfull), tout ceci désigne un moyen de faire des appels via l'utilisation de requête HTTP (et que c'est marrant de se rendre compte qu'on avait déjà fait du REST avant le verbe mais je m'égare). En gros, vous voulez la liste des machines, vous faîtes une requête sur l'URL http://localhost/nodes, ce dernier vous renverra alors la liste des nœuds sous la forme d'un hash map (autrement appelé JSON). Bon d'accord, c'est pas très clair. En gros, ça vous renvoie du texte qui devrait ressembler à un truc de ce genre :

{
  "node1": {"address": "192.168.0.1", "macadress": "00:00:01:00:00:01"},
  "node2": {"address": "192.168.0.2", "macadress": "00:00:01:00:00:02"},
}

Ne reste plus qu'à le lire et l'utiliser dans votre interface web, votre script perl etc.

Pour revenir à nos moutons, PuppetDB à donc pour rôle de stocker les informations qu'on va récolter suite aux applications de catalogue sur nos machines. Seul petit hic, le plugin puppet dashboard n'est plus trop compatible avec tout ceci et je me retrouve donc avec un superbe outil de présentation des données puppet vide et, de l'autre côté, une interface en JSON/Restfull absolument inutilisable pour mes utilisateurs (ainsi que moi-même étant donné que je ne lis pas encore le JSON dans le texte).

C'est donc à ce moment que je me suis mis en quête d'une alternative afin de rendre le sourire à mes utilisateurs et moi-même. Après quelques requêtes sur le moteur dont on ne doit pas prononcer le nom, je tombe sur le jeune et prometteur puppetboard (https://github.com/nedap/puppetboard).

Mais assez de blabla, passons maintenant à l'installation de ce merveilleux outils.

Installation

Autant vous le dire tout de suite, si vous voulez installer ce produit, c'est que vous utilisez puppet. Si vous ne voulez pas utiliser puppet pour l'installation, c'est que vous êtes maso. Comme il se trouve qu'en plus, les auteurs ont fait une recette puppet directement récupérable depuis le puppet forge, on ne va pas s'en priver.

En premier lieu, assurez-vous d'avoir déjà les modules puppet apache et puppetboard (puppet module install/list/etc.).

Ouvrez la structure du node puppet correspondant à la machine sur laquelle vous voulez installer le puppetboard et ajoutez-y la recette suivante :

  class { 'apache': }
  class { 'apache::mod::wsgi': }
  # Configure Puppetboard
  class { 'puppetboard':
    manage_virtualenv => true,
    puppetdb_port     => "9090",
    puppetdb_host     => "127.0.0.1",
  }
  # Access Puppetboard through pboard.example.com
  class { 'puppetboard::apache::vhost':
    vhost_name => 'puppetboard',
    port       => 8888,
  }

De là, je vous invite à lancer la commande d'application de votre recette sur la machine puppetboard :

puppet agent -t

Tada ! Vous avez un puppetboard fonctionnel.

Sortez maintenant votre navigateur préféré (firefox, chrome, Internet E nan, j'déconne) et pointez sur l'URL http://puppetboard:8888 (ou ce que votre cerveau malade aura décidé de choisir) et vous devriez obtenir l'interface suivante :
Un petit tour du propriétaire s'impose :
  • Le détail sur un serveur :
  • Consultation du résultat de l'application d'un catalogue sur une machine :
  • Requêtage des faits en base :

Pour finir

Autant le dire tout de suite, l'outil est encore un peu jeune. A noter un petit soucis que j'ai rencontré lors du déploiement : les librairies Javascript sont référencées sur Internet et non sur la machine. Il faut donc un navigateur avec un proxy valide pour que ça fonctionne. Je me fendrai peut-être d'un patch pour corriger ça ...

Autre chose, je n'ai plus mes courbes de tendance sur le temps d'application du catalogue sur mes machines. Argh ! ça va crier ...

Mais bon, en dehors de ça, l'interface est assez réactive et simple à comprendre. Je recommande donc !

dimanche 26 janvier 2014

Installation de razor (ainsi que puppet, postgresql, tftp et dhcp)

Il y a quelques années, j'avais mis en place un serveur d'installation Linux. C'était basé sur le classique dhcp, tftp et kickstart. Un de mes collègues m'a parlé dernièrement d'un projet relativement intéressant : razor. C'est un projet qui est toujours en cours de développement mais est tout à fait utilisable.

Son principe est assez simple : il se base sur des briques classiques pour gérer la partie boot réseau (DHCP + TFTP + kickstart) et utilise un serveur JBoss couplé à postgresql pour la partie gestion de la configuration.

Pour mémoire, l'installation se fera sur une CentOS 6.5 mais devrait s'adapter très facilement sur une autre distribution.

Mais trêve de bavardage, passons à la mise en oeuvre.

Installation et configuration de postgres

Pour faire fonctionner razor, nous allons avoir besoin d'une version très récente de posgresql (la 9.3). Le repository pour RHEL/CentOS contenant cette version de postgres s'installe avec la commande suivante :

yum install http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/pgdg-centos93-9.3-1.noarch.rpm

L'installation de postgresql à proprement parlé se fait ensuite simplement avec yum :

yum install postgresql93-server

De là, il nous faut initialiser le contenu de la base avec la commande suivante :

/etc/init.d/postgresql93 initdb

Ceci fait, nous pouvons démarrer la base :

/etc/init.d/postgresql93 start

Enfin, nous allons créer notre utilisateur ainsi que notre schéma :

psql
create user razor;
create database razor_prd owner razor;
\password razor

Modifier ensuite le fichier /var/lib/pgsql/9.3/data/pg_hba.conf afin de faire apparaître la ligne suivante (vers la fin du fichier) :

local   all         all     127.0.0.1/32        md5

Un arrêt/relance de postgresql plus tard :

/etc/init.d/postgresql restart

Nous voici prêt pour la suite.

Installation de puppet

Par la suite, je m'appuierai énormément sur puppet pour mettre en oeuvre le produit. Je vous invite donc à l'installer avec la série de commandes suivante :

yum install http://yum.puppetlabs.com/puppetlabs-release-el-6.noarch.rpm
yum install puppet

Installation de razor

Le plus simple et de se servir de puppet pour faire le gros du travail. Pour se faire, lançons l'installation du module razor :

puppet module install puppetlabs-razor

Vous devriez voir le résultat suivant si tout se passe bien :

Notice: Preparing to install into /etc/puppet/modules ...
Notice: Downloading from https://forge.puppetlabs.com ...
Notice: Installing -- do not interrupt ...
/etc/puppet/modules
└─┬ puppetlabs-razor (v0.11.0)
  ├─┬ puppetlabs-java (v1.0.1)
  │ └── puppetlabs-stdlib (v4.1.0)
  └─┬ puppetlabs-tftp (v0.2.1)
    └── puppetlabs-xinetd (v1.2.0)

Passons maintenant à l'installation de razor :

export FACTER_server=ADDRESSE_IP_RAZOR
puppet apply -e "include razor"

Au bout d'un petit moment, vous devriez avoir un process Java JBoss pour héberger l'application razor ainsi qu'un serveur tftpboot fonctionnel (ou presque).

Rendez-vous maintenant dans le répertoire /opt/razor afin de recopier le fichier config.yam.sample en config.yaml :

cd /opt/razor
cp config.yaml.sample config.yaml

Adapter ensuite le contenu du fichier config.yaml à votre plateforme et lancer la commande suivante :

razor-admin -e production migrate-database

De là, il ne nous reste plus qu'à installer une version valide du client razor avec la commande suivante :

puppet resource package razor-client provider=gem ensure=latest

Si vous avez un parefeu sur votre machine, il vous faudra ouvrir le port 8080.

Configuration du tftp

Rien de particulier à signaler si ce n'est de bien faire attention d'ouvrir le port udp 69 sur votre parefeu.

Récupération du microkernel

Nous allons déposer le micro kernel dans un sous répertoire de razor (/var/lib/razor/repo-store). Ci-dessous les commandes à lancer pour le faire :

wget http://links.puppetlabs.com/razor-microkernel-003.tar
tar xfv razor-microkernel-003.tar -C /var/lib/razor/repo-store

Configuration du serveur DHCP

Il existe un fichier d'exemple dans le module puppet que vous pouvez récupérer avec la commande suivante :

cp /etc/puppet/modules/razor/examples/isc-dhcpd-example.conf /etc/dhcp/dhcpd.conf

Reste ensuite à adapter le fichier /etc/dhcp/dhcpd.conf et démarrer notre serveur dhcp en s'assurant qu'il soit démarrer au lancement de la machine :

puppet resource service dhcpd ensure=running enable=true

Nous allons pouvoir commencer quelques tests ...

Installation d'une CentOS 6.5

Création d'un broker par défaut

Avec razor, il est possible de faire tout un tas de chose en post installation. Dans notre cas, on va se contenter quelque chose de simple avant d'aller plus loin :

razor create-broker --name=noop --broker-type=noop

Création d'un repository

Nous allons récupérer un repository CentOS. Cette opération se fait avec la commande razor create-repo :

razor create-repo --name centos-6.5 --iso-url=http://.../CentOS-6.5-x86_64-minimal.iso

Nous pouvons ensuite vérifier la présence de notre repository avec la commande razor repos :

# razor repos
From http://192.168.122.3:8080/api/collections/repos:

    id: "http://...:8080/api/collections/repos/centos-6.5"
  name: "centos-6.5"
  spec: "/razor/v1/collections/repos/member"

Ainsi que le détail du repos en ajoutant son nom :

# razor repos centos-6.5
From http://192.168.122.3:8080/api/collections/repos/centos-6.5:

       id: "http://...:8080/api/collections/repos/centos-6.5"
     name: "centos-6.5"
     spec: "/razor/v1/collections/repos/member"
  iso_url: "http://.../CentOS-6.5-x86_64-minimal.iso"

Création d'un tag

Nous allons procéder à la création d'un tag testant si la machine est virtuelle ou non. Pour se faire, alimenter le fichier virtual.json avec le contenu suivant :

# cat virtual.json
{
  "name": "virtual",
  "rule": ["=", ["fact", "is_virtual"], "true"]
}

Donnons ça à manger à razor avec la commande razor create-tag :

# razor create-tag --json virtual.json
From http://192.168.122.3:8080/api:

    id: "http://localhost:8080/api/collections/tags/virtual"
  name: "virtual"
  spec: "/razor/v1/collections/tags/member"

Création d'une policy

Alimentons maintenant le fichier centos-6.5.json avec le contenu suivant :

# cat centos-6.5.json
{
  "name": "centos-6.5",
  "repo": { "name": "centos-6.5" },
  "task": { "name": "centos" },
  "broker": { "name": "noop" },
  "enabled": true,
  "hostname": "host${id}.local",
  "root_password": "ChangezMoi",
  "max_count": "100",
  "rule_number": "100",
  "tags": [{ "name": "virtual"}]
}

Le contenu du fichier va donner un minimum d'information pour l'installation à savoir :
  • Le nom de la police (centos-6.5) ;
  • Le nom du repository (idem) ;
  • Le type de tâche d'installation (ici une CentOS). Pour connaître la liste complète, on peut utiliser la commande razor tasks ;
  • Le type de broker : Il s'agit d'une espèce de post install. Pour l'instant, l'installation s'arrête là ;
  • Enabled : pour savoir si la police est active ou non ;
  • Un template pour le nom de la machine ;
  • Le mot de passe root ;
  • Le nombre max de création et son numéro ;
  • Enfin, les tags sur lesquels cette police s'appliquera (ici virtual).
Donnons ça à manger à notre ami razor avec la commande razor create-policy :

razor create-policy --json centos-6.5.json

Dès que nous démarrerons une machine virtuelle sur notre réseau, cette dernière commencera son installation. Si vous aviez une machine en attente, cette dernière redémarrera et commencera son installation.

Le mot de la fin

Vous l'avez vu, il s'agit vraiment d'une aide pour mettre en oeuvre razor le plus rapidement possible sans forcément chercher à personnaliser les choses.

J'essaierai dans un second temps de revenir avec un nouvel article pour vous présenter le mécanisme permettant de personnaliser vos installations.

A noter que le produit est en pleine refonte et que certaines parties de ce document vont sûrement être amené à évoluer ou devenir un peu obsolète. Je vous laisse ci-dessous une bibliographie m'ayant permis de mettre en oeuvre le produit.

Bon courage et bon déploiement !

Bibliographie

http://technodrone.blogspot.com/2013/11/installing-razor-yes-new-version.html
http://technodrone.blogspot.com/2013/11/installing-razor-client-and-creating.html