Archives mensuelles : septembre 2018

[Ansible] : comment installer un client et un serveur ntp ?

Cet article fait suite à mon fil rouge sur ansible. L’idée c’est de vous relater quelques moments de mon autoformation dans ce domaine. Pour moi c’est aussi le moment de me pencher différement sur ce que je fais et de constituer mon bloc-note.

Avant de commencer, je ne vais pas revenir dessus dans le détail mais j’utilise un script sympa (enfin je trouve). Il permet de me créer un ensemble de conteneurs façon VM (debian et redhat depuis la dernière évolution). Ainsi j’ai une plateforme de développement et je peux simuler des lancements de playbook sur un parc de machines. Pour en savoir plus rendez-vous sur cet article qui présente le script et les grandes lignes.

Donc j’ai lancé deux fois le script et je possède pour l’exemple 4 machines (2 debian stretch et 2 centos7).

Et voilà. Maintenant comment je peux faire pour avoir 1 serveur ntp et 3 serveurs clients ? L’idée c’est de faire en sorte qu’un seul serveur soit exposé et soit utilisé pour contacter les ntp externes.

ansible-ntp

Ainsi on veut avoir le schéma :

ntp_externes >> ntp_serveur >> ntp_clients

1. Les principes des clients et du serveur (sans ansible)

Là encore on va aller à l’essentiel de la configuration. Vous trouverez facilement des articles clairs et courts comme celui-ci qui vous donnera ce qu’il faut pour installer un ntp.

D’un côté, sur le serveur ntp est installé ntp. Il doit au niveau de sa conf taper vers les serveurs externes et surtout accepter les requêtes des autres serveurs. Pour cela il faut supprimer simplement dans /etc/ntp.conf la ligne :

restrict default nomodify notrap nopeer noquery

Et ajouter la localisation ntp :

ntp_area: 'fr'

De l’autre côté pour les serveurs clients, il faut juste modifier les serveurs vers lesquels on fait la synchro dans /etc/ntp.conf. Les serveurs par défaut deviennent par exemple :

server 172.17.0.2 ibusrt

Pour vérifier le bon fonctionnement, il suffira de faire un ntpq -p et voir où les machines vont se synchroniser.

2. NTP avec ansible c’est facile

Bien sûr que c’est facile car ntp est un utilitaire de base des serveurs web ou autres. Ansible Galaxy vous propose donc de très bon rôles. Et j’aurais tendance à dire comme d’habitude c’est geerlingguy qui va vous le proposer avec geerlingguy.ntp.

Alors pour le mettre en place dans votre répertoire de rôles il suffit de faire :

ansible-galaxy install -p roles geerlingguy.ntp

et dedans on a ceci mais on ne va toucher à rien :

.
├── defaults
│   └── main.yml
├── handlers
│   └── main.yml
├── LICENSE
├── meta
│   └── main.yml
├── README.md
├── tasks
│   ├── clock-rhel-6.yml
│   └── main.yml
├── templates
│   ├── clock.j2
│   └── ntp.conf.j2
├── tests
│   ├── README.md
│   └── test.yml
└── vars
├── Archlinux.yml
├── Debian.yml
├── FreeBSD.yml
├── RedHat.yml
└── Suse.yml

Nous avons donc un rôle ntp qui ne demande qu’à tourner. Pour cela mettons à jour notre liste de hosts.yml de notre inventory :

all:
  children:
    ntp-client:
      hosts:
        172.17.0.3:
        172.17.0.4:
        172.17.0.5:
    ntp-server:
      hosts:
        172.17.0.2:

Vous voyez que j’ai entré les ip de mes conteneurs docker. Elles sont classées en 2 groupes ntp-server et ntp-client.

Maintenant je vais créer 2 group_vars (deux répertoires avec un fichier yaml chacun) :

.
├── group_vars
│   ├── ntp-client
│   │   └── ntp-client.yml
│   └── ntp-server
│       └── ntp-server.yml

Puis je complète les fichiers de la manière suivante (en prenant en compte ce que nous avons abordé dans le paragraphe 1.).

ntp-client.yml

ntp_manage_config: True
ntp_servers:
- "172.17.0.2 ibusrt"

ntp-server.yml

ntp_manage_config: True
ntp_restrict:
- "127.0.0.1" 
- "::1" 
- "-4 default kod notrap nomodify nopeer noquery" 
- "-6 default kod notrap nomodify nopeer noquery"

Et là c’est terrible car je vous dis « nous avons fait le plus dur » ! Car maintenant on lance le playbook :

ansible-playbook -i hosts.yml --user=oki playbook-ntp.yml

Et la bingo

PLAY RECAP ************************************************************************************
172.17.0.2 : ok=7 changed=0 unreachable=0 failed=0 
172.17.0.3 : ok=8 changed=0 unreachable=0 failed=0 
172.17.0.4 : ok=8 changed=0 unreachable=0 failed=0 
172.17.0.5 : ok=8 changed=0 unreachable=0 failed=0

