Approccio di Google Cloud al cambiamento

Ogni anno miliardi di utenti interagiscono con i prodotti e i servizi Google. Offerte chiave come Ricerca, Gmail, Maps, YouTube, Chrome e ora anche Google Cloud sono così perfettamente integrate nella vita moderna che contribuiscono a definire l'esperienza del 21° secolo. Questo impatto a livello mondiale è il risultato della comprovata qualità delle nostre offerte e dell'aspettativa che Google sia sempre disponibile.

In Google Cloud introduciamo continuamente modifiche al codice dei nostri prodotti e servizi per garantire la migliore esperienza utente possibile, migliorare la sicurezza e l'affidabilità e rispettare i requisiti normativi e di conformità. Qualsiasi modifica di questo tipo, grande o piccola che sia, a volte può causare dei problemi. Per gestire questo rischio, diamo la priorità alla sicurezza delle modifiche durante l'intero ciclo di vita di una modifica.

Questo documento spiega in che modo i team di Google Cloud si basano sugli investimenti decennali di Google nell'eccellenza dello sviluppo per implementare best practice di affidabilità e standard di ingegneria che soddisfano le aspettative dei clienti di Google Cloud in termini di velocità e affidabilità dello sviluppo.

Il ciclo di vita di una modifica in Google Cloud

I team di prodotto di Google Cloud condividono gran parte della procedura di gestione e degli strumenti con altri team tecnici di Google. Implementiamo un approccio standard per lo sviluppo di software per la gestione del cambiamento che dà la priorità all'integrazione continua (CI) e alla distribuzione continua (CD). CI continua prevede la proposta, il test e l'invio frequente di modifiche, spesso più volte al giorno per un determinato prodotto o servizio. Il CD è un'estensione dellCI;integrazione continua in cui gli ingegneri preparano continuamente candidati alla release in base all'ultimo snapshot stabile di una base di codice.

Questo approccio dà la priorità alla creazione e all'implementazione delle modifiche in più fasi per i clienti Google Cloud il prima possibile, ma anche nel modo più sicuro possibile. Prendiamo in considerazione la sicurezza delle modifiche prima di scrivere qualsiasi codice e continuiamo a concentrarci sulla sicurezza anche dopo aver implementato le modifiche in produzione. Il nostro modello di gestione del cambiamento prevede quattro fasi generali: progettazione, sviluppo, qualifica e implementazione. Queste quattro fasi sono mostrate nel seguente diagramma e vengono descritte in maggiore dettaglio nel presente documento:

Diagramma che mostra i passaggi per le fasi di progettazione, sviluppo, qualifica e implementazione.

La sicurezza prima di tutto

Siamo consapevoli che anche piccoli errori all'inizio del processo di sviluppo possono causare grandi problemi in un secondo momento e influire notevolmente sulle esperienze dei clienti. Di conseguenza, tutte le modifiche sostanziali devono iniziare con un documento di progettazione approvato. Abbiamo un modello di documento di progettazione comune per consentire ai team di ingegneria di proporre modifiche sostanziali. Questo documento di progettazione comune ci aiuta a valutare in modo coerente le modifiche principali ai prodotti Google Cloud. Il seguente diagramma mostra la nostra procedura di progettazione standard per una modifica importante:

Diagramma dettagliato dei passaggi della fase di progettazione.

La fase di progettazione inizia quando uno sviluppatore software propone una modifica che tenga conto dei requisiti aziendali, tecnici, di costo e di manutenzione. Dopo aver inviato la modifica, viene avviata una procedura di revisione e approvazione completa con esperti di alto livello, tra cui esperti di affidabilità e sicurezza, nonché responsabili tecnici. I lavori per implementare la modifica possono procedere solo dopo che l'ingegnere che ha proposto il design ha risposto a tutti i feedback degli esperti e ogni esperto ha approvato il design. Questa procedura di progettazione e revisione riduce la probabilità che i team di prodotto di Google Cloud inizino a lavorare su modifiche che potrebbero avere un impatto negativo sui clienti in produzione.

Sicuro come sviluppato

