Archives de catégorie : Docker

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

[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

[Docker] : supprimer les images non taggées

Ah cela m’est arrivé plusieurs fois, on créé des images sans faire gaffe. Au bout d’un moment ça devient le boxon et il est temps de faire le ménage. Mais lorsque l’on fait le ménage dans les images docker, on se retrouve avec une tripoté d’images sans tag. Que faire ? les supprimer car c’est moche et ça ne sert à rien.

Mais comment supprimer des images qui ne sont pas taggées ?

Pas si compliqué :

docker rmi $(docker images -f "dangling=true" -q)

Donc :

  • docker images : on liste les images en filtrant sur les « non-taggées » soit dangling = true
  • docker rmi : on applique une suppression d’image par l’ID
arrows box business chalk

Photo by Pixabay on Pexels.com

[Docker] : Swarm – lister les services et les nodes en 1 ligne

Là c’est pas bien compliqué. Mais bon comme j’en ai marre de commencer par chercher les ID des service pour pouvoir faire un docker ps dessus, je me suis créé un alias qui fait le taff.

Vous êtes pas obligé d’ajouter ça dans votre bashrc mais je vous le recommande pour plus de faciliter.

En gros on combine un docker service ls et un docker service ps :

alias dserv='for id in $(docker service ls --format "{{.ID}}");do docker service ps $id;done'

Je pense que vous devez avoir aussi vos petites astuces de ce genre. N’hésitez pas à les laisser en commentaire.