Comme vous le voyez moi je n’ai pas de changement car j’ai fait tourner le playbook deux fois.

Maintenant rendez vous sur le serveur ntp :

[root@7dcab8fb52ed ~]# ntpq -p
remote refid st t when poll reach delay offset jitter
================================================================
dev.rudloff.pro 209.176.15.122 3 u 53 64 1 35.024 -29.279 8.299
clients0.arcani 131.188.3.223 2 u 53 64 1 41.120 -23.491 9.220
myminers.net 10.21.137.1 2 u 53 64 1 28.079 -27.255 13.304
*master.servme.f 213.251.128.249 2 u 53 64 1 22.207 -30.641 11.5

et sur le client :

[root@6c6c89bc23ac ~]# ntpq -p
remote refid st t when poll reach delay offset jitter
================================================
172.17.0.2 178.33.111.48 3 u 1 64 1 0.079 0.018 0.000

Nos avons donc bien installé un serveur ntp qui se met à jour sur des serveurs externes et des clients ntp qui se mettent à jour sur notre serveur maitre.

Si cet article vous a plus partagez-le et n’hésitez pas à vous abonner pour ne pas manquer les prochains articles.

[Oracle] : comment réaliser un explain plan ?

L’explain plan chez oracle c’est une possiblité de découvrir comment le moteur traite vos requêtes. Ainsi, vous voyez le cheminement réalisé par le moteur pour vous apporter le résultat.

Explain plan est donc le prinicipal outil pour optimiser vos requêtes et vos bases. Mais attention, le plus dur n’est pas de réaliser l’explain plan mais sa lecture et son interprétation (et ça il faut des années pour devenir un champion des l’optimisation).

Comment lancer un Explain Plan d’une requête ?

Si nécessaire, mettez en place le module utlxplan.sql

@$ORACLE_HOME/rdbms/admin/utlxplan.sql

Ensuite, définissez le nom de votre plan :

RENAME PLAN_TABLE TO monplan;

Ensuite lancez la requête qui va construire votre explain plan.

EXPLAIN PLAN FOR
SELECT champs1, champs2, champs3 FROM matable;

Maintenant, vous pouvez consulter le résultat en utilisant le DBMS_XPLAN.

SELECT PLAN_TABLE_OUTPUT
FROM TABLE(DBMS_XPLAN.DISPLAY());

Si vous souhaitez voir quelques exemple sur comment paser un explain, vous pouvez consulter la page du site oracle.

Comment l’analyser ?

Clairement, ce n’est pas dans cet article que vous allez apprendre à optimiser vos requêtes et bases.

Sur le blog de Markus Winand, vous trouverez cette page qui va vous permettre de trouver les principaux termes que vous retrouverez dans les résultats d’un explain plan. En effet, le plan repose principalement sur l’exploitations de jointures et d’index pour vous apporter le résultat le plus vite possible.

Un résultat resemble à ceci :

| Id| Operation                   | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
| 0 | SELECT STATEMENT            |               |     4 | 16208 |     3   (0)| 00:00:01 |
| 1 |  TABLE ACCESS BY INDEX ROWID| CONSULTANT    |     4 | 16208 |     3   (0)| 00:00:01 |
|*2 |   INDEX RANGE SCAN          | CONSULTANT_PK |     4 |       |     2   (0)| 00:00:01 |

Source : SOAT

Dedans on peuty découvrir :

  • le type d’opération
  • le nombre de lignes parcourues
  • le volume utilisé
  • le coût
  • le temps

Mais le principal c’est l’ordre. Un plan se lit de bas en haut. Le moteur commence par les actions du bas et remonte progressivement. Donc dans l’exemple, il accède à un index CONSULTANT_PK puis à la table CONSULTANT.

En apprendre plus par les experts oracle

Pour cela il existe une très bonne vidéo d’une interventionde Maria Colgan.

Et si vous voulez en voir une un peu plus courte mais déjà bien complète, commencez par celle de Jeff Smith.

Je vous invite à lire le document : xplan_webinar.pdf

[Ansible] : commençons simplement : copie de fichiers, modification/écriture avec copy et lineinfile

Précédemment, je vous avais fait part de ma volonté de me lancer dans ansible et de vous partager cette expérience d’apprentissage.

Un précédent article vous présentait un script qui me permet de mettre en place un « centre serveur de poche » à partir de conteneurs (attention ce ne sont que des conteneurs pas de VM donc pas des serveurs… pas la peine de lancer des discussions à ce sujet). Bref, l’idée de cet article était de vous expliquer mon script pour mettre en place une infrastructure légère permettant de me faire la main sur ansible.

Et le bilan c’est que ça marche très bien et que c’est bien plus léger que tout ce qui est à partir de VM. C’est extrèmement pratique pour bosser sur son portable car on peut faire et réinitialiser les serveurs très vites.

Maintenant, il faut se former.