La nostra procedura di sviluppo del codice ne aumenta la qualità e l'affidabilità. Dopo l'approvazione di una modifica proposta, il processo di sviluppo inizia con un onboarding completo per i nuovi ingegneri, che include formazione, tutoraggio e feedback dettagliati sulle modifiche al codice proposte. Un approccio di sviluppo e testing a più livelli con test manuali e automatici convalida continuamente il codice in ogni fase di sviluppo. Ogni modifica al codice viene esaminata attentamente per verificare che soddisfi gli elevati standard di Google.

Il seguente diagramma fornisce un flusso di lavoro che illustra approssimativamente la nostra procedura di sviluppo:

Diagramma dettagliato dei passaggi della fase di sviluppo.

La fase di sviluppo inizia quando un ingegnere inizia a scrivere codice e i test di unità e integrazione corrispondenti. Durante questa fase, l'ingegnere può eseguire i test che ha scritto e una suite di test di preinvio per assicurarsi che le aggiunte e le modifiche al codice siano valide. Dopo aver completato le modifiche al codice ed eseguito i test, l'ingegnere richiede una revisione manuale da parte di un'altra persona che abbia familiarità con il codice. Questa procedura di revisione da parte di persone è spesso iterativa e può comportare ulteriori revisioni del codice. Quando l'autore e il revisore raggiungono un consenso, l'autore invia il codice.

Gli standard di codifica garantiscono modifiche di alta qualità

La cultura, le pratiche e gli strumenti di ingegneria di Google sono progettati per garantire che il nostro codice sia corretto, chiaro, conciso ed efficiente. Lo sviluppo del codice in Google avviene nel nostro monorepo, il repository di codice integrato più grande al mondo. Il monorepo contiene milioni di file di codice sorgente, miliardi di righe di codice e una cronologia di centinaia di milioni di commit chiamati elenchi di modifiche. Continua a crescere rapidamente, con decine di migliaia di nuovi elenchi di modifiche aggiunti ogni giorno lavorativo. I vantaggi principali del monorepo sono che semplifica il riutilizzo del codice, facilita la gestione delle dipendenze e impone flussi di lavoro degli sviluppatori coerenti tra prodotti e servizi.

Il riutilizzo del codice è utile perché abbiamo già una buona idea del funzionamento del codice riutilizzato in produzione. Sfruttando il codice di alta qualità esistente, le modifiche sono intrinsecamente più solide e facili da gestire allo standard richiesto. Questa pratica non solo consente di risparmiare tempo e fatica, ma garantisce anche che la salute complessiva della base di codice rimanga elevata, il che si traduce in prodotti più affidabili.

I servizi Google Cloud basati su software open source di alta qualità possono integrare il monorepo con un altro repository, in genere Git, per utilizzare il branching per gestire il software open source.

Una nota sulla formazione

L'investimento nella qualità del codice inizia quando un ingegnere si unisce a un team. Se l'ingegnere è nuovo in Google o ha meno dimestichezza con l'infrastruttura e l'architettura del team, deve seguire un'onboarding approfondita. Nell'ambito di questo onboarding, studiano guide di stile, best practice e guide di sviluppo ed eseguono manualmente esercizi pratici. Inoltre, i nuovi ingegneri richiedono un livello aggiuntivo di approvazione per ogni singolo invio della lista di modifiche. L'approvazione per le modifiche in un determinato linguaggio di programmazione viene concessa da ingegneri che hanno superato un rigoroso insieme di aspettative in base alla loro esperienza e hanno ottenuto la leggibilità in quel linguaggio di programmazione. Qualsiasi ingegnere può ottenere la leggibilità per un linguaggio di programmazione. La maggior parte dei team ha più approvatori per i linguaggi di programmazione in cui scrive il codice.

Shift a sinistra migliora la velocità in sicurezza

