Come separare le migrazioni del database dall’avvio dell’app durante i rollout dei container

Eva Wong è la Technical Writer e smanettatrice residente di ZimaSpace. Una geek da sempre con una passione per homelab e software open-source, si specializza nel tradurre concetti tecnici complessi in guide accessibili e pratiche. Eva crede che l'auto-ospitare debba essere divertente, non intimidatorio. Attraverso i suoi tutorial, dà potere alla comunità di demistificare le configurazioni hardware, dalla costruzione del loro primo NAS al dominio dei container Docker.

È più facile prevenire le migrazioni duplicate quando le modifiche allo schema vengono eseguite come un'unica fase di deployment esplicita, anziché all'interno dell'avvio di ogni container dell'app.

La progettazione preventiva consiste nell'affidare le migrazioni a un unico responsabile, con un unico set di credenziali e un unico segnale di completamento, prima che le nuove repliche inizino a gestire il traffico. Mantieni i container web e worker liberi di riavviarsi senza acquisire privilegi per modificare lo schema, fai attendere il rollout fino al completamento riuscito del job di migrazione e progetta le modifiche allo schema in modo che le versioni precedente e nuova dell'app possano coesistere temporaneamente. In questo modo elimini la condizione di competizione, invece di sperare semplicemente che ogni replica rilevi per prima la stessa cronologia delle migrazioni.

Rimuovi i comandi di migrazione dall'avvio normale dell'app

Controlla l'entrypoint dell'immagine, il comando Compose, il comando del worker, il wrapper di health check e lo script di deployment alla ricerca di chiamate automatiche alle migrazioni. L'applicazione deve poter essere riavviata senza modificare lo schema, a meno che il riavvio non sia la fase di migrazione scelta intenzionalmente.

Un articolo di Octopus sul deployment sostiene che le migrazioni richiedono un ciclo di vita separato, anziché essere associate all'avvio di ogni processo del microservizio.

Mantieni disponibile il binario di migrazione dove necessario, ma non richiamarlo sia dall'entrypoint web sia da un secondo job. Un unico responsabile esplicito è più facile da verificare rispetto a diversi percorsi di avvio che dipendono tutti dal blocco del framework.

Esegui un unico job di migrazione prima del deployment

Crea un job eseguito una sola volta che utilizzi gli stessi file di migrazione della release e termini con esito positivo solo dopo che il database di destinazione ha raggiunto lo stato dello schema previsto. Fai dipendere il rollout dell'applicazione da questo risultato.

Una guida aggiornata sul rollout mostra come un unico job venga eseguito prima del rollout, invece di lasciare che ogni replica avvii una gara durante l'avvio.

Non dimensionare il task di migrazione come il servizio dell'app. Il job dovrebbe avere un unico responsabile dell'esecuzione per ogni database di destinazione, un timeout limitato, dei log e uno stato di errore chiaro che blocchi la nuova versione dell'app.

Vincola l'avvio dell'app al completamento riuscito della migrazione

Fai attendere i nuovi container web e worker finché la fase di migrazione non segnala il completamento riuscito, ma non fare in modo che ogni container in attesa esegua nuovamente la migrazione. La dipendenza riguarda il risultato, non la ripetizione della modifica allo schema.

Il modello di deployment di Andrew Lock utilizza pod dell'app che attendono la migrazione, mantenendo centralizzata la logica di migrazione.

Per una piccola infrastruttura home server, lo stesso principio può essere implementato con un servizio Compose dedicato e uno script di deployment controllato. Mantieni il meccanismo abbastanza semplice da fare in modo che una migrazione non riuscita blocchi visibilmente il rollout.

Utilizza modifiche allo schema compatibili con le versioni precedenti durante la sovrapposizione

I deployment progressivi possono eseguire temporaneamente versioni precedenti e nuove dell'applicazione sullo stesso database. Evita una migrazione che rimuova o rinomini un campo prima che la versione precedente abbia smesso di utilizzarlo.

Una recente guida alle migrazioni senza downtime consiglia di espandere prima di contrarre, in modo che le modifiche additive allo schema vengano applicate prima della pulizia distruttiva.

Quando necessario, suddividi le modifiche più ampie in fasi di espansione, popolamento dei dati, passaggio e contrazione. Il job di migrazione non dovrebbe creare uno schema comprensibile solo al nuovo container mentre le repliche precedenti stanno ancora gestendo le richieste.

Mantieni le credenziali di migrazione fuori dalle repliche dell'app

Quando possibile, utilizza un account del database con privilegi per modificare lo schema esclusivamente nella fase di migrazione eseguita una sola volta. I normali container dell'app dovrebbero mantenere solo i permessi più limitati necessari per leggere e scrivere i dati dell'applicazione.

Un articolo di Liquibase sul deployment descrive come le modifiche al database debbano rientrare nell'automazione, con un'applicazione delle modifiche controllata e ripetibile.

Questa separazione riduce la probabilità che una migrazione venga eseguita accidentalmente, anche se un processo dell'app viene riavviato o duplicato. Conserva la credenziale con privilegi elevati nel percorso dei secret del deployment, anziché nell'ambiente del normale servizio a esecuzione prolungata.

Verifica che il rollout non possa applicare due volte lo stesso gruppo di modifiche

Testa il deployment in un database usa e getta o in uno snapshot ripristinato avviando più repliche dell'app, riavviandole e rieseguendo il comando di deployment. La fase di migrazione dovrebbe segnalare lo stato dello schema esistente senza modificarlo una seconda volta.

JetBrains riassume la regola operativa con esegui le migrazioni come fase del deployment prima dell'avvio normale dell'applicazione.

La policy di prevenzione è completa quando i riavvii dell'app non possono modificare lo schema, una migrazione non riuscita blocca la release e l'esecuzione ripetuta del rollout lascia invariato il database. L'articolo correlato di ZimaSpace sulla diagnosi delle migrazioni duplicate costituisce il percorso di recupero nel caso in cui l'esecuzione duplicata si sia già verificata.

Supporto e consigli

Altro da leggere

Get More Builds Like This

Stay in the Loop

Get updates from Zima - new products, exclusive deals, and real builds from the community.

Stay in the Loop preferences

We respect your inbox. Unsubscribe anytime.