Migration de conteneurs Docker d'un host à l'autre

Tut's Linux juin 15, 2020

Contexte : vous disposez d'un host Docker avec des conteneurs (qu'importe l'image et le contenu) que vous souhaitez migrer entièrement d'un serveur à l'autre (migration "à froid" de toutes les données correspondantes aux conteneurs).

Tests effectués :

  • Migration d'un serveur à l'autre avec un seul fichier docker-compose, sans réseau personnalisé : OK
  • Migration d'un serveur à l'autre avec un seul fichier docker-compose, avec un réseau interne personnalisé dans le docker-compose : OK
  • Migration d'un serveur à l'autre avec avec plusieurs sous-dossiers (e.q. : /srv/docker/dc | /srv/docker/app1 | /srv/docker/app2) et plusieurs sous-réseaux personnalisés : OK

Environnement : deux VM Debian 10.4, tous les deux ayant Docker + docker-compose installé via les dépôts officiels Docker. Les serveurs sont sur le même réseau IP, disposent tous les deux des paquets "rsync" et "openssh-server/openssh-client" (obligatoire !)/

  • serveur 1 = "debian-docker1" / 192.168.1.92(/24) - serveur ayant la base Docker "active", avec tous les conteneurs (images, volumes, network)
  • serveur 2 = "debian-docker2" / 192.168.1.93(/24) - le serveur récepteur

Pour ce PoC, les configurations SSH sont permissives et simples : port 22 en écoute, authentification par mot de passe, authentification de root possible, génération des paires de clef SSH sans mot de passe.

Le dossier où sont stockés les configurations et le .yml se trouve à l'emplacement "/srv/docker". Par défaut, le dossier Docker où sont stockés volumes/images/network/conteneurs se trouve à l'emplacement "/var/lib/docker".

Objectif : "faut qu'ça marche !" - une fois la migration effectuée, démarrons les conteneurs et voyons si ça tourne.


Préparation de la migration

Pré-requis INDISPENSABLE avant de migrer : sauvegardez vos données !! Effectuez des "dump" de vos bases de données et générez des fichiers exports de vos applications (si celles-ci le permette).

Avant de se lancer dans les commandes, préparons l'environnement ; chaque serveur dispose déjà de l'applicatif docker, des paquets "rsync" et "openssh-server/openssh-client". Sur le serveur numéro 1 ("debian-docker1" / 192.168.1.92(/24)), générons une paire de clef SSH - la clé publique sera ensuite envoyée sur le serveur numéro 2.

ssh-keygen -t ed25519
ssh-copy-id root@192.168.1.93

Testons de suite la connection SSH du serveur 1 vers le serveur 2 : ssh root@192.168.1.93
Vous devriez pouvoir vous connecter dès à présent vers le serveur 2 sans entrer de mot de passe.

Si les deux serveurs sont joignables, nous allons attaquer la partie Docker. Assurez-vous que vous n'utilisez plus vos conteneurs, qu'aucune connexion est en cours, bref, que tout soit "off". Dirigez-vous dans votre dossier où se trouve le fichier docker-compose et stoppez le tout.

docker-compose stop 
Il est nécessaire de stopper tous les conteneurs pour être sûr qu'aucune connexion est encore en cours, que les bases de données soient bien "fermées" et qu'aucun index ne soient modifiés. C'est primordial, notamment si vous avez des bases de données relationnelles type SQL.

Par précaution et pour s'assurer qu'une ressource soit utilisée, coupez le service Docker :

sudo systemctl stop docker

Migration !

Pour se faire, j'utilise l'outil RSYNC, avec les attributs "-avn" dans un premier temps puis "-av" par la suite.

  • rsync -avn = récursif et verbose, avec un test d'envoi des dossiers et des fichiers (mode "dry run").
  • rsync -av = récursif et verbose, transfert "réel" de tous les dossiers et fichiers.

Lors de mes tests, je me suis auparavant un peu embêté à copier chaque dossier nécessaire - par la suite, je me suis rendu compte qu'il était possible de copier entièrement le dossier "/var/lib/docker", tout simplement...
Attention, pour rappel, la migration effectuée ici correspond à un serveur ayant "un dossier" où se trouve un fichier docker-compose.yml, où tous les conteneurs y sont. Il n'y a pas de réseau externe créé, pas de personnalisation du daemon Docker.

Volontairement, les commandes rsync seront en mode "dry-run", vous permettant de savoir si tout se passe correctement. Pour lancer le vrai transfert, enlevez simplement le "n" dans la suite d'attributs de la commande rsync (soit rsync -av).

Sur le serveur numéro 2, par précaution, stoppez aussi le daemon Docker :

ssh root@192.168.1.93 systemctl stop docker

Je vous propose 2 méthodes : une façon rapide et une façon plus "sous-contrôle".

Migration rapide et facile

rsync -avn /srv/docker root@192.168.1.93:/srv/docker
rsync -avn /var/lib/docker root@192.168.1.93:/var/lib/docker

En effectuant ces deux commandes rsync, vous copiez l'intégralité de votre Docker vers le second serveur.


Migration par étapes

Plutôt que de déplacer entièrement le dossier "/var/lib/docker", vous pouvez migrer uniquement les dossiers nécessaires (n'oubliez pas de changer l'utilisateur, les chemins des dossiers et l'IP en fonction de votre architecture) :

CONF fichier et confs docker-compose

rsync -avn /srv/docker/ root@192.168.1.93:/srv/docker/

CONF volumes docker

rsync -avn /var/lib/docker/volumes/ root@192.168.1.93:/var/lib/docker/volumes/

CONF images docker

rsync -avn /var/lib/docker/image/ root@192.168.1.93:/var/lib/docker/image/

CONF containers docker

rsync -avn /var/lib/docker/containers/ root@192.168.1.93:/var/lib/docker/containers

CONF docker (attention, très verbose)

rsync -an /var/lib/docker/overlay2/ root@192.168.1.93:/var/lib/docker/overlay2/

Lorsque les transferts sont complétés, il est primordial de vous connecter sur le second serveur et de contrôler si tous les dossiers sont bien arrivés, au bon endroit, que les tailles correspondent entre les serveurs, que vos fichiers de configuration / vos variables dans le fichier docker-compose.yml soient correctes... Un contrôle général en somme.

Une fois certain de vos transferts, vous pouvez alors redémarrer le service docker, puis remonter vos conteneurs :

ssh root@192.168.1.93
systemctl start docker
cd /srv/docker
docker-compose down && docker-compose up -d

Votre migration est désormais terminée - vos conteneurs sont normalement exploitables et démarrés !

Super ! Vous vous êtes inscrit avec succès.
Super ! Effectuez le paiement pour obtenir l'accès complet.
Bon retour parmi nous ! Vous vous êtes connecté avec succès.
Parfait ! Votre compte est entièrement activé, vous avez désormais accès à tout le contenu.