Come avrai sentito dire un backup non va bene se non è ripristinabile .
Esistono vari modi per eseguire un backup dei file essenziali su un server cloud. Ma ciò che è anche importante è che tu abbia sempre una copia aggiornata di quei file sul tuo locale sistemi.
Il backup sul cloud va bene. Ma un vero backup è solo una copia fresca e regolarmente aggiornata che è sempre disponibile alla tua estremità. Come mai? Perché sono i TUOI dati!
Due sfide che affronterò a questo proposito sono :
- La necessità di arrestare i container Docker su un server di produzione per evitare qualsiasi possibile danneggiamento dei dati (in particolare dei database) durante il backup. I file sui contenitori di produzione live vengono scritti continuamente.
- Anche l'arresto dei container Docker comporta tempi di inattività e non puoi permetterti di farlo, soprattutto se sei in produzione.
Questi problemi possono essere risolti utilizzando cluster anziché server singoli. Ma qui, mi sto concentrando su server singoli e non su cluster per mantenere le spese del servizio cloud il più basse possibile.
Continuavo a chiedermi come affrontare le due sfide di cui sopra. Poi mi ha colpito che possiamo utilizzare una combinazione di una soluzione cloud e localizzata.
Per soluzioni basate su cloud intendo i servizi di backup forniti da fornitori di servizi cloud come Linode, Digital Ocean e altri. In questa procedura dettagliata utilizzerò Linode.
Per soluzioni localizzate, intendo l'uso di strumenti a riga di comando o basati su GUI per scaricare il backup dai server cloud nel sistema/desktop locale. Qui ho usato sftp (basato sui comandi).
Innanzitutto, parlerò di come eseguire il backup, seguito da come ripristinarlo.
La procedura di backup basata su cloud e locale
Vediamo prima la procedura di backup.
Abilita i backup sul server di produzione Linode (se non l'hai già fatto)
Se si utilizza un server di produzione su Linode, si consiglia vivamente di abilitare il backup ogni volta che viene distribuito per la prima volta. Un "nanode", come viene chiamato, viene fornito con 1 GB di RAM e offre il seguente piano di backup:

Tutte le altre soluzioni di backup offrono una funzionalità simile ma a tariffe più elevate. Assicurati di averlo abilitato.
Scatta uno snapshot manuale come backup sul cloud
Immettere una data per riferimento futuro. Qui lo chiamo "manual-snapshot-11-05-21".

Non appena ci clicchi sopra, ti verrà chiesta conferma:

Quando confermi, troverai una notifica in basso a destra:

Puoi monitorare i progressi nella stessa pagina, accanto a dove dice che il tuo server è in esecuzione (in alto a sinistra):

Al termine, noterai il backup come quarto nell'elenco.

Clone il server di produzione
Sebbene tu possa clonare direttamente un server (basato su backup pianificati precedenti) dal pannello di Linode, ti consiglio di utilizzare i backup manuali come discusso nel passaggio precedente.
Quindi, per procedere con la creazione di un clone basato sul backup manuale più recente che hai eseguito, assicurati di seguire le istruzioni seguenti:
Vai al pannello Linode e fai clic su "Crea":

Seleziona "Linodo":

Seleziona la scheda "Backup":

Nota che lo snapshot che stai scattando è basato su un Linode da 2 GB. Seleziona lo snapshot manuale che hai appena creato:

Ora assicurati di selezionare la stessa specifica (Piano Linode da 2 GB) per il tuo clone:

Dopo aver creato il nuovo server in base al backup del server di produzione, avrai a disposizione un clone prontamente disponibile del server di produzione.
Accedi al clone tramite ssh e ferma tutti i contenitori
Non dovresti avere problemi ad accedere al nuovo clone tramite ssh perché utilizza le stesse chiavi pubbliche del server di produzione. Devi solo usare il nuovo IP del clone. Presumo che tu usi ssh da solo e che l'autenticazione basata su password sia disabilitata, vero? Leggi questa guida alla sicurezza ssh se non l'hai ancora fatto.
Una volta effettuato l'accesso, arresta tutti i contenitori di cui desideri eseguire il backup dei dati. In genere, ci si sposta nelle rispettive directory dell'app e si utilizza il comando docker-compose down. In un tipico ambiente di produzione, dovresti sempre utilizzare Docker Compose invece del convenzionale docker stop
comando che dovrebbe essere preferito solo durante il test.
Ad esempio, se avessi Ghost in esecuzione con il relativo contenitore di database, prima controllerei le rispettive informazioni:
[email protected]:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6a3aafe12434 ghost:4.4.0 "docker-entrypoint.s…" 7 days ago Up 7 days 2368/tcp ghost_ghost_2
95c560c0dbc7 jrcs/letsencrypt-nginx-proxy-companion "/bin/bash /app/entr…" 6 weeks ago Up 10 days letsencrypt-proxy-companion
6679bd4596ba jwilder/nginx-proxy "/app/docker-entrypo…" 6 weeks ago Up 10 days 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp jwilder-nginx-proxy
1770dbb5ba32 mariadb:10.5.3 "docker-entrypoint.s…" 3 months ago Up 10 days ghost_db_1
Come puoi vedere qui, i nomi dei contenitori sono ghost_ghost_2
e ghost_db_1
rispettivamente in esecuzione sotto un proxy inverso. Fermiamoli.
[email protected]:~$ cd ghost
[email protected]:~/ghost$ docker-compose down
Stopping ghost_ghost_2 ... done
Stopping ghost_db_1 ... done
Network net is external, skipping
[email protected]:~/ghost$
Se hai più applicazioni in esecuzione dietro una configurazione proxy inverso nginx, usa la stessa procedura con i rispettivi nomi di directory impostati per le applicazioni. Fermali tutti uno per uno.
Esegui il backup di volumi e impostazioni come archivi gzip
Ora vediamo il processo di backup manuale.
Esegui il backup dei volumi denominati
Quando hai a che fare con volumi Docker denominati, prendi nota se i volumi sono stati creati manualmente o se erano basati su una configurazione Docker Compose generica, l'app è stata distribuita per la prima volta.
Una configurazione generica nella sezione dei volumi è simile a:
volumes:
ghost:
ghostdb:
Lo scenario precedente è gestito da Docker Compose e i nomi dei volumi effettivi necessari per il backup saranno ghost_ghost
e ghost_ghostdb
.
Nel caso in cui i volumi siano stati creati manualmente con docker volume create volume-name
, la configurazione sarebbe simile alla seguente e rigorosamente ghost
e ghostdb
da solo:
volumes:
ghost:
external: true
ghostdb:
external: true
Tuttavia, devi eseguirne il backup in entrambi i casi e devi anche controllare i percorsi sui contenitori quando i volumi vengono montati. Ad esempio, su una tipica configurazione Ghost con MariaDB, i percorsi possono essere conosciuti osservando le sottosezioni dei volumi all'interno delle definizioni del servizio. Ecco un estratto per mostrarti cosa intendo:
ghostdb:
volumes:
- ghostdb:/var/lib/mysql
La configurazione precedente fa parte del servizio database e del relativo contenitore che verrebbe creato una volta distribuito.
Allo stesso modo, per il servizio fantasma stesso, il percorso è /var/lib/ghost/content
:
ghost:
volumes:
- ghost:/var/lib/ghost/content
Devi conoscere questi percorsi per eseguire il backup dei tuoi volumi.
Usa il docker volume ls
comando per ricontrollare i nomi dei volumi presenti sul server clonato.
[email protected]:~/ghost$ docker volume ls
DRIVER VOLUME NAME
local ghost
local ghostdb
local nginx-with-ssl_acme
local nginx-with-ssl_certs
local nginx-with-ssl_dhparam
local nginx-with-ssl_html
local nginx-with-ssl_vhost
Quindi, puoi confermare che i volumi sono effettivamente ghost
e ghostdb
.
È ora di eseguirne il backup! Sul clone di produzione, creiamo ora una directory di backup all'interno della tua directory utente:
mkdir ~/backup
Ora userò il seguente comando per eseguire il backup del contenuto dei volumi all'interno di un archivio tar:
docker run --rm -v ghostdb:/var/lib/mysql -v ~/backup:/backup ubuntu bash -c "cd /var/lib/mysql && tar cvzf /backup/ghostdb.tar.gz ."
Nel comando precedente, con -v
o --volume
, monto il volume della finestra mobile esistente su un nuovo contenitore Ubuntu e collego anche il montaggio della directory di backup che ho appena creato. Successivamente, mi sposto nella directory del database all'interno del contenitore e uso tar per archiviarne il contenuto. --rm
viene utilizzato per ripulire automaticamente il contenitore e rimuovere il suo file system quando il contenitore esce (perché lo desideri solo finché il processo di backup o ripristino viene completato).
Nota il punto alla fine del comando precedente prima della fine di quote(). Garantisce che l'archivio includa ciò che c'è dentro /var/lib/ghost/content
da solo e non includendo l'intero percorso stesso come sottodirectory. Quest'ultimo causerà problemi durante il ripristino dell'archivio su un nuovo volume su un nuovo server. Quindi, tienilo a mente.
Ora ho un archivio del volume del database MariaDB che sta usando il nostro blog Ghost. Allo stesso modo, devo eseguire anche il backup del volume fantasma:
docker run --rm -v ghost:/var/lib/ghost/content -v ~/backup:/backup ubuntu bash -c "cd /var/lib/ghost/content && tar cvzf /backup/ghost.tar.gz ."
Ricorda che i comandi di backup precedenti si basano su volumi esterni che sono stati inizialmente creati manualmente. Per i volumi generici creati e gestiti da Docker Compose, i nomi dei volumi effettivi sarebbero invece ghost_ghost
e ghost_ghostdb
rispettivamente. Ad esempio, per ghost_ghostdb
, il ghost
il prefisso si riferisce al nome della directory dell'applicazione in cui sono presenti i file di configurazione di Docker Compose e ghostdb
fa riferimento al nome del volume che hai impostato nella configurazione di Docker Compose.
Impostazioni di backup con o senza bind mount
Tieni inoltre presente che devi archiviare la directory di composizione della finestra mobile fantasma indipendentemente dal fatto che utilizzi i mount bind oi volumi denominati perché i tuoi file di configurazione sono archiviati qui.
Nel caso in cui si utilizzino i mount di bind e non i volumi Docker denominati, l'intera directory verrebbe archiviata, inclusi i mount di bind. Qui lo chiamo ghost-docker-compose.tar.gz
per evitare confusione:
[email protected]:~/ghost$ sudo tar cvzf ~/backup/ghost-docker-compose.tar.gz .
I volumi montati con binding non necessitano di una sezione di volumi separata in un file Docker Compose. Vorrebbero solo quanto segue quando definito all'interno del servizio:
ghost:
volumes:
- ./ghost:/var/lib/ghost/content
Allo stesso modo, il volume del database montato su bind sarebbe simile a:
ghostdb:
volumes:
- ./ghostdb:/var/lib/mysql
"./" indica la directory montata su bind all'interno della stessa directory fantasma in cui abbiamo appena "cd"d. Pertanto, in questo caso, esegui un backup completo di tutti i file (compresi i volumi e i file di configurazione).
Il binding di backup viene montato come i volumi denominati
In alternativa, puoi anche eseguire il backup individuale dei supporti di collegamento. Questo ti dà un'opzione per scegliere se vuoi che il tuo nuovo server abbia una configurazione bind montata o una configurazione di volume con nome su Docker. Il motivo è che il backup degli archivi viene eseguito allo stesso modo dei volumi denominati discussi sopra. Per fare ciò, è necessario "cd" nelle directory dell'applicazione e del database (bind mounts) una per una.
cd ~/ghost/ghost
sudo tar cvzf ~/backup/ghost.tar.gz .
cd ~/ghost/ghostdb
sudo tar cvzf ~/backup/ghostdb.tar.gz .
Sia i binding mount che i volumi denominati hanno i loro pro e contro. La domanda su quale di essi sia più ideale varia da applicazione ad applicazione. Ad esempio, gli sviluppatori Nextcloud suggeriscono i volumi con nome, mentre gli sviluppatori Rocket.Chat suggeriscono i binding mount.
Andando avanti, è ora di recuperare quegli archivi alla tua fine.
Scarica gli archivi sul tuo sistema locale usando sftp
Usando sftp, puoi scaricare immediatamente i tuoi archivi nel tuo sistema locale. Qui sto usando la porta 4480 e IP 12.3.1.4 come esempio. Si riferisce alla stessa porta usata da ssh.
[email protected]:~$ sftp -oPort=4480 [email protected]
Connected to 12.3.1.4.
sftp> get /home/avimanyu/backup/ghost.tar.gz /home/user/Downloads
Fetching /home/avimanyu/backup/ghost.tar.gz to /home/user/Downloads/ghost.tar.gz
/home/avimanyu/backup/ghost.tar.gz 100% 233MB 6.9MB/s 00:34
sftp> get /home/avimanyu/backup/ghostdb.tar.gz /home/user/Downloads
Fetching /home/avimanyu/backup/ghostdb.tar.gz to /home/user/Downloads/ghostdb.tar.gz
/home/avimanyu/backup/ghostdb.tar.gz 100% 26MB 6.5MB/s 00:03
sftp> get /home/avimanyu/backup/ghost-docker-compose.tar.gz /home/user/Downloads
Fetching /home/avimanyu/backup/ghost-docker-compose.tar.gz to /home/user/Downloads/ghost-docker-compose.tar.gz
/home/avimanyu/backup/ghost-docker-compose.tar.gz 100% 880 6.0KB/s 00:00
sftp> exit
[email protected]:~$
Come puoi vedere qui, il get
comando su sftp è molto più veloce di rsync o scp . Una volta il download è completo, ti verrà mostrato il prompt sftp dove puoi inserire exit
ed esci dalla console sftp. I file scaricati sarebbero disponibili in /home/user/Downloads
.
A questo punto, puoi dire di aver eseguito un backup completo della tua applicazione Docker.
Ma come devo dire ancora, non va bene a meno che tu non possa ripristinarlo.
Procedura di restauro
Ora che sai come eseguire un backup, è il momento di vedere come eseguire il ripristino da un backup.
Crea un nuovo server sul cloud
Crea un nuovo nuovo server dalla dashboard del tuo servizio Cloud. Ne ho discusso nella nostra sezione di backup. Su Linode, sembra:

Si consiglia di mantenere le specifiche del server identiche a quelle del server originale da cui è stato eseguito il backup degli archivi (menzionato in precedenza).
Carica gli archivi di backup sul nuovo server
Supponendo che ora tu possa accedere al nuovo server in base alle impostazioni ssh salvate sul tuo provider di servizi cloud, carica i file sul server con put
di sftp comando:
[email protected]:~$ sftp -oPort=4480 [email protected]
Connected to 12.3.1.5.
sftp> put /home/user/Downloads/ghostdb.tar.gz /home/avimanyu
Uploading /home/user/Downloads/ghostdb.tar.gz to /home/avimanyu/ghostdb.tar.gz
/home/iborg/Downloads/ghostdb.tar.gz 100% 26MB 6.2MB/s 00:04
sftp> put /home/user/Downloads/ghost.tar.gz /home/avimanyu
Uploading /home/user/Downloads/ghost.tar.gz to /home/avimanyu/ghost.tar.gz
/home/iborg/Downloads/ghost.tar.gz 100% 233MB 7.2MB/s 00:32
sftp> put /home/user/Downloads/ghost-docker-compose.tar.gz /home/avimanyu
Uploading /home/user/Downloads/ghost-docker-compose.tar.gz to /home/avimanyu/ghost-docker-compose.tar.gz
/home/iborg/Downloads/ghost-docker-compose.tar.gz 100% 880 22.6KB/s 00:00
sftp> exit
[email protected]:~$
Se preferisci utilizzare una GUI per il caricamento, puoi comunque utilizzare FileZilla.
Ripristina impostazioni e volumi
Innanzitutto, ripristina la directory di composizione della finestra mobile della tua configurazione Ghost.
mkdir ghost
cd ghost
sudo tar xvf ~/backup/ghost-docker-compose.tar.gz
In alternativa, puoi anche provare a ripristinare la proprietà dell'utente (le autorizzazioni sono già conservate) che potrebbe essere utile durante il ripristino di directory montate bind (già presenti negli archivi), con --same-owner
:
sudo tar --same-owner -xvf ~/backup/ghost-docker-compose.tar.gz
Nel caso in cui desideri affidarti a Docker Compose per la gestione dei nuovi volumi, creali prima. Secondo la nostra discussione nella sezione dei volumi di backup sopra, dovresti ovviamente seguire le convenzioni di denominazione necessarie:
docker volume create ghost_ghost
docker volume create ghost_ghostdb
Se vuoi impostarli come esterni all'interno della tua configurazione Docker Compose, i nomi dovrebbero essere diversi (rivedi i due comandi precedenti):
docker volume create ghost
docker volume create ghostdb
Per ripristinare il volume MariaDB per Ghost:
docker run --rm -v ghostdb:/restore -v ~/backup:/backup ubuntu bash -c "cd /restore && tar xvf /backup/ghostdb.tar.gz"
Per ripristinare il volume Ghost stesso:
docker run --rm -v ghost:/restore -v ~/backup:/backup ubuntu bash -c "cd /restore && tar xvf /backup/ghost.tar.gz"
Assicurati che le impostazioni DNS vengano ripristinate in base al nuovo IP
Poiché stai utilizzando un nuovo server, l'IP è decisamente cambiato e quindi deve essere rivisto per il tuo dominio. Puoi controllare questi prerequisiti della finestra mobile del proxy inverso di nginx come riferimento in cui è stato discusso.
Avvia nuovi container con le impostazioni necessarie e i volumi ripristinati
Ora riavvia la configurazione sul nuovo server:
docker-compose up -d
Se segui assiduamente tutte le istruzioni di cui sopra, ora avrai un'applicazione Web Docker completamente ripristinata in base al tuo backup.
Distruggi il clone
Una volta che ti sei assicurato che il tuo obiettivo è stato raggiunto, avere il clone non è più necessario a meno che tu non voglia conservarlo per i test. Quindi, se non lo vuoi più, elimina il Linode(DOUBLE CHECK!):

Pensieri finali
Esistono già molte soluzioni che utilizzano tali metodi in parti e porzioni. Ma ciò richiede tempi di fermo perché i container devono essere fermati. Questa sfida viene affrontata utilizzando i backup cloud dei cloni di produzione e non i server di produzione stessi.
Invece di utilizzare un server aggiuntivo 24 ore su 24, 7 giorni su 7 come cluster per backup senza tempi di inattività, ne stiamo solo utilizzando uno momentaneamente per garantire lo stesso. Ciò consente migliori FinOps.
Se preferisci utilizzare una GUI per scaricare o caricare i tuoi backup, puoi utilizzare sftp
tramite FileZilla.
Poiché si esegue il backup dei file su un server clonato e non sul server di produzione stesso, si risparmia prezioso tempo di attività, oltre a evitare singhiozzi imprevisti che potrebbero verificarsi durante il processo. Ad essere onesti, puoi essere libero da qualsiasi preoccupazione e giocherellare con esso senza alcuna tensione perché non tocchi il server di produzione;)
Non posso negare che l'intero processo è abbastanza completo, ma sicuramente si prende cura del nostro obiettivo. Guardando oltre, questa procedura potrebbe anche essere completamente automatizzata in futuro, con un'attenta sincronizzazione tra il cloud e il tuo sistema locale.
Se hai ulteriori suggerimenti sul backup e il ripristino di Docker senza tempi di inattività, condividi le tue opinioni nella sezione seguente. Qualsiasi altro feedback o commento è il benvenuto.