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

Print Friendly, PDF & Email

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”.

Découvrez  [Docker] : Swarm - lister les services et les nodes en 1 ligne

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