martedì 6 dicembre 2011

Distribuire Tutte le cose - Deployment Miti Parte 2

Il mio post precedente trattato alcune delle scuse e fastidiosi disturbi che alla gente piace utilizzare quando si parla di distribuzioni. Il grande togliere avrebbe dovuto essere il seguente:
  • Il rischio associati all'implementazione nuovo codice non è nella stessa implementazione, ma tutto quello che hai fatto fino a quel momento.
  • Il modo di fare distribuzione nuovo codice meno rischiosa è quella di farlo più spesso, non meno.
  • Creare una cultura e l'ambiente che consente e incoraggia piccoli, frequenti rilasci.
  • Tutto fallisce. Embrace fallimento.
  • Fai distribuisce banale, automatico e tollerante di fallimento.
Voglio fare una cosa sia perfettamente chiara. L'ho detto diverse volte prima. È possibile ottenere il 90% della strada per un ambiente completamente automatizzato, mai andare che durano il 10% e ancora meglio a quello che erano prima.Capisco che la gente ha regole, i requisiti e le altre cose che impediscono un sistema completamente automatizzato.Non è mai per capovolgere che l'interruttore ma si dovrebbe cercare di avvicinarsi il più possibile.

Comprendere il ruolo delle operazioni

Operazioni è una parola interessante. Al di fuori del campo di IT significa qualcosa di completamente diverso rispetto a qualsiasi altro nel mondo degli affari. Secondo Wikipedia :
Operazioni di business comprende tre imperativi fondamentali di gestione che insieme mirano a massimizzare il valore raccolto dalle attività commerciali
  • Generano ricavi ricorrenti
  • Aumentare il valore dei beni aziendali
  • Fissare il reddito e il valore del business

Operazioni IT non tradizionalmente nulla al riguardo. Invece le operazioni IT è diventata di cazzo blocco e di essere portieri greybeareded che dicono sempre "no" a prescindere dalla questione. Noi shunt la responsabilità fuori al team di sviluppo e poi, in un gioco malato di 'fuck you', facciamo tutto il possibile per evitare che il codice di andare in diretta.Questo è insostenibile; controproducente, e in un tocco casuale del destino, autodistruttivo.
Una cosa che ho sempre cercato di ottenere le mie operazioni e coetanei sysadmin da capire è che siamo fondamentalmente un centro di costo. A meno che non siamo nel business della gestione di sistemi a scopo di lucro, mettiamo a disposizione alcun beneficio diretto alla società. Questa è una delle ragioni per cui sono così entusiasta di automazione. John Willis veramente in risonanza con me nei primi Devops Cafe podcast quando ha parlato la divisione 80/20. Tradizionalmente il personale operativo spende l'80% del suo tempo si occupano di stronzate antincendio letame e il 20% effettivamente fornire valore per il business. L'idea che si possa capovolgere e che diventano soci sostenitori delle nostre rispettive aziende è sorprendente.
Non ti preoccupare. Io l'indirizzo di sviluppo al di sotto, ma ho sentito che era importante per impostare la mia prospettiva verso il basso prima di andare avanti.

Debito tecnica e Risk Management

Guardando indietro alla mia lista di take-away dal post precedente, faccio un bel grassetto (per alcune persone) dichiarazione. Quando dico che il rischio di implementare non è la stessa implementazione ma tutto fino a quel momento, io sto parlando di debito tecnico.
Debito tecnico prende molte forme ed è il risultato di entrambi coscienti, scelte deliberate così come effetti collaterali indesiderati. Alcuni esempi di ciò sono:
  • Mancanza o insufficienza di prova e associati
  • Overreliance su processi manuali che richiede tempo
  • Scorciatoie di rispettare le scadenze - sia artificiale e reale
  • Violazione dei 10 minuti di massima
  • Scelte tecnologiche
  • Scelte culturali
  • Limitazioni fiscali
