Forum Linux.général Sauvegarde mariadb dans docker

Posté par  . Licence CC By‑SA.
Étiquettes :
3
10
mai
2021

Bonjour,

J'ai mis en place un Nextcloud/Mariadb en auto-hebergement avec docker compose. Ça marche très bien par contre je ne sais pas trop comment m'y prendre pour sauvegarder le tout.

Auriez-vous des conseils pour faire un backup régulier de Nextcloud ainsi que de sa base de données?

Merci d'avance!

  • # mysqldump

    Posté par  . Évalué à 3 (+2/-0).

    Pour la partie SQL, tu peux faire un truc du genre :

    TMPDIR=`mktemp -d`
    
    echo "  Backup MySQL..."
    docker-compose exec -T maria sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > $TMPDIR/dump.sql
    
    RESULT="$?"
    if [ "$RESULT" != "0" ]; then
       echo "Error in MySQL dump."
       exit $RESULT
    fi
    
    echo "  Running your backup software...."
    rm -rf $TMPDIR

    Après, il faut que tu gères la sauvegarde des données (et aussi du php). Perso, j'utilise Burp.

    Tu as aussi un peu de doc sur le site de Nextcloud.

    • [^] # Re: mysqldump

      Posté par  . Évalué à 2 (+1/-1).

      sympa le script qui fait le dump pour l'effacer ensuite…

      j'imagine que le rm -rf $TMPDIR devra etre precédé par tout un tas de chose pour déplacer ce dump, l'archiver ou le transférer sur une autre machine, etc.

      • [^] # Re: mysqldump

        Posté par  . Évalué à 3 (+1/-0).

        sympa le script qui fait le dump pour l'effacer ensuite…

        Note qu'il ne l'efface que si le dump a réussi ;-)

        • [^] # Re: mysqldump

          Posté par  . Évalué à 2 (+0/-0). Dernière modification le 11/05/21 à 18:48.

          je ne vois pas la condition de réussite pour l'effacement

          ah si, y a un exit en cas d'erreur placé AVANT
          mais du coup, tu fait un dump
          s'il a marché tu l'effaces

          il manque la phase de backup, envoie vers ailleurs, etc

    • [^] # Re: mysqldump

      Posté par  . Évalué à 8 (+6/-0).

      J'ai quelques suggestions pour le script:

      TMPDIR=$(mktemp -d)
      

      Les contr'apostrophes sont pleines de pièges et je crois même qu'elle sont dépréciées depuis plusieurs dizaine d'années!

      backup_mysql()
      {
          docker-compose exec -T maria sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > $TMPDIR/dump.sql
      }
      
      echo "  Backup MySQL..."
      if backup_mysql; then
        echo "  Remove backup file...."
        rm -rf "${TMPDIR:?}"
      else
        echo "  Exit program: there was an error in the backup procedure."
        exit 1
      fi
      

      La fonction permet d'expliquer ce que fait cette commande compliquée (nom de la fonction) et d'avoir un flot d'exécution plus clair.

      Le :? pour protéger l'exécution de rm -rf c'est important. Le mieux je trouve est de créer un subshell et d'utiliser trap comme dans:

      with_tmpdir()
      (
         TMPDIR=$(mktemp -d)
         trap "rm -rf ${TMPDIR:?}" INT TERM EXIT
         "$@"
      )
      
      use_tmpdir()
      {
         touch "${TMPDIR:?}/canari"
         ls -lR "${TMPDIR}:?"
      }
      
      with_tmpdir use_tmpdir
      

      Ainsi on a une responsabilité claire et unifiée pour l'allocation et la déposition d'une ressource (le répertoire temporaire).

      • [^] # Re: mysqldump

        Posté par  . Évalué à 4 (+3/-0).

        Excellents conseils,

        d'ailleurs je rajouterai l'utilisation de https://www.shellcheck.net/ pour valider ses scripts shells, il est installable en local et donne les explications sur ses suggestions.

    • [^] # Re: mysqldump

      Posté par  . Évalué à 1 (+0/-0). Dernière modification le 14/05/21 à 02:49.

      Voici une alternative plus globale mais plus sale, au cas où elle pourrait être utile :

      #!/bin/sh
      
      BASE_DIR=/var/backups/mysql
      
      # On essaie de diminuer la priorité de la chose
      # Aucune importance si les utilitaires ne sont pas dispos
      renice 15 -p $$ >/dev/null 2>&1
      ionice -c 3 -p $$ >/dev/null 2>&1
      
      # Arrêt à la moindre erreur non-catchée
      set -e
      
      docker ps --format "{{.ID}} {{.Names}}" | egrep "(mysql|mariadb)" | while read CONTAINER_ID CONTAINER_NAMES; do
              # Note : CONTAINER_NAMES peut contenir plusieurs noms qui sont séparés par des vigules
              #        et ces noms peuvent contenir des '/'
              BACKUP_BASENAME=bdd_"$( printf $CONTAINER_NAMES | tr -c '[:alnum:]' '-' )"
              BACKUP_FILENAME="$BACKUP_BASENAME"_"$CONTAINER_ID"_"$( date +\%Y\%m\%d-\%H\%M\%S )".sql.gz
              docker exec "$CONTAINER_ID" bash -c 'mysqldump -u root -p$MYSQL_ROOT_PASSWORD --add-drop-table --all-databases' | gzip > "$BASE_DIR/$BACKUP_FILENAME"
      
              # Suppression des vieux backups
              find "$BASE_DIR" -maxdepth 1 -name "$BACKUP_BASENAME*" -mtime +10 -delete
      done
  • # docker, lecture seule avec volume externe

    Posté par  . Évalué à 5 (+3/-0).

    normalement docker c'est un système en quasi lecture seule
    le stockage amené à changer doit se trouver sur un volume/point de montage externe.

    tu peux donc au choix :
    * faire le dump est l'archiver dans un coin (à chaud du coup)
    * arreter le docker et copier le dossier /var/lib/mysql vers un autre support

    car finalement un backup d'un site web php/mysql se fait de la meme manière qu'on soit en docker ou non.

    • [^] # Re: docker, lecture seule avec volume externe

      Posté par  . Évalué à 4 (+2/-0). Dernière modification le 11/05/21 à 08:51.

      normalement docker c'est un système en quasi lecture seule

      Oui moi aussi ça m'a fait tiquer.

      Le cas où docker ou en général les technologies à base de “conteneurs” sont les plus pertinents en production sont les cas des applications sans état persistant ou qui ont une forte élasticité horizontale (le nombre de processus concurrents peut varier grandement): ce n'est pas vraiment le cas typique d'une base de données.

      Il y a des cas légitimes pour faire tourner une base de données de docker, souvent pour créer un environnement de laboratoire ou bien dans la chaîne de tests d'une application. Dans un environnement de production ou de pré-production, cela n'a pas vraiment d'intérêt et diminue en principe la disponibilité de la base de données.

      • [^] # Re: docker, lecture seule avec volume externe

        Posté par  (site Web personnel) . Évalué à 2 (+2/-1).

        Euh bah on des volumes pour les données.

        Des bases de données dans Docker c’est de plus en plus courant, ça permet d’uniformiser les techniques de déploiement, même en production.

        • [^] # Re: docker, lecture seule avec volume externe

          Posté par  . Évalué à 3 (+1/-0).

          Mon propos n'est pas de dire que c'est techniquement infaisable mais plutôt que c'est une pratique qui se discute et qui n'est pas forcément la plus naturelle.

          Réduire la surface technologique à laquelle est confrontée une équipe c'est très bien mais selon le type d'application les impératifs de disponibilité ou de redimensionnement peuvent jouer un rôle plus important dans le choix de la méthode ou des technologies employées.

          • [^] # Re: docker, lecture seule avec volume externe

            Posté par  (site Web personnel) . Évalué à 0 (+1/-2). Dernière modification le 11/05/21 à 13:24.

            Tu vas pas spécialement avoir d’impact sur les performances et la disponibilité en fait.

            On a de plus en plus tendance à rajouter cette couche horizontale de conteneurs sur les serveurs et pas spécialement en allant jusqu’à un Kubernetes. Certes, une base de données va pas bénéficier de tous les avantages que ça pourrait apporter mais clairement y’a vraiment aucun inconvénients à garder les mêmes types de briques même pour ce genre d’applications stateful. L’écosystème est suffisamment flexible pour ça.

            Et pour le redimensionnement, ça dépend de l’infra. Rien n’empêche de gérer un cluster exactement de la même manière avec des docker[-compose] exec mysql au lieu de mysql dans des scripts.

            Finalement le conteneur est un non-sujet.

            • [^] # Re: docker, lecture seule avec volume externe

              Posté par  . Évalué à 2 (+1/-1). Dernière modification le 11/05/21 à 15:55.

              Tu vas pas spécialement avoir d’impact sur les performances et la disponibilité en fait.

              Sur la disponibilité il y quand-même des sujets.

              Le premier est que pour garantir à l'application d'avoir sa bdd au démarrage on choisit souvent d'écrire un “health-check” qui permet au superviseur de conteneurs de savoir que la bdd est prête avant de démarrer l'application. Si on ne fait pas attention on donne là facilement un prétexte au superviseur pour dézinguer la bdd dès que celle-ci est en surcharge. Ça peut faire mal.

              Le second est que certains scénarios de migration sans interruption de service demandent d'intervenir à un niveau très bas dans la pile réseau, ici faire tourner la bdd sous un superviseur de conteneur qui a tendance à traiterle réseau comme son domaine privé va plutôt être un obstacle. Cela peut concerner par exemple le redimensionnement des disques ou le changement de version.

              Enfin cela veut aussi dire que planter le superviseur de conteneurs ferait planter la bdd, dont on augmente donc un peu le risque de plantage et réduit donc la disponibilité.

              Selon le contexte ces sujets peuvent être sans aucune importance ou par exemple importants.

              (Autre pan de la discussion il y aussi des raison extra-techniques qui vont disqualifier cette option, s'il faut par exemple garantir que des équipes différentes administrent la bdd et d'autres développent et opèrent les applications.)

              • [^] # Re: docker, lecture seule avec volume externe

                Posté par  (site Web personnel) . Évalué à 0 (+1/-2).

                Tout ce que tu décris est indépendant de la question de conteneur en fait. :D

                • Tu configures tes health-checks de la façon dont tu le souhaites avec ou sans conteneur.
                • Tu configures Docker (ou autre) comme tu préfères pour le réseau pour lui laisser ou non la main sur ça.

                Le risque de plantage s’évalue après.

                Bref, tout ça pour dire que c’est pas le choix de faire du conteneur qui va changer grand chose si tu as envie de garder complètement la main sur tes bases de données. Là où je veux en venir c’est que des conteneurs vont plutôt avoir tendance à t’ouvrir des portes sur la manière dont tu gères ton infrastructure plutôt que de t’en fermer. Pareil pour les raisons extra-techniques, t’es pas obligé de tout fusionner.

    • [^] # Re: docker, lecture seule avec volume externe

      Posté par  . Évalué à 1 (+1/-3).

      normalement docker c'est un système en quasi lecture seule

      C'est montrer une très grande ignorance des systèmes containerisés.

      Docker, tout comme Kubernetes ou Apache Mesos utilisent le concept de volumes. Donc oui on peut avoir des données, et elles peuvent être volatiles ou persistentes, partagées entre plusieurs pods/containers ou non.

      Pour des données qui peuvent être copiées à chaud sans risque d'incohérence, on backup par exemple en montant ce volume dans un autre container volatile qui va s'occuper de copier les données sur un système de backup ou un stockage externe.

      Pour une base de donnée on va démarrer un container qui est équipé de l'outil de dump de la base de donnée et se connecter à la base via le réseau (sur un système à simple node, dans le bridge network). Par contre pour ça c'est mieux de ne pas avoir un container monolithique contenant appli et base de donnée mais de les avoir splitté car sinon il est possible que la base de donnée n'a pas été configurée pour écouter ailleurs que depuis localhost.

  • # mysqldump dans un autre container

    Posté par  . Évalué à 4 (+2/-1).

    Pour moi le plus simple c'est d'avoir un timer systemd qui va lancer un script de dump via un container et le copier à l'endroit désiré.

    Ici un exemple de container dédié à ça avec dockerfile et exemple d'usage. L'auteur semble choisir d'utiliser cron dans le container, moi je préfère personnellement utiliser l'ordonnanceur du système hôte (ou celui de kubernetes quand ça tourne dans celui-ci):
    https://github.com/alexanderschnitzler/docker-mysqldump

  • # automysqlbackup

    Posté par  (site Web personnel) . Évalué à 3 (+1/-0).

    Il n’a pas encore été mentionné, mais automysqlbackup (ou autopostgresqlbackup pour PG) fonctionne plutôt bien.

Envoyer un commentaire

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n’en sommes pas responsables.