Implementazione di deployment canary di Cloud Run con rami Git e Cloud Build

Last reviewed 2023-05-26 UTC

Questo documento mostra come implementare una pipeline di deployment per Cloud Run che implementa un avanzamento del codice dai rami di sviluppo alla produzione con test canary automatici e gestione del traffico basata su percentuale. È destinata agli amministratori di piattaforma responsabili della creazione e della gestione delle pipeline CI/CD. Questo documento presuppone che tu abbia una conoscenza di base dei concetti di base delle pipeline Git, Cloud Run e CI/CD.

Cloud Run ti consente di eseguire il deployment delle tue applicazioni e di eseguirle con uno sforzo minimo o un sovraccarico. Molte organizzazioni usano solide pipeline di rilascio per portare il codice in produzione. Cloud Run offre funzionalità esclusive di gestione del traffico che ti consentono di implementare tecniche avanzate di gestione delle release con il minimo sforzo.

Obiettivi

  • Crea il tuo servizio Cloud Run
  • Abilita un ramo sviluppatori
  • Implementare i test canary
  • Implementa in modo sicuro in produzione

Costi

In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il Calcolatore prezzi. I nuovi utenti di Google Cloud possono essere idonei a una prova senza costi aggiuntivi.

Prima di iniziare

  1. Nella pagina del selettore di progetti della console Google Cloud, seleziona o crea un progetto Google Cloud.

    Vai al selettore progetti

  2. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  3. Nella console Google Cloud, attiva Cloud Shell.

    Attiva Cloud Shell

    Nella parte inferiore della console Google Cloud viene avviata una sessione di Cloud Shell che mostra un prompt della riga di comando. Cloud Shell è un ambiente shell con Google Cloud CLI già installato e con valori già impostati per il progetto attuale. L'inizializzazione della sessione può richiedere alcuni secondi.

Preparazione dell'ambiente

  1. In Cloud Shell, crea variabili di ambiente da utilizzare in questo tutorial:

    export PROJECT_ID=$(gcloud config get-value project)
    export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
    
  2. Abilita le seguenti API:

    • Resource Manager
    • GKE
    • Cloud Build
    • Container Registry
    • Cloud Run
    gcloud services enable \
        cloudresourcemanager.googleapis.com \
        container.googleapis.com \
        secretmanager.googleapis.com \
        cloudbuild.googleapis.com \
        containerregistry.googleapis.com \
        run.googleapis.com
    
  3. Concedi il ruolo Amministratore Cloud Run (roles/run.admin) all'account di servizio Cloud Build

    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member=serviceAccount:[email protected] \
      --role=roles/run.admin
    
  4. Concedi il ruolo Utente account di servizio IAM (roles/iam.serviceAccountUser) all'account di servizio Cloud Build per l'account di servizio di runtime Cloud Run

    gcloud iam service-accounts add-iam-policy-binding \
    [email protected] \
      --member=serviceAccount:[email protected] \
      --role=roles/iam.serviceAccountUser
    

Imposta valori Git

Se non hai mai utilizzato Git in Cloud Shell, imposta i valori user.name e user.email che vuoi utilizzare:

    git config --global user.email YOUR_EMAIL_ADDRESS
    git config --global user.name YOUR_USERNAME
    git config --global credential.helper store
  • YOUR_EMAIL_ADDRESS: l'email utilizzata con il tuo account GitHub
  • YOUR_USERNAME: il tuo ID utente GitHub

Se utilizzi l'MFA con GitHub, crea un token di accesso personale e utilizzalo come password quando interagisci con GitHub tramite la riga di comando.

Archivia il tuo ID utente GitHub in una variabile di ambiente per un accesso più semplice:

export GH_USER=YOUR_GITHUB_ID

Crea un fork del repository del progetto

Per creare una versione scrivibile del repository del lab, crea un fork del repository di esempio nel tuo account GitHub tramite l'interfaccia utente di GitHub.

Clona il repository di esempio

Clona e prepara il repository di esempio:

git clone https://github.com/$GH_USER/software-delivery-workshop.git cloudrun-progression

