Archives de l’auteur : xavki

Débuter avec les commandes dans la CLI Kubernetes

Lors d’un précédent article, nous avions découvert les principes de kubernetes et quelques définitions. Il est temps pour nous de débuter dans les commandes kubernetes.

Si vous le souhaitez, vous pouvez retrouver plus de 70 vidéos gratuites dans cette playlist que je mets à votre disposition. Cette formation kubernetes vous permet de découvrir l’outil tranquillement à votre rythme et de bénéficier du code de chacun des tutos pour reproduire cela de votre côté sur votre laptop.

Premier pod et premier run

La couche logique nommée pod qu’apporte k8s est inévitable lorsque vous utilisez cet orchestrateur. Si vous avez pratiqué docker ou un autre conteneur runtime, imaginez un pod comme une couche supérieure. Cette couche dispose de la description des conteneurs qui vont être lancés et de leur environnement.

Nous le verrons plus tard, les objets k8s sont souvent lancés via des manifests. Ces derniers sont des fichiers descriptifs en format yaml. Mais pour débuter souvent on apprend dans un premier temps à lancer ces éléments à partir de la ligne de commande.

Alors comment lancer le plus simplement du monde un pod dans kubernetes ?

Suivant la version de kub qu evous utilisez vous pourrez réaliser un simple « kubectl run » à la manière d’un docker run de cette manière :

kubectl run mycontainer --image busybox

De cette manière nous venons de lancer un pod qui va lancer un conteneur dont l’image source est une busybox. Alors comme pour un run docker, vous pouvez aussi passer des commandes et par exemple vous connecter à un terminal :

kubectl run anothershell -it --image busybox -- sh

Là nous venons de lancer un pod et nous entrons directement dans le conteneur en question avec un shell à notre disposition. Mais nous pouvons également venir nous connecter à un shell d’un conteneur existant. Pour cela et comme pour docker, nous pouvons lancer un kubectl exec :

kubectl exec -ti <monpod> -- sh

Tout cela est assez facile à retenir si vous avez déjà pratiqué un peu de docker.

Comment lister les pods ?

kubectl get pods

Je vous invite à bien retenir la combinaison « kubectl get » qui revient en permanence sur kub. Elle permet de lister les objets d’un type donné.

Si vous êtes sur un cluster kubernetes, il est intéressant d’en revenr aux fondamentaux qu’il faut toujours garder en tête et notamment : kubernetes est un orchestrateur de conteneurs.

Ainsi, je vous invite à faire un :

kubectl get pods -o wide

L’option -o wide permet d’avoir plus d’information et notamment les les noeuds sur lesquels les conteneur ont été déployés. Ainsi poru aller plus loin vous pouvez vous rendre sur le serveur des pods que nous venons de lancer et lancer un simple

docker ps | grep "mycontainer\|another"

Vous devriez retrouver les conteneurs déployés par notre fameuse couche logique qui est le pod.

Vous pouvez aussi supprimer ces pods à l’aide de la commande :

kubectl delete pods <nom_du_pod>

Et un peu plus loin le deployment et le service

Alors maintenant nous allons encore empiler une brique logique sur les pods à savoir le deployement. Un deployment permet de lancer les pods de manière automatisée si on devait le résumer. Le deployment a des capacités étendues.

Ainsi, dans le deployment, nous le verrons plus tard, nous aurons un template de pods. C’est à dire la capcité à lancer et relancer des pods du même type… et même proposer de l’autoscaling de pod en fonction de la sollicitation des ressources ou non.

Alors comment créer un deployment qui va lancer un pod ?

Simplement avec la ligne de commande :

kubectl create deployment monnginx --image nginx

Avec cette ligne nous créons un déploiement de la manière la plus réduite qu’il existe à savoir en spécifiant juste l’image qui servira dans le pod à créer le ou les conteneurs. Dans notre cas, cette image est une nginx.

Je vous invite à lister ce nouvelle object de cette manière :

kubectl get deployment

Vous découvrez donc votre déploiement et si vous lancez un :

kubectl get pods

Vous retrouvez un pod préfixé du nom du déploiement.

Simple non ? Dans la pratique vous le verrez on ne lance presque jamais un pod seul mais vous le ferez par un deployment. Ce dernier apporte aussi de la persistance à votre pod notamment via un autre object créé par le deployment qui se nomme le replicaset. Il a principalement en charge l’existence de vos pods et le respect du bon nombre. Vous pouvez également lister les replicaset

kubectl get replicasets

Et si vous le souhaitez vous pouvez faire le test de supprimer un pod créé par votre deployment.

kubectl delete pods <nom_du_pod>

Que se passe-t-il si vous relisté les pods ensuite ? Kubernetes va recréer le nombre de pods que vous avez demandé de maintenir au deployment.

Alors comment supprimer définitivement les pods ? Simplement en supprimant le pod (il y a d’autres moyens pour d’autres cas de figures).

kubectl delete deployment monginx

Et là kubernetes va supprimer lui même les pods et replicaset.

Voici donc nos premier pas dans un cluster kubernetes réalisés. Si vous souhaitez progresser reportez vous à la playlist de formation kubernetes, c’est gratuit. Vous pouvez aussi retrouver le code pour faire vos tests ici. A bientôt !!

Faire son premier playbook avec ansible

Vous êtes débutant sur ansible ? ou peut être un peu plus avancé mais vous cherchez à vous faire une piqûre de rappel pour remettre les choses en place ? Je vous propose de suivre ma formation ansible en ligne et totalement gratuite via des vidéos youtube mais également à travers les articles de ce blog devops.

Alors depuis quelques vidéos nous avons posé les bases avec :

  • l’inventaire
  • les groupes
  • les hosts
  • l’installation
  • la CLI

Nous allons continuer sur ce chemin pour débuter petit à petit avec cet orchestrateur.

Depuis le temps il est peut être venu le moment de faire quelques actions sur nos serveurs.

A quoi sert le playbook ??

C’est assez simple, dans les définitions et concepts, nous avons vu qu’il y a deux bulles. Avec d’un côté l’inventaire et de l’autre les tasks qui sont des actions individuels que l’on peut rassembler dans des rôles.

Mais comment savoir quelles tâches sont jouées sur quelles machines cibles ?

C’est là qu’intervient le playbook. Il permet de coordonner les deux bulles l’inventaire et les rôles/tasks.

Il s’ait donc ni plus ni moins d’un fichier qui va dire quels groupes ou machines reçoivent quelles actions ? et bien sûr tout cela en format yaml comme la plupart des fichiers dans ansible.

Le playbook minimum resemble à ceci en terme de contenu :

- name: Mon Playbook !!
  hosts: all
  tasks:
  - name: je debug
    debug:
      msg: "{{ var1 }}"

Découvrons un peu plus ce que l’on a écrit :

  • le nom du playbook « mon premier playbook »
  • son périmètre ou ses serveurs cibles, donc notre cas le groupe all (c’est à dire toutes les machines)
  • un bloc permettant de décrire les tasks
  • le nom de la première tâche « je debug »
  • l’appel à un module, en l’occurence « debug »
  • les paramètres passés à ce module « msg » (pour indiquer un message composé d’une variable au format jinja).

On est pas mal pour débuter avec notre playbook.

A côté il ne faut pas oublier d’avoir un inventaire, comme par exemple :

all:
  hosts:
    172.17.0.2:

Comprendre la ligne de commande ansible-playbook ?

Comment lancer le playbook ? Comprendre est peut être un bien grand mot mais au moins savoir un peu ce que l’on fait et ce que l’on peut faire avec ansible et ses playbooks.

Dans ce qui est dessous nous allons parler du binaire ansible-playbook.

Voyons déjà une ligne de commande minimaliste pour lancer ce fichier :

ansible-playbook -i inventory.yml playbook.yml

Très simple non ? bon généralement il y aura souvent un peu plus d’options que cela dans votre terminal.

Voici donc quelques options plus ou moins connues (mais même les moins connues sont intéressantes… le diable se cache dans les détails).

	* -l : réduire le run à certaines machines ou certains groupes de votre inventaire
	* -u : spécifier un user particulier utilisé sur la où les machines distantes
	* -b : become est équivalent à taper sudo devant vos commandes pour élever vos privilèges
	* -k : pour recevoir la demande de saisie du mot de passe pour la connexion ssh
	* -K : le password pour l'élévation de privilège liée au sudo (become)
	* -C : check c'est le dry run... très utile quand on ne connait pas la fréquence des runs ansible
	* -D : diff c'est très utile pour avoir les différences et les modifications de ce que va faire ansible
	* --ask-vault : permet de saisir un password pour déchiffrer les secrets que vous aurez chiffré avec vault
	* --syntax-check : vérfier la syntax
	* --vault-password-file : passer le vault password par un fichier
	* -e : surcharger n'importe quelle variable
	* -f : forks, nombre de parallélisation
	* -t : filtrer sur les tags (--skip-tags)
	* --flush-cache : éviter l'utilisation du cache
	* --step : une tâche à la fois (confirmation via prompt)
	* --start-at-task : commencer à une tâche spécifiquement
	* --list-tags : lister tous les tags rencontrés
	* --list-tasks : liste les tâches qui vont être exécutées