Tutte queste cose possono portare a debito tecnico - l'accumulo di cadaveri nella stanza come un sottoprodotto di come lavoriamo. Nella migliore delle ipotesi, qualcuno almeno riconosce che esistono. Nel peggiore dei casi, ci scorta di mollette, stringiamo le narici e la speranza nessuno nota la puzza. Diamo l'indirizzo di un paio di cose fondamentali, prima di entrare in cose divertenti.

Analisi

Copertura di test è uno dei modi più semplici per gestire il rischio nello sviluppo di software. Una delle prime cose ad andare in un pizzico sta testando. Anche che assume che il test era in realtà una priorità ad un certo punto. Io non ho intenzione di arpa su cose come il code coverage 100%. Come ho detto in precedenza, gli esseri umani tendono a compensare. Copertura di test è però anche uno dei posti più facili per ottenere la vostra testa fuori dall'acqua. Se non si dispone di una cultura di impegno per la sperimentazione, è difficile ma non impossibile per iniziare. Non è necessario allo sviluppo di arresto per una settimana.
  1. Iniziate con un impegno di scrivere test per qualsiasi nuovo codice andando via.
  2. Come nascono i bug nel codice non testato, fare un banco di prova per il bug l'obbligo di chiudere il bug.
  3. Trova una piccola vittoria nel codice esistente. Creare copertura di test per la frutta a basso impiccagione.
  4. Piano per un programma per coprire qualsiasi codice rimanente
La chiave qui è piccoli passi. Piccole vittorie. Pensate Fezzik in 'La storia fantastica' - "Voglio farvi sentire come si sta vincendo".
I test sono uno dei fondamenti bisogna avere per raggiungere il nirvana distribuire. Gli amministratori di sistema hanno una grande responsiblity qui. L'esecuzione di test deve essere indolore, unobstrusive e performante. Si dovrebbe assolutamente stare in piedi qualcosa del genere Jenkins che esegue effettivamente la tua suite di test al momento del check-in. Come suite di test che cresce, è necessario essere in grado di fornire la capacità di crescere con essa. Ed è qui che il punto successivo può essere così importante.

Processi manuali

Come test è una fondazione sul lato codice, le operazioni ha una responsabilità proporzionata per ridurre il numero di mani umane coinvolte con la creazione di sistemi. Noi esseri umani, nonostante il potenziale incredibile che il nostro cervello forniscono, in genere sono stupidi. Facciamo degli errori. La ripetibilità non è qualcosa che siamo bravi a. Una sorta di strategia di configurazione automatizzate e ripetibili esigenze di gestione da adottare. Come nel caso di test, è possibile fare dei progressi incredibili in piccoli passi attraverso l'introduzione di una sorta di gestione della configurazione corretta in futuro. Non consiglio di tentare di retrofit di automazione complesse su sistemi esistenti al di là di alcuni principi fondamentali. Altrimenti sarete troppo tempo cercando di distinguere tra "eredità" e "nuovi" ruoli server.Se si utilizza una sorta di virtualizzazione o il fornitore di cloud come EC2, questa è una facile soluzione. E 'ovviamente un po' più difficile quando si utilizza l'hardware fisico ma ancora fattibile.
Avete mai giocato il piccolo puzzle game viaggio dove si ha una griglia di quadrati in movimento? L'idea è la stessa. È necessario un solo sistema vuota che è possibile lavorare con per automatizzare. Scegli il tuo ruolo più semplice del server come ad esempio un server web apache. Usando qualcosa come marionette o Chef, scrivere il 'codice' che creerà quel ruolo. Non impantanarsi nella roba fantasia gli strumenti forniti. Keep it simple in un primo momento. Una volta che pensi di aver ottenuto tutto ha funzionato, soffiare via il server e applicare il codice di bootstrap. Rosso, verde, refactoring. Una volta che sei a tuo agio che si può reprovision che server da metallo nudo, si muovono in servizio.Assicurati di avere il proprio set di 'test case' che garantiscono lo stato di provisioning è quella corretta. Questo sarà importante in seguito.
Prendere qualsiasi server è sostituire e fare lo stesso per il ruolo successivo. Quando sono arrivato a bordo con la mia azienda ho passato molti cicli inutile provare ad adattare un processo di automazione su sistemi esistenti. Alla fine, ho optato per prendere un paio di vittorie di piccole dimensioni (con Chef in questo caso):
  1. Creare un ruolo di base che non è distruttiva per la configurazione e sistemi esistenti. Nel mio caso, questa è stata la gestione di repository yum e gli account utente.
  2. Scegli il 'semplice' componente della nostra infrastruttura e iniziare a creare un ruolo per esso.
  3. Spin up di una nuova istanza EC2 e verificare il ruolo più e più volte finché non funziona.
  4. Terminare l'istanza e applicare il ruolo in cima con una nuova.
  5. Sostituire le vecchie istanze fornendo quel ruolo con quelli nuovi e passare al ruolo successivo.