Shift a sinistra è un principio che sposta i test e la convalida all'inizio del processo di sviluppo. Questo principio si basa sulla nostra osservazione che i costi aumentano notevolmente più avanti nel processo di rilascio quando individuiamo e correggiamo un bug. In un caso estremo, prendi in considerazione un bug rilevato da un cliente in produzione. Questo bug potrebbe influire negativamente sui carichi di lavoro e sulle applicazioni del cliente. Inoltre, il cliente potrebbe dover seguire la procedura del team di assistenza clienti Google Cloud prima che il team tecnico competente possa mitigare il bug. Se un tecnico assegnato per risolvere il problema è una persona diversa da quella che ha introdotto inizialmente la modifica contenente il bug, il nuovo tecnico dovrà acquisire familiarità con le modifiche al codice, aumentando probabilmente il tempo necessario per riprodurre e infine correggere il bug. L'intera procedura richiede molto tempo ai clienti e all'assistenza di Google Cloud e richiede agli ingegneri di interrompere il lavoro su cui stanno lavorando per risolvere il problema.

Al contrario, prendi in considerazione un bug rilevato da un errore di test automatico mentre un ingegnere sta lavorando a una modifica in fase di sviluppo. Quando l'ingegnere nota il fallimento del test, può correggerlo immediatamente. A causa dei nostri standard di codifica, l'ingegnere non sarebbe nemmeno in grado di inviare la modifica con il fallimento del test. Questo rilevamento precoce consente all'ingegnere di correggere il bug senza alcun impatto sul cliente e senza costi aggiuntivi per il passaggio di contesto.

Quest'ultimo scenario è infinitamente preferibile per tutte le parti coinvolte. Di conseguenza, nel corso degli anni, Google Cloud ha investito molto in questo principio di scorrimento verso sinistra spostando i test tradizionalmente eseguiti durante le fasi di qualificazione e di implementazione delle modifiche direttamente nel loop di sviluppo. Oggi, tutti i test di unità, tutti i test di integrazione tranne i più grandi e analisi statiche e dinamiche approfondite vengono completati in parallelo mentre un ingegnere propone modifiche al codice.

I test di preinvio automatici applicano gli standard di codifica

I test di preinvio sono controlli eseguiti prima che qualsiasi modifica venga inviata in una determinata directory. I test di preinvio possono essere test di unità e di integrazione specifici per una modifica o test generali (ad esempio analisi statica e dinamica) che vengono eseguiti per qualsiasi modifica. In passato, i test di preinvio venivano eseguiti come ultimo passaggio prima che qualcuno inviasse una modifica a una base di codice. Oggi, in parte a causa del principio di shift left e della nostra implementazione dellCI;integrazione continua, eseguiamo i test di preinvio in modo continuo mentre un tecnico apporta modifiche al codice in un ambiente di sviluppo e prima di unire le modifiche nel nostro monorepo. Un ingegnere può anche eseguire manualmente un insieme di test pre-invio con un solo clic nell'interfaccia utente di sviluppo e ogni test pre-invio viene eseguito automaticamente per ogni elenco di modifiche prima di un esame del codice da parte di un essere umano.

La suite di test pre-invio in genere copre test di unità, test di fuzz (fuzzing), test di integrazione ermetici, nonché analisi del codice statico e dinamico. Per le modifiche alle librerie di base o al codice ampiamente utilizzato in Google, gli sviluppatori eseguono un pre-invio globale. Un pre-invio globale testa la modifica sull'intero codebase di Google, riducendo al minimo il rischio che una modifica proposta influisca negativamente su altri progetti o sistemi.

Test di unità e integrazione

I test accurati sono parte integrante del processo di sviluppo del codice. Tutti devono scrivere test delle unità per le modifiche al codice e monitoriamo continuamente la copertura del codice a livello di progetto per assicurarci di convalidare il comportamento previsto. Inoltre, richiediamo che qualsiasi percorso utente critico abbia test di integrazione in cui convalidiamo la funzionalità di tutti i componenti e le dipendenze necessari.

I test di unità e tutti i test di integrazione tranne i più grandi sono progettati per essere completati rapidamente e vengono eseguiti in modo incrementale con un elevato parallelismo in un ambiente distribuito, il che si traduce in un feedback rapido e continuo sullo sviluppo automatico.

Fuzzing