cd cloudrun-progression/labs/cloudrun-progression

Connetti il repository Git.

Cloud Build consente di creare e gestire le connessioni ai repository di codice sorgente utilizzando la console Google Cloud. Puoi creare e gestire le connessioni utilizzando la prima o la seconda generazione di repository Cloud Build. Questo tutorial utilizza repository Cloud Build di seconda generazione.

Concedi le autorizzazioni richieste

Per connettere l'host GitHub, concedi il ruolo Amministratore connessione Cloud Build (roles/cloudbuild.connectionAdmin) al tuo account utente:

PN=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)")
CLOUD_BUILD_SERVICE_AGENT="service-${PN}@gcp-sa-cloudbuild.iam.gserviceaccount.com"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
 --member="serviceAccount:${CLOUD_BUILD_SERVICE_AGENT}" \
 --role="roles/secretmanager.admin"

Crea la connessione host

  1. Configura la connessione al repository Cloud Build:

    gcloud alpha builds connections create github $GH_USER --region=us-central1
    
  2. Fai clic sul link fornito nell'output e segui le istruzioni sullo schermo per completare la connessione.

  3. Verifica l'installazione della tua connessione GitHub:

    gcloud alpha builds connections describe $GH_USER --region=us-central1
    

Utilizzando la connessione host appena configurata, collega il repository di esempio che hai creato con il fork:

 gcloud alpha builds repositories create cloudrun-progression \
     --remote-uri=https://github.com/$GH_USER/software-delivery-workshop.git \
     --connection=$GH_USER \
     --region=us-central1

Imposta variabile del nome del repository

Archivia il nome del repository per utilizzarlo in seguito:

export REPO_NAME=projects/$PROJECT_ID/locations/us-central1/connections/$GH_USER/repositories/cloudrun-progression

Esegui il deployment del tuo servizio Cloud Run

In questa sezione creerai ed eseguirai il deployment dell'applicazione di produzione iniziale che utilizzerai in questo tutorial.

Esegui il deployment del servizio

  • In Cloud Shell, crea ed esegui il deployment dell'applicazione, incluso un servizio che richiede l'autenticazione. Per rendere un servizio pubblico, utilizza il flag --allow-unauthenticated.

        gcloud builds submit --tag gcr.io/$PROJECT_ID/hello-cloudrun
    
        gcloud run deploy hello-cloudrun \
          --image gcr.io/$PROJECT_ID/hello-cloudrun \
          --platform managed \
          --region us-central1 \
          --tag=prod -q
    

    L'output sarà simile al seguente:

    Deploying container to Cloud Run service [hello-cloudrun] in project [sdw-mvp6] region [us-central1]
    ✓ Deploying new service... Done.
      ✓ Creating Revision...
      ✓ Routing traffic...
    Done.
    Service [hello-cloudrun] revision [hello-cloudrun-00001-tar] has been deployed and is serving 100 percent of traffic.
    Service URL: https://hello-cloudrun-apwaaxltma-uc.a.run.app
    The revision can be reached directly at https://prod---hello-cloudrun-apwaaxltma-uc.a.run.app
    

L'output include l'URL del servizio e un URL univoco per la revisione. I valori saranno leggermente diversi da quanto indicato qui.

Convalida il deployment

  1. Una volta completato il deployment, visualizza il servizio di cui è stato appena eseguito il deployment nella pagina Revisioni nella console Cloud.

  2. In Cloud Shell, visualizza la risposta autenticata del servizio:

    PROD_URL=$(gcloud run services describe hello-cloudrun --platform managed --region us-central1 --format=json | jq --raw-output ".status.url")
    
    echo $PROD_URL
    
    curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" $PROD_URL
    

Abilitazione dei deployment di rami

In questa sezione abiliti un URL univoco per i rami di sviluppo in Git.

Configura trigger ramo