Usando questa strategia, sono stato in grado di sostituire tutte le nostre istanze di eredità per i livelli primo e secondo il nostro stack in un paio di mesi di tempo. Siamo ora al punto in cui, assumendo Amazon gioca piacevole con la creazione ad esempio, possiamo avere un ruolo in quei livelli ricreato in un momento di preavviso. Di nuovo, questo contribuirà direttamente a come ridurre i rischi in seguito.

Massima 10 minuti

Mi si avvicinò con questo da principi primi, quindi sono sicuro che c'è un nome migliore per questo. L'idea è semplicemente questo:
Qualsiasi problema che deve essere risolto in cinque minuti si può permettere 10 minuti per pensare alla soluzione.

Gli amministratori di sistema spesso orgogliosi di quanto abilmente e rapidamente siamo in grado di risolvere un problema. E 'bene per il nostro ego. Non è, comunque, buona per la nostra azienda. Prendete un po 'di tempo e di considerare l'impatto a lungo termine della quale soluzione che stai per fare. Allontanati dalla scrivania e muoversi.Consultare coetanei. Molte volte sono giunto alla conclusione che il mio primo istinto è stato quello giusto. Tuttavia il più delle volte, ho incontrato un'altra soluzione che creerebbe debito meno tecnica per noi, per affrontare in seguito.
Un correlary a questa è la decisione di 'risolvere il problema o calci'. Che è 'Spendiamo una quantità imprevedibile di tempo cercando di risolvere qualche problema oscuro o dobbiamo semplicemente ricreare l'istanza che fornisce il servizio dalla nostra gestione della configurazione sopra'. Se avete superato la fase precedente, si dovrebbe avere fiducia sorprendenti codice nell'infrastruttura. Questo è molto importante avere con Amazon EC2, dove si può avere un esempio di eseguire gli straordinari peggio grazie alle meraviglie di oversubscription e vicini rumorosi.
Che cazzo. Disposizione una nuova istanza ed eseguire il test del fumo (I / O test per esempio). Se i test non fumo, buttarlo via e iniziare una nuova. È incredibile la libertà di movimento offerta da essere in grado di descrivere l'infrastruttura come codice.

Tornando a schiera

Direi che senza quanto sopra, la maggior parte delle cose da qui in avanti è abbastanza inutile. Mentre CAN fare automatizzate che non offhour distribuisce senza quanto sopra, sei davvero te stesso insediano per fallimento. Che si tratti di un cambiamento di sistema o il nuovo codice, è necessario essere in grado di garantire che alcuni criteri di base che possono essere soddisfatte. Ora che abbiamo le basi, però, possiamo costruire su di esso e, infine, adottare alcune strategie distinte per le release.

Costruito sulle fondamenta

Le aree successivo bisogno di lavorare su sono un po 'più difficile.

Metriche e monitoraggio

Riprese al buio fa schifo. Senza un qualche tipo di metriche di base, è autorevolmente dire se un implementazione era 'buono'. Se si muove, grafico. Se si muove, monitor. Hai bisogno di sistemi di leva come statsd (disponibile in non node.js sapori pure) in grado di accettare parametri facilmente dalla vostra applicazione e renderli availabile nel sorprendente grafite .
La chiave qui è che ottenere tali metriche essere il più possibile privo di attrito. Per comprendere appieno questo, guardate questa presentazione da Coda Hale di Yammer . Coda ha anche creato un kick-ass biblioteca metriche per la JVM e altri hanno duplicato i suoi sforzi nelle loro rispettive lingue.