Mentre i test di unità e di integrazione ci aiutano a convalidare il comportamento previsto con input e output predeterminati, il fuzzing è una tecnica che bombarda un'applicazione con input casuali, allo scopo di rilevare difetti o debolezze nascosti che potrebbero portare a vulnerabilità o arresti anomali della sicurezza. Il fuzzing ci consente di identificare e risolvere in modo proattivo potenziali punti deboli del nostro software, migliorando la sicurezza e l'affidabilità complessive dei nostri prodotti prima che i clienti interagiscano con le modifiche. La casualità di questi test è particolarmente utile perché a volte gli utenti interagiscono con i nostri prodotti in modi interessanti che non prevediamo e il fuzzing ci aiuta a tenere conto di scenari che non abbiamo considerato manualmente.

Analisi statica

Gli strumenti di analisi statica svolgono un ruolo fondamentale nel mantenere la qualità del codice nei nostri flussi di lavoro di sviluppo. L'analisi statica si è evoluta notevolmente dai primi giorni del linting con espressioni regolari per identificare pattern di codice C++ problematici. Attualmente, l'analisi statica copre tutti i linguaggi di produzione di Google Cloud e trova pattern di codice errati, inefficienti o ritirati.

Con frontend del compilatore e modelli LLM avanzati, possiamo proporre automaticamente miglioramenti mentre gli ingegneri scrivono il codice. Ogni modifica al codice proposta viene esaminata con analisi statiche. Man mano che aggiungiamo nuovi controlli statici nel tempo, l'intero codebase viene sottoposto a scansione costante per verificare la conformità e le correzioni vengono generate automaticamente e inviate per la revisione.

Analisi dinamica

Mentre l'analisi statica si concentra sull'identificazione di pattern di codice noti che possono causare problemi, l'analisi dinamica adotta un approccio diverso. È necessario compilare e eseguire il codice per rilevare i problemi che si verificano solo durante l'esecuzione, come violazioni della memoria e condizioni di gara. Google ha una lunga storia di utilizzo dell'analisi dinamica e ha persino condiviso diversi dei suoi strumenti con la più ampia community di sviluppatori, tra cui:

  • AddressSanitizer: rileva errori di memoria come overflow del buffer e use-after-free
  • ThreadSanitizer (C++, Go): rileva race di dati e altri bug di threading
  • MemorySanitizer: scova l'utilizzo di memoria non inizializzata

Questi strumenti e altri simili sono essenziali per rilevare bug complessi che non possono essere rilevati solo tramite l'analisi statica. Utilizzando sia l'analisi statica sia quella dinamica, Google si impegna a garantire che il proprio codice sia ben strutturato, esente da problemi noti e si comporti come previsto in scenari reali.

Le revisioni del codice da parte di persone convalidano le modifiche e i risultati dei test

Quando un ingegnere raggiunge un traguardo critico nel codice e vuole integrarlo nel repository principale, avvia una revisione del codice proponendo un elenco di modifiche. Una richiesta di revisione del codice è costituita da:

  • Una descrizione che descriva lo scopo delle modifiche e qualsiasi altro contesto
  • Il codice modificato effettivo
  • Test delle unità e eventuali test di integrazione per il codice modificato
  • Risultati del test di preinvio automatico

È in questo punto del processo di sviluppo che interviene un'altra persona. Uno o più revisori designati esaminano attentamente l'elenco delle modifiche per verificarne la correttezza e la chiarezza, utilizzando come guida i test allegati e i risultati precedenti l'invio. Ogni directory di codice ha un insieme di revisori designati responsabili di garantire la qualità di quel sottoinsieme della base di codice e la cui approvazione è necessaria per apportare modifiche all'interno della directory. I revisori e gli ingegneri collaborano per individuare e risolvere eventuali problemi che potrebbero sorgere con una modifica del codice proposta. Quando il listino delle modifiche soddisfa i nostri standard, un revisore dà la sua approvazione ("LGTM", acronimo di "Looks good to me", ovvero "Ok"). Tuttavia, se l'ingegnere è ancora in fase di formazione per il linguaggio di programmazione utilizzato, deve ottenere l'approvazione di un esperto che abbia dimostrato la leggibilità del linguaggio di programmazione.