Le fichier inventory, la liste des serveurs

L’inventory est le fichier contenant la liste de référence de vos machines. Dans mon cas j’ai lancé deux conteneurs (machine) 172.17.0.2 et172.17.0.3. En avoir plusieurs c’est vraiment bien pour créer des variations au niveau des hosts et ainsi approfondir le fonctionnement de ansible.

Mon fichier se nomme hosts (comme souvent sur ansible) :

└─ $ ▶ cat hosts
[web]
172.17.0.2
172.17.0.3

J’ai choisi le format init et non le yaml car je suis tombé avec un bug en lien avec python 3.5 (ansible ne lisait pas le yaml de l’inventory).

Pour tester votre inventory, vous pouvez lancer :

ansible -i hosts all --list-hosts

Ensuite, vous pouvez tester une commande linux sur votre parc, par exemple « uptime » :

00:07:33 - oki @ doki ~/autoform_ansible 
└─ $ ▶ ansible -i hosts all -u oki -m shell -a "uptime"
172.17.0.3 | SUCCESS | rc=0 >>
22:07:35 up 1:26, 1 user, load average: 1.00, 0.75, 0.66

172.17.0.2 | SUCCESS | rc=0 >>
22:07:35 up 1:26, 1 user, load average: 1.00, 0.75, 0.66

L’arborescence

Extrèmement importante cette arborescence dans un outil d’orchestration comme ansible. En effet, cela peut vite tourner au boxon tellement vous aller générer de fichiers.

De base si on ne rentre pas dans les roles :

.
├── group_vars
│   └── web
├── hosts
├── host_vars
│   ├── 172.17.0.2
│   └── 172.17.0.3
├── playbook-manip.yml

  • group_vars : contient les variables des groupes (regroupement de serveur) par exemple « web » dans mon cas
  • hosts : c’ets l’inventory de nos machines classées par groupe
  • host_vars : contient les variables des machines (pour spécifier à la machine une variable)
  • playbook.yml : les actions à réaliser

Les deux éléments centraux sont donc : la liste des machines et les actions à réaliser dessus.

Le playbook

On l’a dit le playbook contient les actions à réaliser (et par qui et sur qui). L’entête sert principalement à définir par qui et sur qui de cette manière :

---
- name: Lancement des actions
  hosts: web
  remote_user: oki
  become: yes
  tasks:
  • hosts : pour dire sur quelles machines ou quel groupe on travaille (en l’occurence web dans mon exemple)
  • remote_user : qui va exécuter les actions
  • become : permet d’élever les privilèges si nécessaire pour faire les actions
  • tasks : indique la liste des actions à venir

Le « – name: » est extrèment important. Il permet sera défini de nombreuse fois tout au long de notre code et permet au lancement du playbook de savoir où nous en sommes. C’est donc indispensable pour débugger.

La première action que nous allons réaliser c’est de copier un fichier présent au même niveau que notre playbook (c’est moche je sais mais c’est simple avant tout).

 - name: Transfert de monfichier.txt
   copy:
     src: ./monfichier.txt
     dest: /tmp/monfichier.txt

Nous définissons donc le nom de l’action que nous allons lancer par « – name: ». Puis utilisons le module copy de ansible. Pour copier/coller un fichier il prend deux éléments :

  • src: le fichier source
  • dest: le fichier de destination

Dans une deuxième action nous allons modifier le contenu de mon fichier qui ne contient que « bonjour Xavier » pour le faire contenir « Remplacement salut Xavier ». Et pour cela nous allons utiliser le module lineinfile :

 - name: Modification de monfichier.txt
   lineinfile:
     path: /tmp/monfichier.txt
     regexp: "^bonjour(.*)"
     line: 'Remplacement salut'
     backrefs: yes