Là on y voit plus clair.

Et maintenant commençons à jouer avec les fichiers grâce au module file.

Débuter avec le module FILE

Créer un fichier, un répertoire, leur affecter des droits, des propriétaires… ce sont des commandes courrantes en linux et généralement on apprend cela en débutant : mkdir, touch, chown, chmod, ln…. Et bien pour ansible c’est un peu pareil.

Le module file peut prendre différents paramètres :

* attribute : définitions des paramètres particuliers d'un fichier : immutabilité etc... cf https://fr.wikipedia.org/wiki/Chattr
* force : pour les liens symboliques (créer même si le fichier source existe pas, la destination existe)
* group/owner : le propriétaire et le groupe du fichier ou du répertoire
* mode : les permissions sous les deux formats : "0755" ou "u=rwx,g=rx,o=rx"
* path : la localisation du fichier ou des répertoires
* recurse : création du chemin intermédiaire si n'existe pas (yes/no), attention cela est valable uniquement pour les répertoires
* src : pour les liens (hard ou symbolique)
* state : le type absent / directory / file / hard / link / touch
		touch > créé le fichier vide
		file > vérifie l'existence et les caractéristiques

Et donc nous voici prêt à écrire notre première task. Par exemple pour créer un répertoire :

- name: créer un répertoire
  file:
    path: /tmp/xavki/
    state: directory
    owner: root

Ici ansible va créer le répertoire xavki dans /tmp car le state est de type directory. Et le propriétaire de ce répertoire sera l’utilistaur root.

Avec l’utilisation du mode récursif :

  - name: création du répertoire /tmp/xavki
    file:
      path: /tmp/xavki/1/2/3/4
      recurse: yes
      state: directory
      owner: root
      group: root
      mode: 0755

Ou encore simplement créer un fichier vide avec touch :

  - name: création du répertoire /tmp/xavki
    file:
      path: /tmp/xavki/1/2/3/4/fichier.txt
      state: touch
      owner: root
      group: root
      mode: 0755

Ou encore sous forme de lien :

  - name: création du répertoire /tmp/xavki
    file:
      src: /tmp/xavki/1/2/3/4/
      dest: /tmp/symlink
      state: link  #hard
      owner: root
      group: root
      mode: 0755

Et enfin pour supprimer des fichiers ou des répertoires, il suffit d’utiliser le state absent très courrant dans les modules ansible.

  - name: dir sans idempotence
    file:
      path: /tmp/xavki.txt
      state: absent

Voilà j’espère que cette prise en main de ansible et que vous pouvez débuter en toute tranquilité à votre rythme. Je vous rappelle que vous pouvez venir découvrir plus de 900 vidéos sur la chaine xavki avec de nombreuses autres thématiques autour du devops bien sûr. Et retrouvez tous les fichiers de ces présentations sur le dépôt dédié à ansible.

Ansible, son inventaire… et son organisation

Après avoir découvert la CLI, continuons dans l’univers d’ansible pour apprendre à l’utiliser et bien comprendre ses principes. Eh oui, apprendre ansible c’est bien mais il faut surtout bien assimiler les concepts et bien organiser. Le but de cet article est d’aider les débutants à trouver leur chemin et de partager les pratiques avec les personnes ayant un niveau un peu plus avancé.

Il existe pas mal de bonnes pratiques pour ne pas se louper et toujours garder le cap. Après quelques années d’expériences, je pense que dans le domaine de l’infra as code, il faut toujours avoir des règles, des principes, des nomenclatures pour garder l’objectif de toujours s’y retrouver et éviter les dérives. Et systématiquement, il y a des dérives et il faudra revenir vers vos règles pour ramener les choses dans l’ordre.

Mais bon, quand on ne connait pas ou même lorsque l’on connait juste un peu, ce n’est pas évident de trouver son cap. Et surtout il faut éviter d’inventer des choses qui existent déjà.

Rester dans les fondamentaux a aussi un gros avantage. Si vous intégrez de nouvelles personnes dans vos équipes et qu’elles connaissent déjà les bonnes pratiques, ce sera encore plus facile pour eux d’être intégré technologiquement parlant. Et cela est très important en matière d’IaC car celle-ci décrit votre infrastructure et l’installation d’élements importants.

Bref l’inventaire ou inventory est un élément essentiel dans ansible et dans votre infrastructure. Pour débuter avec ansible, il faut donc bien organiser celui-ci.

Inventory ou fichier d’inventaire, c’est votre infrastructure

L’inventory n’est pas juste ce fichier mais celui-ci est central. Nous verrons dans le point suivant que l’inventaire est aussi composé de ses variables que nous nommons… variables d’inventaire.

L’inventaire comprend la liste de vos machines, il peut être de 3 types de formats : json, yaml, ini. Personnellement, je préfère le format yaml. Pourquoi ? tout simplement car :

  • tous les autres fichiers ansible sont en format yaml, donc par souci d’homogénéité
  • également car grâce à son indentation il permet de bien visualiser la hiérarchie des groupes et hosts (même si nous ne sommes pas toujours fan du format yaml).

Une machine est appelée host assez logiquement. Un ou plusieurs hosts peuvent consituer un groupe (group). Les hosts peuvent être décrit par des éléments permettant de les joindre : ip, dns principalement.

Et si vous avez des nomenclatures de serveurs adaptées, vous pourrez même gagner du temps en utilisant des patterns, par exemple : srv-bdd-[1-5].

Mettons maintenant tout cela en musique :

all:
  children:
    parent1:
      hosts:
        srv4:
      children:
        enfant1:
          hosts:
            srv1:
            srv2:
        enfant2:
          hosts:
            srv3:
          children
            enfant3:
              hosts:
                srv5:

Cela pour le format yaml, on a :

  • le groupe parent de tous qui se nomme toujours ALL (non modifiable)
  • le sous-groupe de ALL qui se nomme parent1 (à vous de choisir le nom)
  • parent1 est composé d’un host srv4 et de deux sous-groupes : enfant1 et enfant2
  • enfant1 est composé de srv1 et srv2
  • enfant2 est composé de srv3 et un autre sous-groupe enfant3
  • etc

Et maintenant pour le format ini.

[parent1]
srv4
[enfant1]
srv1
srv2
[enfant2]
srv3
[enfant3]
srv5
[parent1:children]
groupe1
groupe2
[enfant2:children]
enfant3

Et voilà l’essentiel. On peut également passer des variables directement dans ce fichier pour les associer à des groupes ou encore à des hosts. Mais je ne recommande pas de faire cela ou surtout il faut le limiter au maximum pour éviter que votre fichier d’inventaire ansible ne soit imbuvable.

Tutoriels : inventory, sa structure

Les variables d’inventaires ansible

Pour apprendre ansible, nous le reverrons mais il est important d’avoir un peu en tête la hiérarchie des variables ou précédence des variables… 22 types de variables au final dont certaines sont plus prioritaires que d’autres. Rassurez-vous vous n’avez pas besoin de toutes les connaître et surtout il faut éviter autant que possible de toutes les utiliser pour faciliter la maintenance de votre code.

Les formations ansible passent souvent assez rapidement sur les variables d’inventaires. C’est assez logique car sans mise en pratique c’est toujours délicat à aborder. Néanmoins il faut y passer quelques minutes pour bien débuter.

Notre fichier inventory est donc composé de hosts et de groupes. Nous allons donc pouvoir définir des variables de groupes et d’autres spécifiquement pour des hosts. Une fois que l’on a dit cela, il se dégage logiquement une hiérarchie ou précédence, les variables de hosts s’imposent aux variables de groupes. Ainsi, si vous avez un groupe de webserver avec une variable port = 80, si vous avez une exception dans ce groupe vous pourrez surcharger la variable de groupe par la variable du host en question port = 8080, par exemple.

Comment cela s’organise ?

Assez simplement au même niveau que notre inventory (le fichier), on va retrouver deux répertoires :

  • group_vars
  • host_vars

Une fois dans ces répertoires nous allons pouvoir créer soit :

  • des répertoires par groupe avec le nom du groupe ou par nom de host, vous pourrez ainsi créer plusieurs fichiers car vous avez beaucoup de variables et donc un besoin d’organiser un maximum
  • des fichiers yaml par nom de groupe ou nom de host car vous avez peu de variables.
├── 00_inventory.yml
├── group_vars
│   ├── all.yml
│   ├── dbserver.yml
│   └── webserver
│       ├── vault.yml
│       └── webserver.yml
└── host_vars
    ├── srv1
    │   └── srv1.yml
    └── srv2.yml

On retrouve bien :

  • notre fichier d’inventaire 00_inventory.yml
  • nos deux répertoires principaux toujours nommés group_vars et host_vars
  • et des sous-répertoires ou fichiers

Et si vous avez différents environnements vous pouvez tendre vers cette organisation assez connue :