Compatibilità all'indietro

È necessario adottare una cultura di compatibilità fra le release. Questo non è Microsoft livelli di cui stiamo parlando.Questo influisce release intermedia. Non appena si è aggiornato tutti i componenti, si pulisce il cruft e andare avanti.Questo è fondamentale per arrivare a zero / quasi a zero i tempi di inattività distribuisce.

Ridurre le interdipendenze

Io non entrerò in tutta la parola d'ordine SOA bingo gioco qui se non per dire che il trattamento dei vostri sistemi interni come un fornitore di terze parti possono avere alcuni benefici. Non è necessario isolare le squadre, ma è necessario fermare con merda come RMI. Hanno un'interfaccia stabilita e versionati tra i componenti. Se il componente A ha bisogno di effettuare una chiamata REST per il componente B, aggiornamenti alle API di B dovrebbe essere versione.Una necessità versione 1 di api di B. Nel frattempo C nuovo componente può usare la versione 2 delle API.

Automazione come default

Anche se questo legame molto nella sperimentazione e gli argomenti gestione della configurazione, il vero obiettivo qui è che si adotta un atteggiamento di automazione per default. La ragione di questo dovrebbe essere chiaro a Eric Ries '"Cinque Whys" post :
Cinque Whys spesso perforare l'illusione di dipartimenti separati e scoprire i problemi umani che si nascondono sotto la superficie di problemi apparentemente tecnici.

Uno dei modi migliori per eliminare i problemi umani è quello di togliere la umana del problema. Le macchine sono molto bravi a fare le cose più volte e fare nello stesso modo ogni volta unico. Gli esseri umani non sono bravo in questo.Lasciate le macchine lo fanno.

Implementare strategie

Ecco alcune delle strategie chiave che io (ed altri) hanno trovato efficaci per rendere distribuisce un problema non.

Lancia scuro

L'idea qui è che per qualsiasi percorso nuovo codice si inserisce nel sistema, è in realtà esercizio prima che va in diretta. Ammettiamolo, non si può mai simulare il traffico di produzione. L'unico modo per verificare se il codice è veramente performante o non è per farlo fuori. Con il lancio di un oscuro, si sta ancora facendo le chiamate al database nuovo, ma utilizzando la vostra cultura a portata di mano damerino parametri di cui sopra, ora sapete come è davvero performante. Quando si arriva a livelli accettabili, renderlo visibile all'utente.

Funzione di bandiere

Bandiere caratteristica sono incredibili e uno dei trucchetti che le persone che eseguono frequenti distribuisce leva.L'idea è che si fanno gli aspetti della vostra applicazione in una serie di alterna. Nel caso in cui qualche caratteristica sta causando problemi, potete semplicemente disabilitarlo attraverso qualche pannello di amministrazione o chiamata API.Non solo questo permette di degradazione scalabile ma fornisce anche un modo per A / B test di funzionalità nuove. Con un po 'più di pensiero messo nel processo, è possibile attivare una nuova funzionalità per un sottoinsieme di utenti. La gente ama sentirsi speciale. Essere parte di qualcosa come un canale "beta" è un modo fantastico per costruire sostenitori del sistema.

Prova di fumo in fase di avvio

Questo è quello che mi piace molto. L'idea è semplicemente che l'applicazione dispone di un set base di 'prove' che attraversa in fase di avvio. Se uno di questi test falliscono, il codice viene eseguito il rollback.
Ora è qui che qualcuno mi chiameranno un ipocrita perché ho detto che deve e non può mai realmente eseguire il rollback. Lei è in parte ragione. Nella mia mente, tuttavia, non è la stessa cosa. Considero il codice implementato una volta preso il traffico di produzione. Fino a quel momento, è solo 'pre-lavoro' essenzialmente. Diamo un servizio a caso API nel nostro stack. Sto assumendo che dispone di due server API in questo caso.
  • Prendete un fuori servizio
  • Distribuire codice
  • Eseguire test del fumo
  • Se i test non fumo, stop nuovo codice e iniziare il vecchio codice
  • Se il test del fumo passano, iniziare a inviare il traffico al server di produzione
  • Se è accettabile, spingere ad un altro server
  • profitto!