Dopo che una lista di modifiche supera i test e i controlli automatici e riceve un LGTM, l'ingegnere che ha proposto la modifica può apportare solo modifiche minime al codice. Eventuali modifiche sostanziali invalidano l'approvazione e richiedono un'altra revisione. Anche le piccole modifiche vengono segnalate automaticamente ai revisori originali. Una volta che l'ingegnere invia il codice finalizzato, questo viene sottoposto a un altro ciclo completo di test di pre-invio prima che l'elenco delle modifiche venga unito al monorepo. Se uno o più test non vanno a buon fine, l'invio viene rifiutato e lo sviluppatore e i revisori ricevono un avviso per intraprendere un'azione correttiva prima di riprovare a inviare le modifiche.

Idoneità alla distribuzione sicura

Sebbene i test di preinvio siano completi, non rappresentano la fine della procedura di test di Google. I team spesso hanno test aggiuntivi, come i test di integrazione su larga scala, che non sono possibili da eseguire durante la revisione iniziale del codice (l'esecuzione potrebbe richiedere più tempo o ambienti di test ad alta fedeltà). Inoltre, i team devono essere a conoscenza di eventuali errori causati da fattori al di fuori del loro controllo, come le modifiche alle dipendenze esterne.

Ecco perché Google richiede una fase di qualificazione dopo la fase di sviluppo. Questa fase di qualificazione utilizza un processo di compilazione e test continuo, come mostrato nel seguente diagramma:

Diagramma dettagliato dei passaggi della fase di qualificazione.

Questo processo esegue periodicamente test per tutto il codice interessato da modifiche dirette o indirette dall'ultima esecuzione. Eventuali errori vengono riassegnati automaticamente al team di ingegneria responsabile. In molti casi, il sistema è in grado di identificare automaticamente il file di variazioni che ha causato l'interruzione e di eseguire il relativo rollback. Questi test di integrazione su larga scala vengono eseguiti in una serie di ambienti di staging che vanno da ambienti parzialmente simulati a intere sedi fisiche.

I test hanno una serie di obiettivi di qualificazione che vanno dall'affidabilità di base alla sicurezza alla logica di business. Questi test di idoneità includono il test del codice per quanto segue:

  • La capacità di fornire le funzionalità richieste, che viene testata utilizzando test di integrazione su larga scala
  • La capacità di soddisfare i requisiti aziendali, testata con rappresentazioni sintetiche dei carichi di lavoro dei clienti
  • La capacità di gestire i guasti dell'infrastruttura sottostante, che viene testata mediante l'iniezione di errori nello stack
  • La capacità di sostenere la capacità di pubblicazione, che viene testata con framework di test di carico
  • La possibilità di eseguire il rollback in sicurezza

Implementazioni sicure

Anche con le procedure di sviluppo, test e qualifica più rigorose, a volte si verificano difetti negli ambienti di produzione che influiscono negativamente sui nostri utenti. In questa sezione spiegheremo in che modo la procedura di implementazione di Google Cloud limita l'impatto delle modifiche con errori e garantisce il rilevamento rapido di eventuali regressioni. Applichiamo questo approccio a tutti i tipi di modifiche implementate in produzione, inclusi binari, configurazioni, aggiornamenti dello schema, modifiche della capacità e liste di controllo dell'accesso.

Modificare la propagazione e la supervisione

Applichiamo un approccio coerente al deployment delle modifiche in Google Cloud per minimizzare gli impatti negativi sui clienti e isolare i problemi in singoli domini di errori logici e fisici. Il processo si basa sulle nostre pratiche di affidabilità SRE di decenni e sul nostro sistema di monitoraggio su scala planetaria per rilevare e mitigare le modifiche errate il più rapidamente possibile. Il rilevamento rapido ci consente di informare i clienti più rapidamente e di adottare azioni correttive per evitare sistematicamente che si verifichino nuovamente errori simili.

La maggior parte dei prodotti Google Cloud è a livello di regione o zona. Ciò significa che un prodotto regionale pubblicato nella regione A è indipendente dallo stesso prodotto pubblicato nella regione B. Analogamente, un prodotto zonale in esecuzione nella zona C della regione A è indipendente dallo stesso prodotto zonale in esecuzione nella zona D della regione A. Questa architettura riduce al minimo il rischio di un'interruzione del servizio che colpisca altre regioni o altre zone all'interno di una singola regione. Alcuni servizi, come IAM o la console Google Cloud, forniscono un livello coerente a livello globale che copre tutte le regioni, motivo per cui li chiamiamo servizi globali. I servizi globali vengono replicati nelle regioni per evitare single point of failure e ridurre al minimo la latenza. La piattaforma di implementazione condivisa di Google Cloud è consapevole se un servizio è a livello di zona, di regione o globale e orchestra le modifiche in produzione in modo appropriato.

Il processo di implementazione di Google Cloud suddivide tutte le repliche di un servizio di cui è stato eseguito il deployment su più località target in ondate. Le ondate iniziali includono un numero ridotto di repliche, con gli aggiornamenti che procedono in serie. Le ondate iniziali bilanciano la protezione della maggior parte dei carichi di lavoro dei clienti con la massimizzazione dell'esposizione alla diversità dei carichi di lavoro per rilevare i problemi il prima possibile e includono carichi di lavoro sintetici che simulano i pattern di carico di lavoro comuni dei clienti.

Se l'implementazione continua a essere eseguita correttamente man mano che le repliche del servizio vengono aggiornate nelle località di destinazione, le successive ondate di implementazione aumentano progressivamente di dimensioni e introducono un maggiore parallelismo. Anche se è necessario un certo parallelismo per tenere conto del numero di località di Google Cloud, non sono consentiti aggiornamenti simultanei alle località che si trovano in ondate diverse. Se un'ondata si protrae fino a notte fonda o nel fine settimana, può completare la sua progressione, ma non è possibile avviare una nuova ondata fino all'inizio dell'orario di lavoro del team che gestisce l'implementazione.

Il seguente diagramma è un esempio di flusso di lavoro che illustra la logica di implementazione che utilizziamo in Google Cloud per i prodotti e i servizi a livello di regione:

Diagramma dettagliato dei passaggi coinvolti nella fase di implementazione.

Il processo di implementazione di Google Cloud utilizza il Canary Analysis Service (CAS) per automatizzare i test A/B per tutta la durata di un'implementazione. Alcune repliche diventano canarini (ovvero un deployment parziale e limitato nel tempo di una modifica in un servizio) e le repliche rimanenti costituiscono il gruppo di controllo che non include la modifica. Ogni passaggio della procedura di implementazione ha un tempo di attesa per rilevare i problemi latenti prima di passare al passaggio successivo, in modo da garantire che tutte le funzionalità di un servizio vengano esercitate correttamente e che eventuali anomalie vengano rilevate da CAS. Il tempo di compilazione è definito con attenzione per bilanciare il rilevamento di problemi a lenta combustione con la velocità di sviluppo. L'implementazione di Google Cloud richiede in genere una settimana.

Questo diagramma fornisce una rapida panoramica del flusso di lavoro del CAS:

Diagramma dei passaggi seguiti nel flusso di lavoro del CAS.

Il flusso di lavoro inizia con lo strumento di implementazione che esegue il deployment della modifica nella replica canary. Lo strumento di implementazione richiede quindi un verdetto da CAS. CAS valuta la replica del canary rispetto al gruppo di controllo e restituisce un verdetto PASS o FAIL. Se un indicatore di stato non va a buon fine, viene generato un avviso per i proprietari del servizio e il passaggio in esecuzione dell'implementazione viene messo in pausa o viene eseguito il rollback. Se la modifica causa interruzione del servizio per i clienti esterni, viene dichiarato un incidente esterno e i clienti interessati vengono avvisati utilizzando il servizio Stato del servizio personalizzato. Gli incidenti attivano anche una revisione interna. La filosofia di Google relativa ai post mortem garantisce che venga identificata e applicata la giusta serie di azioni correttive per minimizzare la probabilità che si verifichino nuovamente errori simili.

Indicatori di monitoraggio e sicurezza post-implementazione

I difetti del software non si manifestano sempre immediatamente e alcuni potrebbero richiedere circostanze specifiche per essere attivati. Per questo motivo, continuiamo a monitorare i sistemi di produzione al termine di un'implementazione. Nel corso degli anni, abbiamo notato che anche se un'implementazione non attiva immediatamente problemi, è comunque la causa più probabile di un incidente di produzione. Per questo motivo, i nostri playbook di produzione chiedono agli addetti alla gestione degli incidenti di correlare gli implementamenti recenti ai problemi osservati e di ripristinare per impostazione predefinita un implementamento recente se non possono escludere che le modifiche recenti siano la causa principale dell'incidente.

Il monitoraggio post-implementazione si basa sullo stesso insieme di indicatori di monitoraggio che utilizziamo per le analisi A/B automatiche durante una finestra di implementazione. La filosofia di monitoraggio e generazione di avvisi di Google Cloud combina due tipi di monitoraggio: introspettivo (noto anche come white-box) e sintetico (noto anche come black-box). Il monitoraggio introspettivo utilizza metriche come l'utilizzo della CPU, l'utilizzo della memoria e altri dati dei servizi interni. Il monitoraggio sintetico esamina il comportamento del sistema dal punto di vista del cliente, monitorando i tassi di errore del servizio e le risposte al traffico sintetico dei servizi di prober. Il monitoraggio sintetico è orientato ai sintomi e identifica i problemi attivi, mentre il monitoraggio introspettivo ci consente di diagnosticare i problemi confermati e, in alcuni casi, di identificare i problemi imminenti.

Per facilitare il rilevamento di incidenti che interessano solo alcuni clienti, raggruppiamo i carichi di lavoro dei clienti in coorti di carichi di lavoro correlati. Gli avvisi vengono attivati non appena il rendimento di una coorte si discosta dalla norma. Questi avvisi ci consentono di rilevare le regressioni specifiche per i clienti anche se il rendimento aggregato sembra essere normale.

Protezione della catena di fornitura del software

Ogni volta che i team di Google Cloud introducono modifiche, utilizziamo un controllo di sicurezza chiamato Autorizzazione dei binari per Borg (BAB) per proteggere la nostra catena di approvvigionamento del software e i clienti di Cloud dai rischi legati agli addetti ai lavori. BAB viene avviato nella fase di revisione del codice e crea un audit trail del codice e della configurazione di cui è stato eseguito il deployment in produzione. Per garantire l'integrità della produzione, BAB consente solo modifiche che soddisfano i seguenti criteri:

  • Sono a prova di manomissione e firmati
  • Provenire da un team di compilazione e da una posizione di origine identificati
  • Essere stati esaminati e approvati esplicitamente da una parte distinta dall'autore del codice

Se ti interessa applicare alcuni degli stessi concetti nel ciclo di vita di sviluppo del tuo software, abbiamo incluso i concetti chiave di BAB in una specifica aperta chiamata Supply-chain Levels for Software Artifacts (SLSA). SLSA funge da framework di sicurezza per lo sviluppo e l'esecuzione di codice negli ambienti di produzione.

Conclusione

Google Cloud si basa sui decenni di investimenti di Google nell'eccellenza dello sviluppo. L'integrità del codice e l'integrità della produzione sono principi culturali instillati in tutti i team di ingegneria di Google. La nostra procedura di revisione del design garantisce che le implicazioni sul codice e sull'integrità della produzione vengano prese in considerazione in una fase iniziale. Il nostro procedura di sviluppo, basata sul principio di spostamento a sinistra e su test approfonditi, garantisce che le idee di design vengano implementate in modo sicuro e corretto. La nostra procedura di qualifica estende ulteriormente i test per coprire le integrazioni su larga scala e le dipendenze esterne. Infine, la nostra piattaforma di implementazione ci consente di acquistare gradualmente la certezza che una determinata modifica funzioni effettivamente come previsto. Dal concepimento alla produzione, il nostro approccio ci consente di soddisfare le aspettative dei clienti di Google Cloud sia in termini di velocità di sviluppo sia di affidabilità.