Ogni ramo è rappresentato da un URL identificato dal nome del ramo. I commit nel ramo attivano un deployment e gli aggiornamenti sono accessibili allo stesso URL.

  1. In Cloud Shell, configura il trigger:

    gcloud alpha builds triggers create github \
    --name=branchtrigger \
    --repository=$REPO_NAME \
    --branch-pattern='[^(?!.*main)].*' \
    --build-config=labs/cloudrun-progression/branch-cloudbuild.yaml \
    --region=us-central1
    
  2. Per esaminare il trigger, vai alla pagina Trigger di Cloud Build nella console Cloud.

Crea modifiche su un ramo

  1. In Cloud Shell, crea un nuovo ramo:

    git checkout -b new-feature-1
    
  2. Apri l'applicazione di esempio utilizzando il tuo editor preferito o l'IDE di Cloud Shell:

    edit app.py
    
  3. Nell'applicazione di esempio, modifica la riga 24 per indicare v1.1 anziché v1.0:

    @app.route('/')
    
    def hello_world():
        return 'Hello World v1.1'
    
    
  4. Per tornare al terminale, fai clic su Apri terminale.

Esegui il trigger di ramo

  1. In Cloud Shell, esegui il commit della modifica ed esegui il push al repository remoto:

    git add . && git commit -m "updated" && git push origin new-feature-1
    
  2. Per esaminare la build in corso, vai alla schermata della cronologia di Cloud Build.

  3. Per esaminare la nuova revisione, al termine della build vai alla pagina Revisioni di Cloud Run nella console Cloud:

  4. In Cloud Shell, recupera l'URL univoco per questo ramo:

    BRANCH_URL=$(gcloud run services describe hello-cloudrun --platform managed --region us-central1 --format=json | jq --raw-output ".status.traffic[] | select (.tag==\"new-feature-1\")|.url")
    
    echo $BRANCH_URL
    
  5. Accedi all'URL autenticato:

    curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" $BRANCH_URL
    

    L'output della risposta aggiornato ha il seguente aspetto:

    Hello World v1.1
    

Automatizza i test canary

Quando il codice viene rilasciato in produzione, di solito viene rilasciato su un piccolo sottoinsieme di traffico in tempo reale prima di eseguire la migrazione di tutto il traffico al nuovo codebase.

In questa sezione implementerai un trigger che viene attivato quando viene eseguito il commit del codice nel ramo principale. Il trigger esegue il deployment del codice su un URL canary univoco e instrada il 10% di tutto il traffico in tempo reale alla nuova revisione.

  1. In Cloud Shell, configura il trigger del ramo:

    gcloud alpha builds triggers create github \
      --name=maintrigger \
      --repository=$REPO_NAME \
      --branch-pattern=main \
      --build-config=labs/cloudrun-progression/main-cloudbuild.yaml \
      --region=us-central1
    
  2. Per esaminare il nuovo trigger, vai alla pagina Trigger di Cloud Build nella console Cloud.

  3. In Cloud Shell, unisci il ramo alla riga principale ed esegui il push al repository remoto:

    git checkout main
    git merge new-feature-1
    git push origin main
    
  4. Per esaminare la build in corso, vai alla pagina delle build di Cloud Build.

  5. Una volta completata la build, per esaminare la nuova revisione vai alla pagina Revisioni di Cloud Run nella console Cloud. Tieni presente che il 90% del traffico è instradato alla produzione, il 10% alla versione canary e lo 0% alle revisioni del ramo.

Esamina le righe chiave di main-cloudbuild.yaml che implementano la logica per il deployment canary.

Le righe 39-45 eseguono il deployment della nuova revisione e utilizzano il flag dei tag per instradare il traffico dall'URL canary univoco:

gcloud run deploy ${_SERVICE_NAME} \
--platform managed \
--region ${_REGION} \
--image gcr.io/${PROJECT_ID}/${_SERVICE_NAME} \
--tag=canary \
--no-traffic

La riga 61 aggiunge un tag statico alla revisione che annota la breve SHA Git del deployment:

gcloud beta run services update-traffic ${_SERVICE_NAME} --update-tags=sha-$SHORT_SHA=$${CANARY} --platform managed --region ${_REGION}

La riga 62 aggiorna il traffico per instradare il 90% alla produzione e il 10% alla versione canary:

gcloud run services update-traffic ${_SERVICE_NAME} --to-revisions=$${PROD}=90,$${CANARY}=10 --platform managed --region ${_REGION}
  1. In Cloud Shell, recupera l'URL univoco per la revisione canary:

    CANARY_URL=$(gcloud run services describe hello-cloudrun --platform managed --region us-central1 --format=json | jq --raw-output ".status.traffic[] | select (.tag==\"canary\")|.url")
    
    echo $CANARY_URL
    
  2. Esamina direttamente l'endpoint canary:

    curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" $CANARY_URL
    
  3. Per visualizzare le risposte basate sulla percentuale, esegui una serie di richieste:

    LIVE_URL=$(gcloud run services describe hello-cloudrun --platform managed --region us-central1 --format=json | jq --raw-output ".status.url")
    for i in {0..20};do
      curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" $LIVE_URL; echo \n
    done
    

Rilascio in produzione

Una volta convalidato il deployment canary con un piccolo sottoinsieme di traffico, rilasci il deployment per il resto del traffico in tempo reale.

In questa sezione configurerai un trigger che viene attivato quando crei un tag nel repository. Il trigger esegue la migrazione del 100% del traffico alla revisione di cui è già stato eseguito il deployment in base all'algoritmo SHA di commit del tag. L'uso dell'SHA commit assicura che la revisione convalidata con il traffico canary sia la revisione utilizzata per il resto del traffico di produzione.

  1. In Cloud Shell, configura l'attivatore del tag:

    gcloud alpha builds triggers create github \
      --name=tagtrigger \
      --repository=$REPO_NAME \
      --tag-pattern=. \
      --build-config=labs/cloudrun-progression/tag-cloudbuild.yaml \
      --region=us-central1
    
  2. Per esaminare il nuovo trigger, vai alla pagina Trigger di Cloud Build nella console Cloud.

  3. In Cloud Shell, crea un nuovo tag ed esegui il push al repository remoto:

    git tag 1.1
    git push origin 1.1
    
  4. Per esaminare la build in corso, vai alla schermata della cronologia di Cloud Build nella console Cloud.

  5. Una volta completata la build, per esaminare la nuova revisione vai alla pagina Revisioni di Cloud Run nella console Cloud. Tieni presente che la revisione viene aggiornata per indicare il tag di produzione e che gestisce il 100% del traffico in tempo reale.

  6. In Cloud Shell, per visualizzare le risposte basate sulla percentuale, esegui una serie di richieste:

    LIVE_URL=$(gCloud Run services describe hello-cloudrun --platform managed --region us-central1 --format=json | jq --raw-output ".status.url")
    
    for i in {0..20};do
      curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" $LIVE_URL; echo \n
    done
    
  7. Esamina le righe chiave di tag-cloudbuild.yaml che implementano la logica di deployment in produzione.

    La riga 37 aggiorna la revisione canary aggiungendo il tag di produzione. La revisione di cui è stato eseguito il deployment è ora codificata sia per la versione di produzione che per la versione canary:

    gcloud beta run services update-traffic ${_SERVICE_NAME} --update-tags=prod=$${CANARY} --platform managed --region ${_REGION}
    

    La riga 39 aggiorna il traffico dell'URL del servizio di base in modo da instradare il 100% del traffico alla revisione contrassegnata come prod:

    gcloud run services update-traffic ${_SERVICE_NAME} --to-revisions=$${NEW_PROD}=100 --platform managed --region ${_REGION}
    

Esegui la pulizia

Per evitare che al tuo Account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, elimina il progetto che contiene le risorse oppure mantieni il progetto ed elimina le singole risorse.

  1. Nella console Google Cloud, vai alla pagina Gestisci risorse.

    Vai a Gestisci risorse

  2. Nell'elenco dei progetti, seleziona il progetto che vuoi eliminare, quindi fai clic su Elimina.
  3. Nella finestra di dialogo, digita l'ID del progetto e fai clic su Chiudi per eliminare il progetto.

Passaggi successivi