├── dev
│   ├── 00_inventory.yml
│   ├── group_vars
│   │   ├── all.yml
│   │   ├── dbserver.yml
│   │   └── webserver
│   │       ├── vault.yml
│   │       └── webserver.yml
│   └── host_vars
│       ├── srv1
│       │   └── srv1.yml
│       └── srv2.yml
├── prod
│   ├── 00_inventory.yml
│   ├── group_vars
│   │   ├── all.yml
│   │   ├── dbserver.yml
│   │   └── webserver
│   │       ├── vault.yml
│   │       └── webserver.yml
│   └── host_vars
│       ├── srv1
│       │   └── srv1.yml
│       └── srv2.yml
└── stage
    ├── 00_inventory.yml
    ├── group_vars
    │   ├── all.yml
    │   ├── dbserver.yml
    │   └── webserver
    │       ├── vault.yml
    │       └── webserver.yml
    └── host_vars
        ├── srv1
        │   └── srv1.yml
        └── srv2.yml

Prenez bien votre temps pour bien comprendre et retenir ce type d’organisation car vous la retrouverez souvent ou elle pourra repondre à votre besoin. Pour débuter avec l’inventaire ansible c’est déjà un très bon début.

Voici une petite démonstration qui va permettre de rendre parlant tout cela avec une variable que l’on va surcharger à différents endroits.

Tutoriel : les variables d’inventaire

Mon dépôt de formation ansible ici.

Retrouvez également la documentation officielle concernant l’inventory ici.

English version : if you want to learn and start with ansible

Commencer avec la CLI de ansible et quelques astuces

Lors de notre précédent article, nous avons débuter avec ansible :

  • principes de base
  • installations possibles
  • premières commandes

Nous n’allons pas encore nous jeter dans le grand bain des rôles et playbooks. Pour un débutant, il est important de comprendre le fonctionnement de base d’un outil. En guise de formation et pour faire un premier pas avec la ligne de commande, je vous propose de pratiquer quelques commandes.

Retrouvez mon dépôt ici.

Et la vidéo associée :

La plus basique : le ping ansible

Pour savoir si ansible fonctionne de votre serveur/laptop source vers votre machine cible, nous pouvons utiliser le module ping. Attention, il ne s’agit pas là de faire un ping réseau ou icmp mais un ping au sens de ansible. En gros, ansible peut-il faire une connexion ssh vers la machine cible d’où vous le lancer.

Cela induit donc plusieurs paramètres : le serveur et le user. Il est important de ne pas oublier ce dernier car c’est avec lui que sera associé la clef ssh ou le password. L’utilisateur de départ qui initie la connexion est celui qui lance la commande ansible et l’utilisateur final peut être précisé par l’option -u.

Regardons la ligne ci-dessous :

ansible -i "node2," all -u vagrant -m ping

On a :

  • -i : qui précise le serveur target/cible, cela peut être un nom dns ou une ip. Important,vous devez rajouter une virgule après ce n’est pas une erreur de frappe. Suivi de « all » qui définit le groupe qui par défaut est all, nous reverrons cela plus tard avec l’inventaire.
  • -u : précise l’utilsiateur de la machine cible. Si vous utilisez une clef ssh c’est dans la conf ssh de ce user que vous devez avoir ajouté votre clef publique (dans le fichier authorized_keys).
  • -k : si vous n’avez pas de clef publique ou que vous souhaitez utiliser une connexion ssh via un passowrd vous pouvez le faire avec cette option. Ansible proposera alors de le saisir après avoir lancé la commande.

Vous pouvez forcer l’utilisation du password ssh de cette manière :

ansible -i "node2," all -u vagrant -k --ssh-extra-args="-o 'PreferredAuthentications=password'" -m ping

Pour afficher le résultat sur une ligne :

ansible -i "node2," all -u vagrant -m ping --one-line

Pour utiliser à distance une commande sur le shell distant :

ansible -i "node2," all -u vagrant -m command -a uptime

Et voilà vous avez lancé un uptime à distance et récupéré son résultat.

Poussons plus loin dans l’utilisation de la CLI

Bien sûr on peut même aller plus loin avec la simple ligne de commande ansible. Je vous propose pour vous former quelques exemples qui vous permettront de vous aguerrir par la pratique et sans faire de code pour le moment.

Par exemple, par la ligne de commande nous pouvons définir une variable et afficher son résultat comme si nous étions sur le serveur distant.

ansible -i "node2," all -e "var1=xavki" -m debug -a 'msg={{ var1 }}'

Ainsi nous passons quelques nouvelles options :

  • -e : pour définir une variable « var1 » avec sa valeur « xavki »
  • -m : pour préciser le module à utiliser, en l’occurence « debug »
  • -a : pour définir un paramètre de ce module, nous définissons « msg » avec la valeur de var1. Remarquez le double accolade qui est un format jinja, ansible reposant sur python.

Maintenant lançons un shell un peu plus élaboré avec quelques pipe dans ansible :

ansible -i "node2," all -u vagrant -m shell -a "ps aux | grep vagrant | wc -l" --one-line

On retrouve toujours nos options et nous avons simplement changé de module en utilisant « shell ». Et on profite du oneline pour l’output.

Comment installer à distance un serveur nginx :

ansible -i "node2," all -b -m apt -a 'name=nginx state=latest'

Là encore changement de module pour « apt » et définition de deux paramètres de ce module avec -a.

De même pour arrêter ou redémarer le service systemd :

ansible -i "node2," all -b -m service -a 'name=nginx state=stopped'

Et encore un peu plus…

Et on peut pousser encore plus loin avec d’autres onelines très facile à comprendre et utiliser.

Comment faire l’équivalent d’un scp avec ansible en une ligne ?

ansible -i "node2," all -m copy -a 'src=toto.txt dest=/tmp/titi.txt'

On y définit le fichier source et la destination. Mieux qu’un scp, ansible va faire jouer son idempotence et ne réalisera cette action que si nécessaire. C’est à dire si le fichier n’existe pas ou si il est différent du fichier source.

Pour faire l’inverse et récupérer un fichier d’une machine distante ?

ansible -i "node2," all -m fetch -a 'src=/tmp/titi.txt dest=xavki.txt flat=yes'

Cette fois-ci on utilisera le module « fetch », là encore en une ligne pour débuter tranquillement et apprendre à notre rythme.

Mais savez vous que à chaque run, ansible récupère ce que l’on appelle des facts, ce sont des variables génériques soit nécessaire pour son fonctionnement soit souvent utiles.

Eh bien regardons les facts disponibles pour une machine donnée :

ansible -i "node2," all -m setup -a "filter=ansible_distribution*"

Vous voyez que dans cette exemple, nous filtrons ceux-ci pour ne récupérer que les facts relatifs à la distribution.

Forez vous avec des tutorials ansible sur la chaine Xavki

Se former et apprendre Ansible et mettre un pied dans l’automatisation

Vous le savez, la chaine xavki que je tiens, est axée autour du devops. Comment devenir devops ou en acquérir les réflexe ou même la philosophie ? Dans ce domaine, certains outils sont marquants et sortent du lot. L’infrastructure as code est bien sûr un peu essentielle. De nombreux softs existent dans ce domaine et certains ont gagné des parts ces dernières années. Ansible fait partie de ces outils du parfait devops.

Ansible en quelques principes ?

Les principes d’ansible en font de lui un des plus faciles à adopter du marché. Totalement gratuit, il se base sur le langage python qui a fortement progressé ces dernières années agrandissant sensiblement son périmètre au fur et à mesure des années (IA, big data, statistiques, développement, CMS, framework…).

En outre, pour faciliter les choses, il se base sur une méthode de type push. A savoir que ansible ne nécessite pas d’agent. Mieux, une simple connexion ssh et python vous permettront de faire l’essentiel des tâches que vous aurez à réaliser. Un bon point pour les sysadmins qui restent fidèles à leurs scripts bash avec des boucles pour lancer un peu de ssh. Ou encore aux développeurs python qui utilisent paramiko avec une gestion délicate de l’idempotence… Ansible peut satisfaire vraiment beaucoup de monde.

Certains apprécieront moins son langage descriptif à base de yaml. Néanmoins, il permet de glisser sur la tendance et permet d’organiser clairement le code sous réserve de respecter les bonnes indentations. Un bon IDE vous y aidera d’autant plus.

Quelques éléments centraux :

  • le fichier d’inventaire (inventory file) : facile à deviner, il permet de regrouper la liste des machines, des groupes de machines ou même des patterns de serveurs
  • les variables d’inventaire : il s’agit des variables spécifiques à des hosts/serveurs ou à des groupes de machines. Elles sont stockées soit dans le fichier d’inventaire mais plutôt dans des répertoires host_vars et group_vars, respectivement pour les serveurs et les groupes de serveurs.
  • le rôle : regroupe un ensemble de tâches ou d’actions cohérentes pour installer, configurer etc (par exemple installer un serveur web). Un rôle est constitué notamment d’actions que l’on appelle tasks.
  • les tasks : ce sont des tâches individuelles qui utilise un module suivant des paramètres adaptés à la finalité de l’action
  • le playbook : fichier permettant de faire la jointure entre l’inventaire et les rôles. Il a une fonction centrale qui permet de dire quel groupe ou quel serveur va avoir tels et tels rôles de joués.