Dans cette utilisation de lineinfile je transmets les éléments :

  • path : la localisation de mon fichier à modifier
  • regexp : un élément permettant de retrouver la ligne et capturer un motif (dans mon cas je capture « Xavier » par exemple
  • line : la nouvelle ligne contenant mon texte et « \1 » c’est à dire le motif capturé
  • backrefs : pour utiliser la capture à partir du backslash

Mon playbook au final contient ceci (attention l’indentation doit être stricte, c’est un yaml) :

---
- name: Lancement des actions
  hosts: all
  remote_user: oki
  become: yes
  tasks:

    - name: Transfert de monfichier.txt
      copy:
        src: ./monfichier.txt
        dest: /tmp/monfichier.txt

    - name: Modification de monfichier.txt
      lineinfile:
        path: /tmp/monfichier.txt
        regexp: "^bonjour(.*)"
        line: 'Remplacement salut'
        backrefs: yes

Pour lancer votre playbook sur votre inventory passez :

ansible-playbook -i hosts --user=oki -D playbook-fichier.yml

Et en sortie le résultat du log ansible donne :

PLAY [Lancement des actions] ********************************************************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************************************************
ok: [172.17.0.2]
ok: [172.17.0.3]

TASK [Transfert de monfichier.txt] **************************************************************************************************************************************************************
--- before: /tmp/monfichier.txt
+++ after: /home/oki/autoform_ansible/monfichier.txt
@@ -12,4 +12,4 @@
###############################################################


-Remplacement salut Xavier
+bonjour Xavier

changed: [172.17.0.3]
--- before: /tmp/monfichier.txt
+++ after: /home/oki/autoform_ansible/monfichier.txt
@@ -12,4 +12,4 @@
###############################################################


-Remplacement salut Xavier
+bonjour Xavier

changed: [172.17.0.2]

TASK [Modification de monfichier.txt] ******************************************
--- before: /tmp/monfichier.txt (content)
+++ after: /tmp/monfichier.txt (content)
@@ -12,4 +12,4 @@
###############################################################


-bonjour Xavier
+Remplacement salut Xavier

changed: [172.17.0.3]
--- before: /tmp/monfichier.txt (content)
+++ after: /tmp/monfichier.txt (content)
@@ -12,4 +12,4 @@
###############################################################


-bonjour Xavier
+Remplacement salut Xavier

changed: [172.17.0.2]

PLAY RECAP ***************************************************
172.17.0.2 : ok=3 changed=2 unreachable=0 failed=0 
172.17.0.3 : ok=3 changed=2 unreachable=0 failed=0

[Docker] : comment créer une image à partir d’un conteneur et la pousser ?

Comme dirait l’autre ça va finir par rentrer, nom d’une pipe. Mais cela fait plusieurs fois que je fais cette manip et comme écrire un article m’aide à retenir les choses je vais vous faire partager une manip docker.

Le but aujourd’hui c’est de savoir comment créer une image à partir d’un conteneur existant que vous avez ajustez à votre guise. Dans mon cas c’est un conteneur qui permet d’avoir une debian stretch avec systemd, openssh, sudo et vim. La grosse subtilité c’est d’avoir systemd mais je ne vais pas vous détailler cela aujourd’hui.

docker-image-conteneur

Démo en vidéo :

La première chose à faire c’est de connaître l’id de son conteneur avec un bon docker ps :

└─ $ ▶ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bbb5c547002c debian-systemd "/lib/systemd/systemd" 31 minutes ago Up 31 minutes competent_vaughan

Ensuite il faut commiter tout ceci dans une nouvelle image avec un docker commit (à partir de l’ID de l’image) :

└─ $ ▶ docker commit -m "image stretch + systemd + openssh" bbb5c547002c priximmo/stretch-systemd-ssh

Sivous faite un docker image ls, vous pouvez déjà voir votre image sur votre pc en local.

Puis si vous le souhaitez vous pouvez pousser ceci sur dockerhub ou un autre repository.

docker login
docker push priximmo/stretch-systemd-ssh

Et voilà vous disposez de votre image en local et sur votre dépôt.

Retrouvez l’image en question sur docker hub.

Top commandes linux #9 : git, mdk3, wifi over loading, hypertext, rpm

Comment ça va la team des xavki ? petit à petit l’oiseau fait son nid et vous êtes de plus en plus nombreux à vous abonner… MERCI !!! si ce n’est pas déjà fait vous pouvez le faire dans la colonne de droite je ne pollue personne avec des ventes de ebook gratuits lol et autres méthodes marketing.

Avant de commencer, l’article du blog qui a le mieux marché la semaine dernière est :

 

# git

comparer les deux derniers commits avec un diff

git diff $(git log --pretty=format:%h -2 --reverse | tr "\n" " ")

moins bien que :

git diff HEAD^ HEAD

# sed & HTML

Convertir une url en lien cliquable html (balise <a>)

cat url.txt | sed "s/\([a-zA-Z]*\:\/\/[^ ]*\)\(.*\)/\<a href=\"\">\<\/a\>/"

avec url.txt contenant des liens format : http://monlien.fr

# PS & sort

Lister le top 10 des processus en cours

ps -auxf | sort -nr -k 4 | head -10

# RedHat

Lister les 10 derniers paquets installés avec RPM

rpm -qa --last | head

Article de la semaine :

Vidéo de la semaine : brouiller un wifi avec mdk3 (démo)

https://www.youtube.com/watch?v=FF_tVKPOelY

[Ansible] : le samedi c’est debug de mon erreur avec include_tasks

Pour une fois je publie un article le samedi. Ne vous inquiétez pas, pas de spam. D’ailleurs si ce n’est déjà fait vous pouvez vous inscrire pour recevoir les articles du blog et ne pas manquer les prochains.

J’aimerai revenir sur ma mésaventure ansible de la semaine.

En fait, je suis toujours en train de monter en compétences sur ansible. Hier je testé un rôle tout simple de ntp (dont la source est le très bon geerlingguy).

Donc j’importe mon rôle :

ansible-galaxy install -p roles geerlingguy.ntp

Et là paff ça marche pas.

The error appears to have been in '/home/oki/autoform_ansible/roles/geerlingguy.ntp/tasks/main.yml': line 16, column 3, but may
be elsewhere in the file depending on the exact syntax problem.

Pourtant l’auteur de la source est ultra fiable et les dernières mises à jour datent de 22 jours. Là j’ai un gros doute.

Donc mon premier réflexe (le mauvais), je recherche sur internet à partir du message d’erreur. Je vois donc que l’on parle de la version 2.4 et je ne suis qu’en 2.3. Bon ben je décide de monter de version.

Me voici en 2.4 et là je tombe sur une autre erreur : mauvaise reconnaissance de l’inventory.

 [WARNING]: * Failed to parse /home/oki/autoform_ansible/hosts with constructed plugin:
Unable to parse /home/oki/autoform_ansible/hosts: Syntax Error while loading YAML.

Pas de bol. Donc je recherche et là je tombe sur quelqu’un qui explique qu’un patch est passé pour régler le pb en 2.4.1. Ce que je fais je monte de version.

Ah au fait pour monter de version facilement :

sudo pip install ansible==2.4.1

et la bingo tout marche comme il faut.

Mais le  bon réflexe c’est déjà de voir la doc ansible de include_tasks. J’aurais vu que cette fonctionnalité est incrémentée à partir de la 2.4. Bon pour l’autre problème c’est autre chose.

[Docker][Ansible] : comment se créer un mini datacenter de test sans VM ? (parc de conteneurs)

Datacenter, le terme est bien prétencieux car il ne s’agit ni de machines physiques, ni de vm mais de simples conteneurs docker. L’idée est très simple et je sais que certains d’entre vous ont besoin de ce genre de script : comment créer facilement, à la volée, une série de conteneurs identiques pour reproduire des actions à la manière d’un centre serveur (orchestration, scheduler…).

Attention, ce qui est fait dans ce script et l’image utilisée (que j’ai adapté pour l’occasion) ne prennent pas en compte la sécurité nécessaire pour faire de la production. L’idée est de créer ce mini pool de conteneurs et de le supprimer une fois les manipulations réalisées. En moins de 5 minutes vous avez autant de machine que vous voulez sous la main et dans le même réseau.

Le besoin ? faire des tests sur un parc de « machines »

Pourquoi moins sécurisé que d’autres ? Par exemple, je permets de faire du ssh sur le user root depuis l’extérieur du conteneur. Je mets en place un mot de passe unique pour root et le user. Tout cela pour faire comme si il s’agissait d’une vm ou une machine physique donc de ne plus passer par un « docker exec » pour accéder à root.

Pourquoi faire ? des tests. Dans mon cas, je vais m’en servir pour me faire la main sur Ansible et runner des playbooks sur tout le parc ou sur une partie.

L’intérêt comme je l’ai déjà dit :

  • pouvoir casser et repartir avec des machines vierges en 2 minutes
  • pouvoir en lancer une bonne dizaine (voir plusieurs) sur mon pc
  • avoir un réseau facilement opérationnel
  • switcher d’OS ou d’image à volonté
  • cela reste léger car il n’y a pas de noyau embarqué

Dans le détail du conteneur

De base, j’utilise une image que j’ai créé et mis à disposition sur mon compte dockerhub (priximmo/debian-sshd). Il s’agit d’une image debian officielle à laquelle j’ai ajouté un openssh-server et dont j’ai permis la connexion en ssh sur le user root. C’est ce point qui aura été le plus difficile car je ne voyais pas pourquoi je ne pouvais pas passer root sur les conteneurs docker. Il suffit d’ouvrir /etc/ssh/sshd_config et de passer la clause PermitRootLogin à « yes ».

Le mot de passe root est aussi configuré mais je vous invite à le modifier à l’aide d’une commande docker (en lançant chgpasswd). Mais comme le but est de ne pas garder les conteneurs en fonction hors des phases de test c’est moins grave.

Le script ? c’est du shell et il est dispo sur le github

Quatre options :

  • –proxy : utilisation perso mais à vous de l’adapter vous pouvez avec prévoir d’ajouter votre proxy dans http-proxy.conf
  • –create : par défaut il créé 2 conteneurs mais vous pouvez en mettre autant que vous souhaitez
  • — drop : pour nettoyer les conteneurs créés
  • –infos : donne les ips,users des conteneurs

Dans le create, vous pouvez voir que l’on créé un user du même nom que votre utilisateur courant et on pousse votre clé publique dans le conteneur. On installe aussi python-minimal et sudo, nécessaires pour faire du ansible dans mon cas. Et à la fin de la création j’utilise docker inspect pour récupérer les ip des conteneurs pour donner un petit récapitulatif.

#!/bin/bash

###############################################################
#  TITRE: parc de conteneurs
#
#  AUTEUR:   Xavier
#  VERSION: 1.1
#  CREATION:  17/09/2018
#  MODIFIE: 
#
#  DESCRIPTION: 
#   mot de passe obtenu par :
#          perl -e 'print crypt("password", "salt"),"\n"'
###############################################################

USERNAME=$(id -nu)

if [ "$1" == "--proxy" ];then
	
	if [ -f /etc/systemd/system/docker.service.d/http-proxy.conf ];then
		sudo rm -f /etc/systemd/system/docker.service.d/http-proxy.conf
		sudo service docker restart
	fi 

fi


if [ "$1" == "--create" ];then
	
	nbserv=$2
	[ "$nbserv" == "" ] && nbserv=2
	
	# rapatriement de l'image si elle n'exsiste pas
	echo "Installation de l'image "
	docker pull priximmo/stretch-systemd-ssh:v3.1

	# création des conteneurs
	echo "Création : ${nbserv} conteneurs..."

	# détermination de l'id mini
  id_first=$(docker ps -a --format "{{ .Names }}" |grep "oki-vmparc" | sed s/".*-vmparc"//g  | sort -nr | head -1)
	id_min=$(($id_first+1))

	#détermination de l'id max
	id_max=$(($nbserv + $id_min - 1))

	for i in $( seq $id_min $id_max );do
		echo ""
		echo "=> conteneur ${USERNAME}-vmparc${i}"
    docker run -tid -v /sys/fs/cgroup:/sys/fs/cgroup:ro --name ${USERNAME}-vmparc${i} priximmo/stretch-systemd-ssh:v3.1
		echo "    => création de l'utilisateur ${USERNAME}"
		docker exec -ti ${USERNAME}-vmparc${i} /bin/bash -c "useradd -m -p sa3tHJ3/KuYvI ${USERNAME}"
		echo "Installation de votre clé publique ${HOME}/.ssh/id_rsa.pub"
		docker exec -ti ${USERNAME}-vmparc${i} /bin/bash -c "mkdir  ${HOME}/.ssh && chmod 700 ${HOME}/.ssh && chown ${USERNAME}:${USERNAME} $HOME/.ssh"
		docker cp ${HOME}/.ssh/id_rsa.pub ${USERNAME}-vmparc${i}:${HOME}/.ssh/authorized_keys
		docker exec -ti ${USERNAME}-vmparc${i} /bin/bash -c "chmod 600 ${HOME}/.ssh/authorized_keys && chown ${USERNAME}:${USERNAME} ${HOME}/.ssh/authorized_keys"
		docker exec -ti ${USERNAME}-vmparc${i} /bin/bash -c "echo '${USERNAME}   ALL=(ALL) NOPASSWD: ALL'>>/etc/sudoers"
		docker exec -ti ${USERNAME}-vmparc${i} /bin/bash -c "service ssh start"
	done
	echo ""
	echo "Liste des ip  attribuées :"
	for i in $( seq $id_min $id_max );do

	infos_conteneur=$(docker inspect -f '   => {{.Name}} - {{.NetworkSettings.IPAddress }}' ${USERNAME}-vmparc${i})
	echo "${infos_conteneur} - Utilisteur : ${USERNAME} / mdp:password"
	
	done

fi

if [ "$1" == "--drop" ];then

	for i in $(docker ps -a --format "{{ .Names }}" |grep "${USERNAME}-vmparc" );do
		echo "     --Arrêt de ${i}..."
		docker stop $i
		echo "     --Suppression de ${i}..."
		docker rm $i
		done

fi

if [ "$1" == "--infos" ]; then

	for i in $(docker ps -a --format "{{ .Names }}" |grep "vmparc" );do
		infos_conteneur=$(docker inspect -f '   => {{.Name}} - {{.NetworkSettings.IPAddress }}' ${i})
		echo "${infos_conteneur} - Utilisteur : ${USERNAME} / mdp:password"
	done

fi

if [ "$1" == "--start" ];then
	
	sudo /etc/init.d/docker start

	
        for i in $(docker ps -a --format "{{ .Names }}" |grep "vmparc" );do
                echo "     --Démarrage de ${i}..."
                docker start $i
                #echo "     --Démarrage de sshd sur ${i}"
                #docker exec -ti ${i} /bin/bash -c "sudo service ssh start"
        done
echo ""
echo "#### Récap des infos ####"
echo ""


	for i in $(docker ps -a --format "{{ .Names }}" |grep "${USERNAME}-vmparc" );do
                infos_conteneur=$(docker inspect -f '   => {{.Name}} - {{.NetworkSettings.IPAddress }}' ${i})
                echo "${infos_conteneur} - Utilisteur : ${USERNAME} / mdp:password"
        done


fi

[Mysql] :Comment diagnostiquer et optimiser votre base et moteur ? avec mysqltuner

Mysql est une base que l’on trouve souvent derrière de nombreux outils web (par exemple wordpress…). Elle s’est généralisée avec la montée en puissance de WAMP ou LAMP. Mais souvent les moteurs et les bases installés sont installés avec des valeurs par défaut sans optimisation. C’est pourquoi, de temps en temps, il est nécessaire de faire des optimisations (défragmentation de base…).

Dans ce genre de travail d’optimisation de bases, on cherche des outils qui permettront de faire une partie du travail à notre place. Et c’est là que vous trouverez votre bonheur avec le binaire intitulé mysqltuner.

Il est facile à installer et comme vous le verez ci-dessous son rapport est plutôt bien fichu. tout cela en perl donc on aime bien.

Pour l’installer rien de plus simple :

sudo apt-get install mysqltuner

Et après on le lance simplement :

└─ $ ▶ mysqltuner

 >>  MySQLTuner 1.3.0 - Major Hayden <major@mhtx.net>
 >>  Bug reports, feature requests, and downloads at http://mysqltuner.com/
 >>  Run with '--help' for additional options and output filtering
Please enter your MySQL administrative login: ------
Please enter your MySQL administrative password: 
[OK] Currently running supported MySQL version 5.5.60-0+deb8u1
[OK] Operating on 64-bit architecture

-------- Storage Engine Statistics -------------------------------------------
[--] Status: +ARCHIVE +BLACKHOLE +CSV -FEDERATED +InnoDB +MRG_MYISAM 
[--] Data in MyISAM tables: 714M (Tables: 400)
[--] Data in PERFORMANCE_SCHEMA tables: 0B (Tables: 17)
[--] Data in MEMORY tables: 496K (Tables: 4)
[--] Data in InnoDB tables: 55M (Tables: 14)
[!!] Total fragmented tables: 28

-------- Security Recommendations  -------------------------------------------
[!!] User 'rundeck@%' has no password set.

-------- Performance Metrics -------------------------------------------------
[--] Up for: 18d 0h 10m 24s (136M q [87.417 qps], 261K conn, TX: 113B, RX: 23B)
[--] Reads / Writes: 80% / 20%
[--] Total buffers: 192.0M global + 2.7M per thread (151 max threads)
[OK] Maximum possible memory usage: 597.8M (15% of installed RAM)
[OK] Slow queries: 0% (81/136M)
[OK] Highest usage of available connections: 19% (29/151)
[OK] Key buffer size / total MyISAM indexes: 16.0M/266.3M
[OK] Key buffer hit rate: 99.5% (362M cached / 1M reads)
[OK] Query cache efficiency: 94.4% (123M cached / 131M selects)
[!!] Query cache prunes per day: 258354
[OK] Sorts requiring temporary tables: 0% (0 temp sorts / 508K sorts)
[!!] Temporary tables created on disk: 35% (1M on disk / 3M total)
[OK] Thread cache hit rate: 99% (1K created / 261K connections)
[!!] Table cache hit rate: 0% (400 open / 393K opened)
[OK] Open file limit used: 73% (756/1K)
[OK] Table locks acquired immediately: 99% (9M immediate / 9M locks)
[OK] InnoDB buffer pool / data size: 128.0M/55.5M
[OK] InnoDB log waits: 0
-------- Recommendations -----------------------------------------------------
General recommendations:
    Run OPTIMIZE TABLE to defragment tables for better performance
    Enable the slow query log to troubleshoot bad queries
    When making adjustments, make tmp_table_size/max_heap_table_size equal
    Reduce your SELECT DISTINCT queries without LIMIT clauses
    Increase table_open_cache gradually to avoid file descriptor limits
    Read this before increasing table_open_cache over 64: http://bit.ly/1mi7c4C
Variables to adjust:
    query_cache_size (> 16M)
    tmp_table_size (> 16M)
    max_heap_table_size (> 16M)
    table_open_cache (> 400)

Vous avez donc une liste de recommandations qui vous permettront d’atteindre votre but pour optimiser votre moteur et votre base :

  • faire un OPTIMIZE TABLE
  • activé le slow query
  • ajuster des variables de configuration  : tmp_table_size…
  • réduire les volume de « SELECT DISTINCT » en utilisant la clause « LIMIT »

Les choses sont donc relativement bien formulées. Je pense que nous aurons l’occasion de revenir en détail sur certaines de ces actions et de leurs effets.

De votre côté utilisez vous ce genre d’outils ?

[Linux] : lister les ports en écoute sur une machine

La base pour les sysadmin, on a souvent besoin pour diagnostiquer des problèmes de lister les ports en écoute sur un serveur. Deux binaires peuvent réaliser ceci sans problème : netstat ou lsof.

Avec lsof :

sudo lsof -i -P | egrep LISTEN | awk -F ":" '{print $2}' |sort -u


Avec netsat :

netstat -ntaup | awk '/LISTEN/ && match($0,/:[0-9]+/) {print substr( $0, RSTART+1, RLENGTH )}' | sort -u


De la même manière on peut lister les connexions établies pour connaître les machines connectées :

netstat -ntaup | awk '/ESTABLISHED/ {print $5}'


[Python] : un mot sur les listes ? boucles for…

Les listes en python permettent de laisser place à toute votre imagination. De nombreuses astuces permettent d’alimenter une liste ou encore de la parcourir avec les slices, les ranges ou autres.

Je n’ai pas le niveau pour prétendre faire le tour de la question mais j’ai envie de partager mon expérience à ce sujet. En effet, un peu d’expérience dans ce domaine permet de gagner du temps, de simplifier son code et tout simplement de progresser.

Création d’une liste le plus simplement du monde

Définir et alimenter une liste en premier lieu c’est :

>>> liste=['B','o','n','j','o','u','r']

Ensuite lorsque l’on débute on réalise ce genre d’opération :

>>> texte="Bonjour Xavki"
>>> liste=[]
>>> for i in texte:liste.append(i)
>>> print(liste)
['B', 'o', 'n', 'j', 'o', 'u', 'r', ' ', 'X', 'a', 'v', 'k', 'i']

Avec la fonction append, on a ajouté chaque caractère à la liste. En outre, la variable texte fait aussi office de liste et est utilisable comme telle.

Liste  créée et définie en une ligne avec for intégré

>>> print(texte)
Bonjour Xavki
>>> a = [i for i in texte]
>>> print(a)
['B', 'o', 'n', 'j', 'o', 'u', 'r', ' ', 'X', 'a', 'v', 'k', 'i']

Là c’est déjà plus sympa.

Et puis on peut aller plus loin si nécessaire et y placer des conditions avec « if ».

>>> a = [i for i in texte if i == "o"]
>>> print(a)
['o', 'o']

Faire d’une liste de liste… une unique liste

Ce cas se présente souvent, vous avez une liste de liste et vous souhaitez n’en faire qu’une simple liste. Faire cette opération peut se révéler un peu fastidieux car il faut faire deux boucle for et ajouter les éléments avec un append dans notre  liste finale.

Bref voici comment se simplifier la vie et mieux comprendre ce principe d’alimentation des listes. Et avec ça vous aller devenir de vraies oneliners (la frime lol).

>>> texte = [['B','o','n'], ['j','o','u','r']]
>>> print(texte)
[['B', 'o', 'n'], ['j', 'o', 'u', 'r']]
>>> liste=[txt for tmp in texte for txt in tmp]
>>> print(liste)
['B', 'o', 'n', 'j', 'o', 'u', 'r']

Vous me direz cela n’empêche pas de faire deux boucles mais tout cela prend peu de lignes.

Et donc si vous avez compris les « for » empilés voici la même chose avec un niveau supplémentaire.

>>> texte = [['B','o','n'], ['j','o','u','r'],[' ',['X','a','v','k','i']]]
>>> liste=[i for tmp in texte for txt in tmp for i in txt]
>>> print(liste)
['B', 'o', 'n', 'j', 'o', 'u', 'r', ' ', 'X', 'a', 'v', 'k', 'i']

 

Top commandes linux #8 : vim, git, od, sql, convert, aria2c

La routine du lundi c’est de découvrir rapidement quelques commandes et infos que j’ai récolté la semaine dernière. Retrouvez les versions des lundis précédents sur cette page.

Sur le blog l’article qui a le plus cartonné la semaine c’est celui avec la petite astuce pour imprimer la sortie d’une commande dans un png.

# aria2c

Utilisez aria2c pour télécharger plus vite avec de multiples connexions.

aria2c -s 4 https://xavki.blog

# convert

Compressez un pdf pour réduire sa taille avec la commande convert.

convert -density 200 -compress jpeg -quality 20 test.pdf out.pdf

# vim

insérer dans le fichier courant son nom

:put %

# od

Réalisez un dump en hexadécimale de vos fichiers avc la commande od option -x

od -x <file

# git

comparer les deux derniers commits avec un git diff

git diff HEAD^ HEAD

# SQL – Connor MacDonnald

créez une table de table create table as select mais avec des clauses particulières (partition, primary key…) – article complet

create table t (
...,
constraint pk primary key (id1), ...
) partition by range (id2) (...)
as
select...

Rappels git pour les retours arrières

Actualité :

La vidéo de la semaine : comment créer un script bash pour générer un password ?

[youtube https://www.youtube.com/watch?v=P5552IJp7tU&w=700&h=500]

[Linux] : grapher l’utilisation de la mémoire machine

Les outils ps ou top sont surement les plus utilisés pour observer l’état de la mémoire des serveurs. Mais parfois ça manque de charme lol.

En tout cas on peut avoir envie de faire vite fait un graphe plutôt que des chiffres.

Si c’est votre cas vous pouvez installer smem et lancer :

15:29:48 - oki @ doki ~ 
└─ $ ▶ smem --pie name -s pss


Et là vous obtiendrez ce genre de résultats :
figure_1
Bon c’est pas le paradie niveau mise en forme mais faut savoir que ça existe.