Ora si potrebbe vedere un po 'di gotcha lì. Ho volutamente lasciato fuori un passo. Questo è un po 'diverso da come negozi come Wealthfront farlo. In realtà DO rollback se il monitoraggio della produzione non riesce. La mia preferenza è quella di utilizzare qualcosa di simile a em-proxy per fare una sorta di mini-scuro prima di lanciare effettivamente girando per gli utenti finali. Non è necessario utilizzare effettivamente em-proxy. Si potrebbe scrivere il proprio o usare qualcosa come RabbitMQ o altro sistema di messaggistica. Questo non sempre funziona a seconda del servizio che fornisce il componente è ma fornisce un ulteriore livello di 'comodità'.
Naturalmente questo funziona solo se si mantiene la compatibilità all'indietro.

Compatibilità con il passato

Questo è probabilmente il più difficile da realizzare. Si può essere limitato dal vostro stack tecnologico o anche qualche decisione sbagliata fatta anni fa. La compatibilità vale anche per più di un semplice stack software. Questo è più o meno una componente fondamentale di gestione delle modifiche del database con downtime pari a zero.

Codice relativo

Il codice deve capire 'versioni' di cosa ha bisogno. Se si leva alcune API interne, è necessario mantenere il supporto per una versione precedente di tale API fino a quando tutti gli utenti l'aggiornamento. Siate sempre disapprovazione e MAI MAI ridefinire cosa significa qualcosa. Non modificare una proprietà o impostazione che significa "Questo è il mio server di database hostname" a "Questa è la mia mail server hostname". Invece di creare una nuova proprietà, iniziare ad usarlo e rimuovere il vecchio in una versione futura. Non ridete, ho visto fare. Per quanto ho frustrazioni con Java, funzioni di costruzione è un buon esempio di compatibilità all'indietro.

Base di dati relativi

In particolare in quanto si riferisce alle banche, in considerazione alcuni dei seguenti approcci:
  • Non effettuare modifiche dello schema all'indietro incompatibili.
  • Non eseguire ALTERI su tavoli molto grandi. Creare una nuova tabella che i sistemi aggiornati usare e copiare sul letto alla nuova tabella. Migrare vecchie registrazioni in background.
  • Considerate isolare l'accesso a una determinata tabella tramite un servizio. Invece di dare a tutti l'accesso alle applicazioni di tabella 'utenti', creare un servizio agli utenti che lo fa.
  • Iniziare l'allenamento percorsi di codice per le nuove tabelle primi sfruttando lancia scuro
Alcune di queste tecniche avrebbe fatto girare Codd nella tomba.
Stiamo vivendo una situazione simile in questo momento. Inizialmente abbiamo conservato una grande quantità di 'blob' di dati in Voldemort. Questo è stato un po 'sconcertante come abbiamo già sfruttando S3 per dati simili. Per migrare i dati (diverse centinaia di concerti), abbiamo preso il seguente approccio:
  • Distribuire una release minore che scrive e nuovi dati sia per Voldemort e S3.
  • Avviare un processo di 'copia' in background per migrare i dati più vecchi
  • Continua la migrazione dei dati
  • Quando la migrazione è terminata, faremo distribuire una nuova versione che utilizza esclusivamente S3
  • Utile (perché si arriva a terminare un paio di casi m1.large EC2)
Questo ha funzionato molto bene in questo scenario. Questi non sono nuove tecniche sia. In sostanza, stiamo facendo una variazione di un commit a due fasi.
Ora si potrebbe pensare che tutto questo crea cruff compatibilità all'indietro. Lo fa. Ancora una volta, questo è qualcosa che richiede un cambiamento culturale. Quando le cose non sono più necessari, è necessario ripulire il codice. Questo impedisce troppo grosso e fa capire che la strada molto più facile.