Respecter ces principes est PRIMORDIAL pour la faciliter de l’organisation du code dans son ensemble. S’agissant de bonnes pratiques, n’importe quelle personne ayant suivie une formation ansible pourra s’y retrouver relativement facilement et pouvoir découvrir votre infra en lisant comme dans un livre (on l’oubli trop souvent).

Installer le binaire

Potentiellement il y a 3 choix pour installer ansible :

  • via le gestionnaire de module python comme pip (pip3)
  • via le téléchargement de la source
  • via le gestionnaire de paquets de votre distribution préférée

Personnellement je préfère de loin cette dernière solution. Mais le contexte peut vous en faire décider autrement.

Sur debian on va simplement faire

sudo apt update

sudo apt install ansible

Et voilà le tour est joué. Vous pourrez très bien le faire sur redhat/centos/fedora car le projet ansible est porté par Redhat.

Pour configurer ansible, il est nécessaire de retenir un nom de fichier : ansible.cfg.

Vous pourrez le retrouver dans /etc/ansible/ ou encore dans votre home ou enfin à la racine de votre code (localisation du playbook).

Je vous invite à en découvrir plus sur la playlist de tutos ansible.

Premières commandes en CLI

Si vous avez installé ansible, vous êtes prêts à faire feu !!! Sauf si vous n’avez pas créé votre clef ssh. Dans ce cas, je vous propose une petite piqure de rappel ici.

Bref comment débuter et faire vos premières commandes ?

Pour pinguer les machines cibles.

ansible -i "node2," all -u vagrant -m ping

Attention, on parle d’un ping au sens ansible à savoir réussir une connexion ssh globalement.

-i : permet de préciser le fichier d’inventaire mais comme nous ne l’avons pas encore vu et que notre cible est une seule et unique machine on va simplement préciser cette machine entre double quote MAIS n’oubliez pas la virgule et le all (pour indiquer que cette machine fait partie du groupe all.

-u : permet de préciser l’utilisateur distant pour notre ssh ( <user>@<server>)

-m : permet de préciser l’utilisation d’un module, en l’occurence le module ping.

Dans notre cas nous avons une clef ssh mais on peut également faire la même chose par un password ssh :

ansible -i "node2," all -u vagrant -k -m ping

et si vous voulez forcer le fonctionnement par password pour une raison précise :

ansible -i "node2," all -u vagrant -k --ssh-extra-args="-o 'PreferredAuthentications=password'" -m ping

Kubespray : installation d’un cluster K8S se rapprochant de la production

Installer kubernetes on premise est un petit défi même si certaines solutions sont plus simples que d’autres. J’ai pu tester différentes options comme kubadm, rancher ou en core kubespray mais jamais « the hard way ». Cette dernière méthode est certainement la meilleure pour mieux appréhender la constitution d’un cluster. Certes, cette méthode est formatrice mais peut effrayer notamment faire peur si on veut installer un cluster kubernetes pour de la production. Si vous souhaitez vous former à kubernetes rendez-vous sur cette playlist.

Je vous propose de découvrir une méthode intermédiaire mais d’y ajouter le nécessaire pour rendre votre cluster hautement disponible. Et vous allez voir que contrairement à ce que l’on pense ce n’est pas si compliqué. Je vous invite après cette installation de prendre du recul et d’identifier les points critiques pour être bien à l’aise avec ces éléments. Car le jour où votre cluster kube dysfonctionne en production et on premise, vous pouvez transpirer pas mal pour débuguer car généralement vous n’avez pas mis qu’une seule application dessus.

Tout le code ci-dessous est présent dans mon dépôt officiel.

Mais je vous invite à découvrir les vidéos dans cette playlist youtube :

De quoi avons nous besoin côté machines virtuelles ?

Eh oui on veut tester un environnement de production mais rien ne vous empêches de vous faire la main sur votre laptop ou de simples machines virtuelles. Personnellement, j’utilise souvent virtualbox et je fais le provisioning de manière automatisé avec vagrant. Le Vagrantfile est donc ce qui va le mieux décrire notre infrastructure. J’ai volontairement évité de factoriser les boucles de manière à rendre cela plus lisisble.

Notre infrastructure sera composée :

  • 1 machine de déploiement pour jouer kubespray (ansible) on va pas salir notre laptop non plus et en prod on ne déploie pas de son laptop.
  • 2 haproxy : ils serviront pour loadbalaner l’api kubernetes pour les commandes kubectl vers nos master (port 6443) et également pour loadblancer sur les noeuds worker les flux http/https (80/443)
  • 2 masters : il vaudrait mieux 3 mais notre but est de faire de simples tests tout de même (en ajoute run n’est juste que rajouter une ligne dans le ansible)
  • 1 node : notre objectif n’est pas d’héberger mais de tester un cluster kube et son environnement haute disponibilité.

Ce qui donne :

Vagrant.configure(2) do |config|
  common = <<-SHELL
  if ! grep -q deploykub /etc/hosts; then  sudo echo "192.168.7.120     kdeploykub" >> /etc/hosts ;fi
  if ! grep -q node01 /etc/hosts; then  sudo echo "192.168.7.121     kmaster01" >> /etc/hosts ;fi
  if ! grep -q node02 /etc/hosts; then  sudo echo "192.168.7.122     kmaster02" >> /etc/hosts ;fi
  if ! grep -q node03 /etc/hosts; then  sudo echo "192.168.7.123     knode01" >> /etc/hosts ;fi
  if ! grep -q node04 /etc/hosts; then  sudo echo "192.168.7.124     haproxy01" >> /etc/hosts ;fi
  if ! grep -q node05 /etc/hosts; then  sudo echo "192.168.7.125     haproxy02" >> /etc/hosts ;fi
  sudo yum -y install vim tree net-tools telnet git python3-pip sshpass
  sudo setsebool -P haproxy_connect_any=1
  sudo echo "autocmd filetype yaml setlocal ai ts=2 sw=2 et" > /home/vagrant/.vimrc
  sed -i 's/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/g' /etc/ssh/sshd_config
  sudo systemctl restart sshd
  SHELL
  

	config.vm.box = "centos/7"
	config.vm.box_url = "centos/7"

	config.vm.define "kdeploykub" do |kdeploykub|
		kdeploykub.vm.hostname = "kdeploykub"
		kdeploykub.vm.network "private_network", ip: "192.168.7.120"
		kdeploykub.vm.provider "virtualbox" do |v|
			v.customize [ "modifyvm", :id, "--cpus", "1" ]
			v.customize [ "modifyvm", :id, "--memory", "512" ]
			v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
      			v.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
			v.customize ["modifyvm", :id, "--name", "kdeploykub"]
		end
		config.vm.provision :shell, :inline => common
	end
	config.vm.define "kmaster01" do |kmaster01|
		kmaster01.vm.hostname = "kmaster01"
		kmaster01.vm.network "private_network", ip: "192.168.7.121"
		kmaster01.vm.provider "virtualbox" do |v|
			v.customize [ "modifyvm", :id, "--cpus", "2" ]
			v.customize [ "modifyvm", :id, "--memory", "2048" ]
			v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
      			v.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
			v.customize ["modifyvm", :id, "--name", "kmaster01"]
		end
		config.vm.provision :shell, :inline => common
	end
	config.vm.define "kmaster02" do |kmaster02|
		kmaster02.vm.hostname = "kmaster02"
		kmaster02.vm.network "private_network", ip: "192.168.7.122"
		kmaster02.vm.provider "virtualbox" do |v|
			v.customize [ "modifyvm", :id, "--cpus", "2" ]
			v.customize [ "modifyvm", :id, "--memory", "2048" ]
			v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
      			v.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
			v.customize ["modifyvm", :id, "--name", "kmaster02"]
		end
		config.vm.provision :shell, :inline => common
	end
	config.vm.define "knode01" do |knode01|
		knode01.vm.hostname = "knode01"
		knode01.vm.network "private_network", ip: "192.168.7.123"
		knode01.vm.provider "virtualbox" do |v|
			v.customize [ "modifyvm", :id, "--cpus", "2" ]
			v.customize [ "modifyvm", :id, "--memory", "2048" ]
			v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
      			v.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
			v.customize ["modifyvm", :id, "--name", "knode01"]
		end
		config.vm.provision :shell, :inline => common
	end
	config.vm.define "haproxy01" do |haproxy01|
		haproxy01.vm.hostname = "haproxy01"
		haproxy01.vm.network "private_network", ip: "192.168.7.124"
		haproxy01.vm.provider "virtualbox" do |v|
			v.customize [ "modifyvm", :id, "--cpus", "1" ]
			v.customize [ "modifyvm", :id, "--memory", "512" ]
			v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
      			v.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
			v.customize ["modifyvm", :id, "--name", "haproxy01"]
		end
		config.vm.provision :shell, :inline => common
	end
	config.vm.define "haproxy02" do |haproxy02|
		haproxy02.vm.hostname = "haproxy02"
		haproxy02.vm.network "private_network", ip: "192.168.7.125"
		haproxy02.vm.provider "virtualbox" do |v|
			v.customize [ "modifyvm", :id, "--cpus", "1" ]
			v.customize [ "modifyvm", :id, "--memory", "512" ]
			v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
      			v.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
			v.customize ["modifyvm", :id, "--name", "haproxy02"]
		end
		config.vm.provision :shell, :inline => common
	end

end

Ou encore ce Vagrantfile

Commençons par le loadbalancer externe haproxy et sa vip gérée par keepalived

Attention avant de lancer le ansible kubespray, il est nécessaire que votre haproxy et votre VIP soient mis en place.

Donc première chose on installe les deux haproxy et keepalived :

sudo apt install - y haproxy keepalived

et ensuite on édite la configuration de haproxy

global
    log         127.0.0.1 local2

    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
    stats socket /var/lib/haproxy/stats

defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000

listen stats
    bind *:9000
    stats enable
    stats uri /stats
    stats refresh 2s
    stats auth xavki:password

listen kubernetes-apiserver-https
  bind *:6443
  mode tcp
  option log-health-checks
  timeout client 3h
  timeout server 3h
  server master1 192.168.7.121:6443 check check-ssl verify none inter 10000
  server master2 192.168.7.122:6443 check check-ssl verify none inter 10000
  balance roundrobin

Bien sûr derrière je vous laisse reload le service systemd de haproxy.

Ensuite ajoutons la configuration de keepalived :

vrrp_script reload_haproxy {
    script "/usr/bin/killall -0 haproxy"
    interval 1
}

vrrp_instance VI_1 {
   virtual_router_id 100
   state MASTER
   priority 100

   # interval de check
   advert_int 1

   # interface de synchro entre les LB
   lvs_sync_daemon_interface eth1
   interface eth1

   # authentification entre les 2 machines LB
   authentication {
    auth_type PASS
    auth_pass secret
   }

   # vip
   virtual_ipaddress {
    192.168.7.130/32 brd 192.168.7.255 scope global
   }

   track_script {
     reload_haproxy
   }

}

Dans cette configuration on utilise une VIP qui switchera en fonction du service haproxy et du fait qu’il soit fonctionnel au vue de systemd ou non. Cette VIP est la :

192.168.7.130

Par défaut cette VIP sera portée par la machine haproxy1. Si celui-ci tombe cette adresse va être installée sur haproxy2 grâce à keepalived.

Vérifiez que les deux services (haproxy et keepalived) soient bien démarrés sur les 2 machines haproxy. Activez le redémarrage au reboot avec le systemctl enable.

Maintenant configurons kubespray

Kubespray c’est du ansible. donc première chose vous devez l’installer sur la machine de déploiement et installer également pip :

sudo apt install ansible python3-pip

Ensuite clonez le dépôt de kubespray :

git clone https://github.com/kubernetes-sigs/kubespray

rendez-vous dans le nouveau répertoire puis :

sudo pip3 install -r requirements.txt

Ensuite on prépare le ansible on va recopier le modéèle d’inventaire :

cp -rfp inventory/sample inventory/mycluster

Puis on modifie cet inventory :

# ## Configure 'ip' variable to bind kubernetes services on a
# ## different ip than the default iface
# ## We should set etcd_member_name for etcd cluster. The node that is not a etcd member do not need to set the value, or can set the empty string value.
[all]
kmaster01 ansible_host=192.168.7.121  ip=192.168.7.121 etcd_member_name=etcd1
kmaster02 ansible_host=192.168.7.122  ip=192.168.7.122 etcd_member_name=etcd2
knode01 ansible_host=192.168.7.123  ip=192.168.7.123 etcd_member_name=etcd3

# ## configure a bastion host if your nodes are not directly reachable
# bastion ansible_host=x.x.x.x ansible_user=some_user

[kube-master]
kmaster01
kmaster02
[etcd]
kmaster01
kmaster02
knode01

[kube-node]
knode01

[calico-rr]

[k8s-cluster:children]
kube-master
kube-node
calico-rr

On y a donc déclaré nos nodes master et notre worker.

Particularité ETCD

Particularité pour notre test, nous allons faire ce qu’il ne faut pas faire c’est à dire héberger les services etcd sur les master et surtout sur 1 worker. Pourquoi cela ? Etcd nécessite un nombre impair de noeuds pour son bon fonctionnement. Donc on pourrait en avoir 1 ou 3. Mais si on veut faire des tests de coupures de noeuds il est préférable d’en avoir 3. J’ai donc salement choisi d’en ajouter un sur le worker.

En production il serait recommandé d’externaliser les etcd et ne pas les avoir au sein des machines kubernetes (plus y ajouter des backups etc).

Dernière configuration ansible

Maintenant il nous faut éditer le fichier du group all :

vim inventory/mykub/group_vars/all/all.yml

comme en modifiant ces lignes

## External LB example config
apiserver_loadbalancer_domain_name: "elb.kub"
loadbalancer_apiserver:
  address: 192.168.7.130
  port: 6443

On vient donc de préciser que la VIP est notre point d’entrée du loadbalancer et également que votre cluster répondra sur le nom de domaine elb.kub (vous pourrez modifier votre /etc/hosts).

Maintenant c’est partie on peut jouer notre ansible en tant que user vagrant et on utilisera le password « vagrant »… un standard sur vagrant.

ansible-playbook -i inventory/my-cluster/inventory.ini -u vagrant -k -b cluster.yml

Attendez plusieurs dizaines de minutes suivant votre connexion et le nombre de machines et votre cluster sera up à la fin.

Première connexion avec kubectl

Dernière tâche pour accéder à notre cluster, il nous faut récupérer le certificat du compte d’administrateur de notre cluster kubernetes.

Copiez sur un des master le fichier

cat /etc/kubernetes/admin.conf

Puis créez et collez le contenu sur la machine devant accéder au cluster :

mkdir -p ~/.kube
vim ~/.kube/config

Enfin installons kubectl sur cette même machine :

sudo apt-get update && sudo apt-get install -y apt-transport-https
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubectl

Maintenant testons notre cluster :

kubectl cluster-info
kubectl get nodes

Test de la haute disponibilité

Si tout est bien fonctionnel…

Coupez un haproxy soit en coupant le service avec un systemctl stop soit en arrêtant plus ou moins brutalement la machine.

Testez à nouveau vos commandes kubectl.

Ensuite coupez un master et procédez au même test.

Alors ça marche ?

Je vous invite à découvrir la playlist complète pour découvrir kubernetes et d’autres outils liés ici.

Tutorials pour débuter avec Kubernetes

Suivre les technologies du moment, c’est souvent le but recherché par tous les sysadmin et devops. Et cela n’est pas facile avec la démultiplication des technologies de puis l’arrivée du cloud, des conteneurs et de l’infrastructure as code. Une évolution inévitable à l’heure de l’industrialisation de l’informatique, secteur encore jeune qui a besoin d’évoluer.

Kubernetes est pleinement dans cette mouvance. D’ailleurs, le nombre de technologies ou d’outils rattachés à celui est presque affolant. Tous les jours de nouveaux outils, régulièrement de nouveaux concepts émergent également. Bref on en a jamais fini avec kubernetes. D’ailleurs l’une des forces d’un bon devops, c’est de savoir aussi attendre et faire le bon choix parmi cette forêt d’outils qui demain n’existeront plus pour certains.

Apprendre par le bon bout…

K8S pour les intimes commence déjà par docker et les principes de conteneurisation. Je vous invite à découvrir docker via la chaine xavki si vous le souhaitez. Certes kubernetes tente de se détacher de ce « conteneur runtime » mais néanmoins pour apprendre se focaliser sur docker est plutôt une bonne approche.

Mais k8s se comprend avant de s’apprendre avec de nombreux concepts et définitions. Il faut imaginer déjà que k8s est un orchestrateur de conteneurs mais c’est aussi une grosse couche logique sur les conteneurs, leurs réseaux, le stockage et le dns qui va avec.

Dans cette introduction, si vous avez du mal à imaginer kubernetes, je vous propose de vous le présenter avec simplicité.

Kubernetes vient d’ailleurs du grec et signifie timonier. On peut le comprendre car il est à la tête de ce magistral porte conteneurs.

Avec kub vous allez pouvoir bénéficier de nombreuses fonctions avancées et rares, que ne fournissent pas forcément les autres orchestrateurs de conteneurs :

  • autoguérisson
  • autoscaling
  • versionning
  • rolling update
  • sécurisation des communication entre les conteneurs par différentes couches
  • gestion de la persistence de la donnée…

Mais attention ces grands pouvoirs nécessitent une grande responsabilité comme on dit. La responsabilité de celui qui manage le paquebot. Le moindre grain de sable dans cette horlogerie et c’est le trou noir compte tenu du rôle central de l’outil. Courage donc aux sysadmins et aux devops face à ce challenge.

C’est aussi pour cela que beaucoup de choix s’orientent vers des solutions plus ou moins managés :

  • les solutions cloud : GKE, EKS…
  • les managers : rancher…

Bref c’est une aventure et on peut même simplifier en indiquant que c’est un vrai outil de virtualisation avec les responsabilités qui vont avec (et les ressources et le temps).

On ne va pas vers kubernetes pour se faire plaisir, il faut y trouver un réel intérêt sur de nombreux facteurs. On ne le fait pas pour faire comme les autres ou parce que c’est la techno du moment.

De nouvelles notions et définitions dans kubernetes

Kubernetes fait partie des technologies embarquant le plus de concepts je trouve. Intellectuellement c’est très intéressant mais c’est aussi une charge.

En voici quelques unes :

Le Pod

Inévitable, il peut regrouper un ou plusieurs conteneurs. C’est la couche logique par excellence qui va permettre une total abstraction avec l’échelon inférieur le conteneur.

Le pod contient les applicatifs, il peut être plus ou moins éphémères suivant sont types. Vous pouvez associer avec lui un applicatif et une tâche ponctuelle nécessaire pour son installation. Il peut être scallé up ou down pour soutenir la charge etc…

Les services

On pourrait les rapprocher à l’exposition des pods mais en même temps il joue une sorte de fonction de dns. L’idée est de sécuriser et permettre l’accès aux pods ayant la même fonction.

Avec eux vous pourrez en quelque sorte exposer vos conteneurs ou à l’opposé les barricader. Si les pods d’un même applicatif sont distribués sur différents noeuds, il aura la charge de fournir comment accéder à ces pods (ip port…). Il permet également de faire du dns au sein du cluster kub.

Le replicaset

Résumons-le simplement à la gestion du nombre de pods.

Le deployment

Un autre échelon très important qui englobe les replicasets et les pods. Il permet notamment de gérer la santé des pods et leur scaling suivant certaines règles. Un deployment va permettre de créer des pods suivant un template de pods. Idéal pour l’instanciation.

Les statefulsets

On peut les résumer à des deployments avec les mêmes fonctions auxquels on ajouter des facilités pour gérer la persistence de la data qui est attachée aux pods. Idéal pour les bases de données essentiellement.

Bon courage à tous mais le plaisir est au rendez-vous si vous ne brûlez pas les étapes.

Débuter avec Prometheus et se former

Le monitoring est un domaine qui existe depuis de nombreuses années pour gérer les infrastructures. Il existait avant le web mais son intérêt c’est accru d’année en année. La tolérance aux pannes étant devenue de plus en plus faible, les outils de monitoring ont évolué également avec le temps.

L’arrivée des infrastructure à base de microservices et la nécessaité de baser le monitoring sur de plus en plus d’éléments « métiers » a aussi joué ces dernières années. Si le monitoring système était bien présent auparavant, la partie applicative est devenu un enjeu important pour toute société ayant le moindre site web ou même fournissant des services en interne.

Parfois, le monitoring système est même réduit au minimum au bénéfice du service rendu final.

Vous pouvez retrouver mes prises de notes sur Prometheus en plus des vidéos de la chaine sur ce dépôt gitlab.

Prometheus et Grafana, la stack du moment

La collecte et la mise en valeur de métriques passent souvent par la combinaison de plusieurs outils. Je vous propose de découvrir aujourd’hui une partie de la stack prometheus/grafana qui est l’une des plus à la mode en ce moment.

Pourquoi ? en grande partie par sa simplicité de mise en place et son déploiement. Prometheus constitue la base de données (timeseries). Il stocke les données sur de courtes périodes (son point faible reste la rétention sur des volumes importants). Attention, il reste très performant sur de longues périodes si vous ne collectez pas trop de métriques.

Sa force ? être capable d’aller chercher lui-même l’information sur les serveurs. Alors que de nombreux autres outils fonctionnent avec des agents qui envoient l’information vers la base centralisée, Prometheus va chercher l’information.

Attention, néanmoins, vous devez mettre en place ce que l’on appelle des exporters. Il s’agit de petits binaires, souvent développés en GO (mais vous pouvez aussi développer el votre en bash ou en python). Ces derniers affichent les informations sur une route à savoir un port et un path de la machine (par défaut on utilise couramment la route /mettrics). On parle là des données où les outils ne mettent pas déjà à disposition une route pour prometheus.

Car de nombreux outils mettent à dispositions des options pour mettre en place cette route. Les données, dans tous les cas, sont affichées au format openmetrics. Un standard, facile à scraper et à utiliser.

Prometheus est aussi souvent utiliser pour ses capacités d’autodiscovery notamment dans kubernetes ou docker mais pas seulement (consul, aws, dns…).

Comment installer Prometheus ?

Bien sûr vous pouvez retrouver la documentation de prometheus ici. Cette timeseries database est tellement courante que de nombreuses distributions vous la fournissent dans les dépôts standards. Par exemple sur les OS à base de Debian :

sudo apt-get install prometheus

Sinon, bien sûr, vous pouvez l’installer facilement avec l’aide de docker pour la lancer sous forme de conteneur :

docker run -d --name prometheus \
-v $PWD/etc/:/etc/prometheus/ \
 -v $PWD/data/:/prometheus/ \
-p 9090:9090 quay.io/prometheus/prometheus:v2.0.0

Attention néanmoins à ne pas oublier qu’il s’agit d’une application stateful et que du coup vous devrez stocker des éléments en dehors du conteneur en montant un volume. Ainsi comme dans l’exemple précédent, je vous invite à monter un volume pour la configuration et un autre pour les datas. Stocker sa configuration en dehors du conteneur vous permettra de facilement relancer un conteneur similaire avec les mêmes options.

Quelques défintions pour cette TSDB particulière

Comme tout outil, Prometheus dispose de son propre langage et ses propres notions et définitions.

Sa configuration est stockée dans un fichier (par défaut prometheus.yml) au format yaml.

./prometheus --config.file=prometheus.yml

Dans ce fichier de configuration on retrouver :

  • Une partie « global » qui définit des settings par défaut par exemple :
    • scrape_interval : fréquence de collecte des métriques
    • evaluation_interval : fréquence de check des alertes
    • scrape_timeout : durée d’attente des métriques (temps de réponse de la route)
  • rule files :volet relatif à la configuration des alertes
  • scrape config : éléments relatifs aux routes mise à disposition de prometheus :
    • dynamiques ou non
    • ip/url et port
    • nom du job de scrape

Et toutes les données sont donc exportées au format openmetrics :

up{instance="192.168.62.3:9100",job="node_exporter",service="myapp"} 1

Dans cet exemple, « up » est une métrique (notamment par défaut la route prometheus), 1 sa valeur.

On découvre également ce que l’on appelle des labels comme par exemple : instance, job, service. Mais bien sûr vous pouvez aussi créer vos propres labels.

L’outil n’est pas une simple database car il récupère lui-même ses informations et met également à votre disposition une interface graphique. Par défaut, affichée sur le port 9090, elle affiche :

  • la configuration pris en compte sur le moment
  • les routes collectées
  • la possibilié de requêter les données en utilisant le langage PromQL (prometheus query language)
  • la possibilité de réaliser des graphiques (un peu rudimentaires que l’on remplacera souvent par grafana).

Node Exporter : le plus courant

On l’a dit, notre TSDB va chercher elle même ses métriques. Soit sur des outils intégrés aux applicatifs soit par le biais d’exporter. Ces outils tournent au niveau local, collecte la données et l’expose sur un port et une route (souvent /metrics par défaut).

Node exporter est l’un des plus commun. en effet, il permet de collecter des informations de bases sur le système : les disques, leurs volumes, le réseau, les process…

Pour l’installer vous devez faire votre choix :

  • par un paquet de votre distribution
  • par un conteneur docker spécifique
  • par le binaire.

Ainsi sous debian vous pouvez l’installer avec :

sudo apt-get install prometheus-node-exporter

Avec docker :

docker run -d \
  --net="host" \
  --pid="host" \
  -v "/:/host:ro,rslave" \
  -p 9100:9100 \
  --name node_exporter \
  quay.io/prometheus/node-exporter \
  --path.rootfs=/host

Et pour le faire avec le binairere source :

  • récupérez le binaire et préparez les répertoires et user
sudo useradd -rs /bin/false node_exporter
https://prometheus.io/download/#node_exporter
wget https://github.com/prometheus/node_exporter/releases/download/v0.18.1/node_exporter-0.18.1.linux-amd64.tar.gz
tar -xvzf node_exporter-0.18.1.linux-amd64.tar.gz
mv node_exporter-0.18.1.linux-amd64/node_exporter /usr/local/bin/
chown node_exporter:node_exporter /usr/local/bin/node_exporter
  • créez le service systemd pour lancer le processus et le gérer
cat /etc/systemd/system/node-exporter.service
[Unit]
Description=Node Exporter
After=network-online.target
[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter
[Install]
WantedBy=multi-user.target
  • puis activez le service systemd
systemctl daemon-reload
systemctl enable node_exporter
systemctl start node_exporter

Maintenant vous disposez de la route <ip>:9100/metrics sur la machine sur laquelle vous avez installé node exporter.

Il ne vous reste plus qu’à dire à prometheus de venir récupérer cette source d’informations. Bien sûr la machine prometheus doit pouvoir accéder à la route de node exporter. Ajoutez alors à votre configuration prometheus les lignes suivantes :

  - job_name: node-exporter
    static_configs:
      - targets: ['l<ip>:9100']

Labels et Filtres

Les labels et les filtres sont le quotidien de la personne qui utilise prometheus à travers les requêtes PromQL.

Les labels sont assimilables à des tags. C’est à dire une information que l’on va ajouter au fur et à mesure des scrape pour nous aider à isoler certaines données et les travailler plus facilement.

Ainsi, pour un scrape donnée (appelé aussi job), vous allez pouvoir ajouter un label nommé « environnement » :

  - job_name: node_exporter
      static_configs:
      - targets: [ '192.168.1.1:9100' ]
        labels:
          environnement: developpement

Dans le cas, d’utilisation d’autodiscovery, Prometheus autodécouvre des instances à monitorer et leurs informations (aws ec2 on retrouve les tags etc, les noms de services de consul etc). Et vous allez pouvoir ajouter ces informations complémentaires du discovery à votre liste de labels en utilisant le relabel.

scrape_configs:
  - job_name: Consul
    consul_sd_configs:
      - server: '192.168.57.10:8500'
        datacenter: 'mydc'
    relabel_configs:
      - source_labels: [__meta_consul_service]
        target_label: job

Dans cet exemple, l’information nom de service de consul vient compléter le label nommé « job ».

Les filtres permettent d’affiner les requêtes promql et limiter les résultats. Par exemple pour ne prendre en compte que le device eth0 :

node_network_receive_bytes_total{device="eth0"}

Le filtering se fait donc dans les labels mentionnés entre les accolades et la valeur mentionnées.

On peut également utiliser les regex pour plus de fléxibilités :

node_network_receive_bytes_total{device=~"eth.+"}
node_network_receive_bytes_total{device=~"eth0|lo"}

Voici donc la fin de ces premiers pas avec prometheus. Totu devops doit avoir quelques notions dans ce domaine. Je vous propose de retrouver les tutorials prometheus ici.

Top5 des vidéos devops en août 2020 !!!

La chaine youtube xavki marche bien et c’est surtout grâce à vous. Je n’ai pas trop chomé cet été finalement moi qui pensais faire une pause. Et comme je suis un addict dès que j’ai quelque chose qui me branche en finalement je n’aurais pas fait de pause.

Mon plaisir c’est de vous voir venir et revenir sur cette chaine. Et pour cela vous proposer du contenu intéressant. J’évite de faire le buzz si ce n’est de prendre des technologies à la mode dans le monde du devops.

Les dernières technologies auront été : kvm, traefik, ELK, terraform, prometheus et grafana… et j’en ai pas fini avec elles.

Alors ce top 10 de la chaine xavki ? car je suis bien incapable de dresser un top 10 à l’échelle du web il y a tellement de choix et de bons contenus.

Voici donc les vidéos les plus consultées pour le mois d’août et je vous en dis mon ressenti.

1. Docker : Premier Pas

C’est la vidéo la plus vu mais pour autant j’en suis d’autant plus déçu. Paradoxal non ? en effet, elle fait partie des premières vidéos et son son est très mauvais. Mon approche pédagogique n’est pas encore là non plus . Alors pourquoi elle marche ? docker est recherché et les tutorials en français introduisant cette technologie n’était pas si courante à l’époque. Du coup elle s’est faite sa place avec ses likes.

2. Traefik, l’introduction

Autant l’introduction à docker m’a pas forcément apporté un énorme plaisir, autant que ce genre de vidéo marche me fait plaisir. Pourquoi ? une technologie française qui marche fort en ce moment, un besoin d’en parler et le réelle sentiment que vous recherchez ce genre d’informations.

Traefik est une technologie que j’adore en ce moment pour son dynamisme et ce qu’il l’entoure. D’ailleurs je crois que je suis traefik ambassador même si je n’en ai pas réellement le niveau.

3. Kubernetes, présentation des tutorials de la chaine

Cette playlist fait partie de mes tops formations. Je peux réellement avoir le sentiment de vous faire converger vers des niveaux un peu plus pointus à chauqe fois et c’est quelque chose que j’apprécie. Bien sûr Kubernetes est à la mode et ça aide mais présenter la simple liste des vidéos à venir n’est pas forcément quelque chose de recherché. Mais c’est déjà un pas vers la formation. Comprendre et découvrir un plan de formation c’ets déjà se former à mon sens.

4. Gitlab, oui c’est recherché

Dans cette vidéo j’ai tenté de survoler et présenter les opportunités apportées par Gitlab. Un formidable outil qui a tendance à créer une forte dépendance. Petite société qui a su se faire une place parmi les très grand parmi les sociétés côtées boursières américaines. La petite société a bien évoluée autour de l’automatisation du déploiement de votre code applicatif mais pas forcément. Ils ont su intégré des technos tendances et inévitables comme : grafana, terraform, kubernetes???

5. Jenkins peut être ce qui me représente le plus…

Une vidéo simple, un peu sans prétention qui vous présente jenkins. Jenkins est un acteur historique dans le domaine du scheduling. Malgré son ancienneté, il est encore présent parmis les leaders. Et surtout sa communauté abondante rend cet outil ultra-polyvalent dans des domaines variés : déploiement, datas, infrastructure…

J’aime vraiment beaucoup ce côté polyvalent et discret mais toujours présent ce qui en démontre sa robustesse et son efficacité.

A vous de me dire à travers les commentaires dans les vidéos, les pouces bleus ou rouges, ce que vous pensez de tout cela.

Même si j’ai des regrets sur les vidéos réalisées au début de la chaine xavki, il faut l’accepter. On vient d’où l’on vient et l’on évolue. D’ailleurs il me semble plus intéressant d’évoluer et de comprendre ce process d’évolution que de déjà tout connaître sans évoluer.

Allé je vous laisse apprécier ou pas tout cela. Vous abonner ou non… voir même devenir membre VIP. A vous de voir appréciez, votre liberté de choix.

Ne pas s’éparpiller sur les sujets et les technos, mais bon…

La fin de la période des vacances d’été arrive, parfois tristement pour certains mais c’est ainsi il faut retourner au boulot. Je n’ai pas pris de vacances et cela s’en est peut être ressenti sur la chaine Xavki.

Du coup, j’ai été pas mal centré sur la chaine durant cete période. Parfois trop certainement avec les débordements que cela donne mais qu’il faut maitriser.

Au début j’ai tenté de maîtriser mon programme de tutorials pour éviter de me disperser. Mais finalement je pense que je me suis un peu étallé. En effet, je me suis dit que pour un devops toucher un peu à tout ce qui m’intéresse, reste nécessaire.

Les tutorials ELK où comment éplucher une documentation ? lol

Bon j’ai tout de même fait un bon focus sur ELK avec déjà plus de 90 vidéos. Non pas que j’ai réalisé des trucs compliqués mais j’ai tenté d’être un peu exhaustifs sur les possibilités d’utilisations de la stack ELK.

Dans le cadre de la réalisation de ces tutos, j’ai pu me rendre compte à quel point, j’avais une méconnaissance de cet outil et des opportunités qu’il propose. En effet, entre les beats, elasticsearch, logstash, kibana… il est possible de réaliser de très nombreuses choses.

On limite souvent cette stack à simplement lui injecter des logs mais elle va bien au-delà.

On s’en sert parfois comme stockage de documents et là encore, elle permet bien plus. Logstash à lui seul est un réel ETL (Extract Transfert and Load). Il permet de gérer de nombreux traitements de données, voir même d’extraire d’une base sql vers du nosql, faire intervenir du kafka etc.

Bref j’ai bien apprécié. J’ai pu aussi découvrir opendistro la version opensource d’une partie de stack et mis à disposition par AWS. Très kool.

Terraform et KVM en support

Terraform est un sujet qui me tient à coeur. En effet j’estime que cet outil signé hashicorp est nécessaire dans la caisse à outils de tout bon devops. Mieux il est souhaitable de maitriser la stack d’automatisation et d’orchestration : packer, ansible, terraform.

Et pour découvrir terrafomr je me suis dit que tout le monde ne souhaitait pas forcément mettre la main dans le cloud directement. Du coup j’ai regardé les providers pour tenter de trouver de meilleurs points d’entrées permettant de faire la passerelle avec des travaux déjà proposés sur la chaine.

Ainsi, j’ai fait plusieurs tutos sur les providers docker et kubernetes avec de la mise en application autour de wordpress. Et maintenant, je creuse autour de KVM, avec l’occasion aussi de faire des vidéos autour de KVM. Un bon moyen de se passer de virtualbox et vagrant pour pratiquer encore plus du terraform.

Et d’autres sujets pour se mettre en ordre

D’autres sujets sont venus dans le même temps.

Traefik, depuis la version 2, le reverse proxy français montre des choses très intéressantes avec des configurations plus dynamiques. Et donc après avoir examiné un peu haproxy, je me suis dit il va falloir initier cette playlist pour y revenir plus tard sur les sujets plus profonds comme l’ingress dans kubernetes etc.

Loki me tentait bien à force d’avoir épluché ELK, je me demandais en quoi ce projet de grafana labs était différent. Donc j’ai fait quelques tutorials loki pour découvrir l’outils. J’en retiens sa simplicité et son intégration à grafana pour centraliser la supervision globale : monitoring, logging et tracing.

Et un peu de cassandra. Découvrir cassandra c’est ouvrir une boite remplie de concepts très intéressants, mettant en évidence la disctinction entre sql et nosql.

Et le diverstissement autour de vagrant

Pour gagner du temps et réaliser des tests, des tutos, des démos, j’utilise la plupart du temps vagrant. ET à force de celà je me suis dit l’efficacité de notre apprentissage repose dans une mise en situation rapide via une VM ou une infrastructure rapidement à disposition.

Pour mettre cela en évidence, je me suis dit et si je proposais à tout le monde de découvrir vagrant tout en lançant un cluster kubernetes avec un peu d’automatisation via kubespray. Un moyen rapide et fiable pour avoir un lcuster kubernetes sous la main notamment pour faire des tests d’outils liés à k8s.

Et j’y ai ajouté un wordpress avec du nfs pour compléter ce cluster et faire en sorte d’avoir un applicatif dans ce cluster fonctionnel.

Les chiffres dans tout ça ?

La chaîne marche toujours très bien. Nous sommes déjà à plus de 13000 abonnés, 200 membres youtube, plus de 800 vidéos.

Dans quelques jours, le nombre de vues franchira les 800k, un grand pas avant le million que j’ai vraiment hâte de franchir.

Et tout les retours sont de très forts encouragements à poursuivre ces efforts.

Bref un grand merci pour m’aider dans cette aventure!!!

Manipuler une API via une interface graphique avec Postman

Que vous soyez développeur frontend ou backend, une étape incontournable du développement d’une application web est l’appel vers le serveur. Plus votre application croit, plus ces appels sont nombreux. Si dans certains cas vous pouvez faire ces appels via votre navigateur, le plus souvent il faudra un autre outil pour pouvoir lancer ces appels et vérifier que votre développement a bien fonctionné.

L’outil Postman est l’incontournable pour pouvoir manipuler efficacement des appels API via une interface graphique.

Pourquoi utiliser Postman ?

Dès lors que vos appels API impliquent des appels autres que des requêtes GET, vous aurez besoin d’avoir un outil. Saisir ses requêtes curL à la main n’étant pas une option pour être productif, il faut utiliser un client graphique pour accélérer ses tests manuels.

Postman propose une interface graphique très simple d’utilisation pour effectuer ses appels HTTP en paramétrant la méthode, l’url, les query params, le header et, le cas échéant, body.

Postman est très pratique lors du développement d’une API ou lorsqu’on cherche à découvrir une API tierce en vue de l’intégrer dans son application.

Accélérer son développement

Postman va bien au delà de pouvoir effectuer ses requêtes http via une interface graphique. Son véritable atout vient de sa capacité à stocker certaines données en variables et de pouvoir lancer de manière séquentielle plusieurs appels API d’affilé.

Ainsi, tester un flux de comportement comme si un utilisateur allait manipuler votre API est possible en créant une collection d’appels API. Vous pourrez définir en variable certaines données qui sont renvoyés en tant que réponse d’une requête précédente et définir un comportement à suivre en fonction des résultats.

Vous pouvez également utiliser de la donnée externe, via un fichier CSV ou JSON afin de faire tourner vos requêtes. Ce cas est utilisé pour initialiser un échantillon de base de donnée en vue de faire quelques tests manuels.

Alternatives à Postman

Des alternatives gratuites et payantes à Postman existent. L’application Insomnia, compatible Mac, Windows et Linux, est une alternative gratuite et plus simple que Postman. Elle offre moins de fonctionnalités au bénéfice d’avoir une interface plus épurée.

Paw est un client Mac, vendu à 49€, offrant des fonctionnalités au moins aussi poussé que Postman. Son interface graphique est très travaillée et rend son utilisation très agréable. Cependant, son prix décourage beaucoup d’utilisateurs qui trouvent leurs compte avec postman gratuitement

Et le bon vieux Jmeter

Enfin, vous pouvez aussi vous tourner vers un outil plus ancien : Jmeter. Ce dernier est plus réputé pour être capable de faire des tests de charge mais sa polyvalence lui permet sans souci de faire les tests de vos routes d’API. Gratuit et appartenant à la fondation apache, il nécessite une certaine pratique mais vous permettra de réaliser des tests complets allant jusque vérifier la bonne insertion des données dans la base de données de votre API.

Et l’aventure continue…

Après plusieurs semaines, il est temps pour moi de refaire un petit sur cette aventure xavki. Et une fois de plus, j’en tire beaucoup de points positifs.

Les nouvelles playlists sont attendues

Dernièrement, j’ai ouvert de nouvelles playlists : terraform, ELK, cassandra, packer ou encore mindset.

Et à chaque fois le public a répondu présent. Bien sûr l’idée pour moi n’est pas de m’étaler sans rentrer un peu dans chaque technologie mais d’offrir un échantillon du potentiel de chaque outil.

Et c’est bien là l’objectif de la chaine, vous faire et au passage me faire découvrir le périmètre de chaque outil. Pour moi un devops doit surtout avoir une vision générale pour savoir piocher dans sa caisse à outils pour trouver la clef qui correspond le mieux. Et cela en prenant en compte, l’environnement, les objectifs et également son niveau de connaissances et compétences.

Votre carrière et vos qualités à mettre en valeur

Xavki vise à nous faire progresser sur le côté technologique mais aussi sur les aspects liés à notre métier en général.

Ainsi, j’ai souhaité ouvrir un volet RH avec une orientation carrière. L’idée est de se donner les outils, les réflections pour faire les bons choix aux bons moments. Comment aussi se rassurer face à des questions dont on est peu habitées de traiter.

Un autre volet, Mindset, me permet de proposer un angle plus comportemental. Non pas que l’on soit tous mauvais moi. Mais plutôt que l’on peut parfois ne pas se donner toutes les chances pour progresser, s’étendre encore plus vite et prendre vraiment son envol. C’est dans ce sens que j’ai abordé la question de la patience (qui peut me manquer cruellement parfois).

Dans une prochaine vidéo, j’y aborderai « apprendre, comprendre et montrer ». En essayant de faire le tour de la question de l’apprentissage en entreprise avec des personnes de profils différents et que ce soit sous l’angle apprenant que enseignant. C’est pour moi aussi l’occasion de comprendre pourquoi les gens aime apprendre via la chaine xavki… pourquoi ça marche ??

Recentrer des liveki

Depuis 3 mois, je cherche la bonne formule pour les lives et les choses progressent. Il me semble que les interventions sont une bonnes formules. Maintenant il reste à trouver le bon équilibre pour ne pas en avoir trop et être dans la ligne de la chaine. C’est à dire restons fortement en lien avec le monde professionnel.

Je pense que les prochains liveki dureront autour de 2h avec pas plus de 2 intervenants. Par ailleurs, j’essairai d’avoir un peu plus de lien avec le monde pro c’est à dire plutôt des personnes qui présentent des choses sur les technos devops. J’ai pris contact avec plusieurs sociétés que je connais via mon réseau (rancher, haproxy, traefik…). Le but étant pour elles de nous montrer des choses simples faites à partir de leurs outils et pour les spectateurs de pouvoir poser des questions sur des cas d’usages.

Je trouve cet équilibre assez sympathique et plus en lien avec l’esprit des tutos.

En outre, je pense continuer à faire un concours pour chaque liveki qui permettra aux gagnants d’avoir des goodies de formes diverses (peut être même des goodies xavki).

Structurer la vision globale

Depuis plusieurs mois, je trouve que Youtube ne permet pas de voir efficacement l’intégralité de la chaine. C’est pourquoi, je me suis mis à faire unpetit script python pour collecter la liste des vidéos et la remettre en forme au format markdown. Le résultat est présent sur deux dépôt au choix :

Je commence aussi à faire un peu de selenium pour permettre d’avoir un autre regard sur la chaine avec des stats sympas comme le top de commentateurs etc.

La mise en place des membres permet aussi de trouver un équilibre entre une publication qui ne spam pas et permettre de contribuer à la chaine. Ainsi, les membres peuvent avoir accès aux vidéos sans délai contrairement aux abonnés qui doivent attendre leur publication. Cela va permettre de rester sur un rythme de 3 vidéos par semaine ce qui est déjà assez dense.

Les sujets à venir ?

Une petite liste des choses que j’ai en tête pour la suite :

  • terraform plus que tout
  • packer
  • imbrication packer > terraform > ansible
  • refaire la playlist ansible
  • des tutoriels sur selenium
  • mise en place d’une infra complète de microservices de démonstration avec des tutoriels pour apprendre à faire le tout (code et infra)
  • kafka pour les débutant
  • nginx l’inévitable
  • traefik 2
  • kong peut être…

Voilà j’espère que vous prenez tous du plaisir à regarder la chaine. A très bientôt !!!