Oscillare come un boss

Ecco un altro esempio del mondo reale:
La nostra base di codice utilizzato in origine una casa laminati tecnica di bilanciamento del carico di comunicare con uno dei nostri servizi interni. Inoltre, tutte le comunicazioni tramite RPC con successo dell'Assia. Alla fine questo è diventato insostenibile e abbiamo deciso di trasferirsi a RabbitMQ e JSON. Questo è stato un cambiamento abbastanza importante, ma al valore nominale, saremmo stati in grado di gestire con interfacce duali del fornitore del servizio. Che non è accaduto.
Vedete, per essere in grado di utilizzare le librerie RabbitMQ, abbiamo dovuto aggiornare la nostra versione della Primavera. Di nuovo, non un grande affare. Tuttavia la nostra versione di dell'Assia era così vecchia che la versione di dell'Assia dovremmo utilizzare con la nuova versione della Primavera era indietro incompatibili. Questa è la rasatura yak al suo migliore, gente. Quindi, fondamentalmente abbiamo dovuto aggiornare 5 componenti diverse tutte in una volta solo per arrivare a dove volevamo e doveva essere per il lungo termine.
Dato che avevo già finito di codifica nostri libri di cucina dello chef, siamo andati lungo il sentiero di duplicare tutta la nostra front-end stack. Ciò che ha reso questo anche lontanamente possibile era il fatto che stavamo usando gestione della configurazione, in primo luogo. Ecco come è andato giù:
  • Duplicare i vari componenti in un ambiente nuovo chef chiamato 'prodB'
  • Spingere il nuovo codice a questi nuovi componenti
  • Aggiungere i nuovi componenti al ELBs e bilanciatori di carico interno di una finestra molto breve 5-10 minuti. Una sorta di mini-test A / B.
  • Controllare i registri per tutto ciò che si è distinto. Convalidato il comportamento previsto dei nuovi sistemi. Anche questo ci ha dato la possibilità di 'load-test' nostro setup RabbitMQ. Noi in realtà ha fatto prendere un paio di piccoli bug in questo modo.
Una volta eravamo sicuri che le cose sembrava buono, abbiamo oscillato tutto il traffico verso le nuove istanze e tirò fuori i vecchi. Non abbiamo mai nemmeno preso la briga di aggiornare le istanze di età. Abbiamo appena li chiuse.
Ovviamente questa tecnica non funziona per tutti. Se stai usando hardware fisico, è molto più costoso e più difficile da tirare fuori. Anche internamente, tuttavia, è possibile sfruttare la virtualizzazione per fare questo genere di cose possibili.

Bitrot

Quale dovrebbe essere la vera storia in questo è che bitrot accade. Non gioco sui tenere librerie di terze parti in corso. Se una libreria di terze parti introduce una modifica sostanziale e colpisce più di una parte del tuo stack, probabilmente avete un po 'troppo stretta di un raccordo tra le risorse.

Wrap up / Portare via

Questo post è venuto fuori più a lungo di quanto avessi previsto. Spero che sia fornito con alcune informazioni e cose da considerare. Aziende di tutte, i mercati le forme e dimensioni stanno facendo implementazione continua, tempi di inattività e distribuisce tutta una serie di cose che non abbiamo mai ritenuto possibile. Guarda aziende come Wealthfront, IMVU, Flickr e su Etsy. Google in giro per frasi come 'impiego continuo' e 'erogazione continua'.
Sono anche dolorosamente consapevoli del fatto che anche con questi trucchi, alcune persone semplicemente non possono fare. Ci sono molti settori dell'industria che potrebbe anche non tenerne conto. Ciò non significa che alcune di queste idee non possono essere attuate su scala minore. Fonte: http://blog.lusis.org/blog/2011/10/18/deploy-all-the-things/

Nessun commento:

Posta un commento

Nota. Solo i membri di questo blog possono postare un commento.