Déploiement continu sur Google Kubernetes Engine (GKE) avec Cloud Build

1. Présentation

Dans cet atelier, vous allez apprendre à configurer un pipeline de livraison continue pour GKE à l'aide de Cloud Build. Cet atelier explique comment déclencher des jobs Cloud Build pour différents événements Git et décrit un modèle simple pour des versions Canary automatisées dans GKE.

Procédez comme suit:

  • Créer l'application GKE
  • Automatiser les déploiements des branches Git
  • Automatiser les déploiements pour la branche principale git
  • Automatiser les déploiements pour les tags Git

2. Avant de commencer

Pour ce guide de référence, vous avez besoin d'un projet Google Cloud. Vous pouvez en créer un ou sélectionner un projet que vous avez déjà créé:

  1. Sélectionnez ou créez un projet Google Cloud.

ACCÉDER À LA PAGE DE SÉLECTION DE PROJET

  1. Activez la facturation pour votre projet.

ACTIVER LA FACTURATION

3. Préparer l'environnement

  1. Créez les variables d'environnement à utiliser tout au long de ce tutoriel:
    export PROJECT_ID=$(gcloud config get-value project)
    export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
    
    export ZONE=us-central1-b
    export CLUSTER=gke-progression-cluster
    export APP_NAME=myapp
    
  2. Activez les API suivantes:
    • Resource Manager
    • GKE
    • Cloud Source Repositories
    • Cloud Build
    • Container Registry
    gcloud services enable \
        cloudresourcemanager.googleapis.com \
        container.googleapis.com \
        sourcerepo.googleapis.com \
        cloudbuild.googleapis.com \
        containerregistry.googleapis.com \
        --async
    
  3. Clonez l'exemple de source et accédez au répertoire de l'atelier:
    git clone https://github.com/GoogleCloudPlatform/software-delivery-workshop.git gke-progression
    
    cd gke-progression/labs/gke-progression
    rm -rf ../../.git
    
  4. Remplacez les valeurs d'espace réservé dans l'exemple de dépôt par votre PROJECT_ID. Au cours de cette étape, vous allez créer des instances des différents fichiers de configuration propres à votre environnement actuel. Pour consulter un exemple de modèles en cours de mise à jour, exécutez la commande suivante.
    cat k8s/deployments/dev/frontend-dev.yaml.tmpl
    
    Effectuez la substitution de variable à l'aide de la commande suivante.
    for template in $(find . -name '*.tmpl'); do envsubst '${PROJECT_ID} ${ZONE} ${CLUSTER} ${APP_NAME}' < ${template} > ${template%.*}; done
    
    Pour consulter un exemple du fichier après la substitution, exécutez la commande suivante.
    cat k8s/deployments/dev/frontend-dev.yaml
    
  5. Si vous n'avez jamais utilisé Git dans Cloud Shell auparavant, définissez les valeurs user.name et user.email que vous souhaitez utiliser:
    git config --global user.email "YOUR_EMAIL_ADDRESS"
    git config --global user.name "YOUR_USERNAME"
    
  6. Stockez le code de l'exemple de dépôt dans Cloud Source Repositories:
    gcloud source repos create gke-progression
    git init
    git config credential.helper gcloud.sh
    git remote add gcp https://source.developers.google.com/p/$PROJECT_ID/r/gke-progression
    git branch -m main
    git add . && git commit -m "initial commit"
    git push gcp main
    
  7. Créez votre cluster GKE.
    gcloud container clusters create ${CLUSTER} \
        --project=${PROJECT_ID} \
        --zone=${ZONE}
    
  8. Accordez à Cloud Build les droits sur votre cluster.Cloud Build va déployer l'application sur votre cluster GKE et aura besoin des droits pour le faire.
    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member=serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
        --role=roles/container.developer
    

Votre environnement est prêt !

4. Créer votre application GKE

Dans cette section, vous allez créer et déployer l'application de production initiale que vous utiliserez tout au long de ce tutoriel.

  1. Créez l'application avec Cloud Build:
    gcloud builds submit --tag gcr.io/$PROJECT_ID/$APP_NAME:1.0.0 src/
    
  2. Déploiement manuel dans des environnements Canary et de production:créez les déploiements et services de production et Canary à l'aide des commandes kubectl apply.
    kubectl create ns production
    kubectl apply -f k8s/deployments/prod -n production
    kubectl apply -f k8s/deployments/canary -n production
    kubectl apply -f k8s/services -n production
    
    Le service déployé ici achemine le trafic à la fois vers les déploiements Canary et de production.
  3. Vérifiez le nombre de pods en cours d'exécution. Vérifiez que quatre pods sont en cours d'exécution pour l'interface, dont trois pour le trafic de production et un pour les versions Canary. Cela signifie que les modifications apportées à votre version Canary ne toucheront qu'un utilisateur sur quatre, soit 25 %.
    kubectl get pods -n production -l app=$APP_NAME -l role=frontend
    
  4. Récupérez l'adresse IP externe des services de production.
    kubectl get service $APP_NAME -n production
    
    Une fois que l'équilibreur de charge a renvoyé l'adresse IP, passez à l'étape suivante.
  5. Stockez l'adresse IP externe pour une utilisation ultérieure.
    export PRODUCTION_IP=$(kubectl get -o jsonpath="{.status.loadBalancer.ingress[0].ip}"  --namespace=production services $APP_NAME)
    
  6. Examinez l'application. Vérifiez la version du service. Le message "Hello World v1.0" doit s'afficher.
    curl http://$PRODUCTION_IP
    

Félicitations ! Vous avez déployé l'application exemple. Vous allez maintenant configurer des déclencheurs pour déployer vos modifications en continu.

5. Automatiser les déploiements pour les branches Git

Dans cette section, vous allez configurer un déclencheur qui exécutera un job Cloudbuild lors du commit d'une branche autre que main. Le fichier Cloud Build utilisé ici crée automatiquement un espace de noms et un déploiement pour toutes les branches existantes ou nouvelles, ce qui permet aux développeurs de prévisualiser leur code avant l'intégration à la branche principale.

  1. Configurez le déclencheur:le composant clé de ce déclencheur consiste à utiliser le paramètre branchName pour faire correspondre main et le paramètre invertRegex, qui est défini sur "true" et modifie le modèle branchName pour qu'il corresponde à tout ce qui n'est pas main. Pour référence, vous trouverez les lignes suivantes dans build/branch-trigger.json.
      "branchName": "main",
      "invertRegex": true
    
    De plus, les dernières lignes du fichier Cloud Build utilisé avec ce déclencheur créent un espace de noms nommé d'après la branche ayant déclenché la tâche, puis déploie l'application et le service dans le nouvel espace de noms. Pour référence, vous pouvez trouver les lignes suivantes dans build/branch-cloudbuild.yaml
      kubectl get ns ${BRANCH_NAME} || kubectl create ns ${BRANCH_NAME}
      kubectl apply --namespace ${BRANCH_NAME} --recursive -f k8s/deployments/dev
      kubectl apply --namespace ${BRANCH_NAME} --recursive -f k8s/services
    
    Maintenant que vous connaissez les mécanismes en cours d'utilisation, créez le déclencheur à l'aide de la commande gcloud ci-dessous.
    gcloud beta builds triggers create cloud-source-repositories \
      --trigger-config build/branch-trigger.json
    
  2. Pour examiner le déclencheur, accédez à la page Déclencheurs Cloud Build dans la console.Accéder à la page Déclencheurs
  3. Créez une branche:
    git checkout -b new-feature-1
    
  4. Modifiez le code pour indiquer v1.1Modifier src/app.py et remplacez la réponse 1.0 par 1.1.
    @app.route('/')
    def hello_world():
        return 'Hello World v1.1'
    
  5. Validez la modification et déployez-la dans le dépôt distant:
    git add . && git commit -m "updated" && git push gcp new-feature-1
    
  6. Pour examiner la compilation en cours, accédez à la page Historique Cloud Build dans la console.Accéder aux compilationsUne fois la compilation terminée, passez à l'étape suivante.
  7. Récupérez l'adresse IP externe du service de branche que vous venez de déployer.
    kubectl get service $APP_NAME -n new-feature-1
    
    Une fois que l'équilibreur de charge a renvoyé l'adresse IP, passez à l'étape suivante.
  8. Stockez l'adresse IP externe pour une utilisation ultérieure.
    export BRANCH_IP=$(kubectl get -o jsonpath="{.status.loadBalancer.ingress[0].ip}"  --namespace=new-feature-1 services $APP_NAME)
    
  9. Examinez l'application. Vérifiez la version en sortie du service. Le message "Hello World v1.0" doit s'afficher.
    curl http://$BRANCH_IP
    

6. Automatiser les déploiements pour la branche principale git

Avant de déployer le code en production, il est courant de le publier sur un petit sous-ensemble du trafic réel avant de migrer l'ensemble du trafic vers le nouveau code base.

Dans cette section, vous mettez en œuvre un déclencheur qui est activé lorsque le code est validé dans la branche principale. Le déclencheur déploie le déploiement Canary, qui reçoit 25% de l'ensemble du trafic en temps réel vers la nouvelle révision.

  1. Configurez le déclencheur pour la branche principale:
    gcloud beta builds triggers create cloud-source-repositories \
      --trigger-config build/main-trigger.json
    
  2. Pour examiner le nouveau déclencheur, accédez à la page Déclencheurs Cloud Build de la console.Accéder à la page Déclencheurs
  3. Fusionnez la branche avec la ligne principale et déployez-la dans le dépôt distant:
    git checkout main
    git merge new-feature-1
    git push gcp main
    
  4. Pour examiner la compilation en cours, accédez à la page Historique Cloud Build dans la console.Accéder aux compilationsUne fois la compilation terminée, passez à l'étape suivante.
  5. Examinez plusieurs réponses du serveur. Exécutez la commande suivante et notez qu'environ 25% des réponses indiquent la nouvelle réponse de Hello World v1.1.
    while true; do curl -w "\n" http://$PRODUCTION_IP; sleep 1;  done
    
    Lorsque vous êtes prêt à continuer, appuyez sur Ctrl+c pour quitter la boucle.

7. Automatiser les déploiements pour les balises Git

Une fois le déploiement Canary validé avec un petit sous-ensemble de trafic, vous déployez le déploiement sur le reste du trafic actif.

Dans cette section, vous allez configurer un déclencheur qui est activé lorsque vous créez un tag dans le dépôt. Le déclencheur ajoute le tag approprié à l'image, puis déploie les mises à jour en production en s'assurant que 100% du trafic accède à l'image taguée.

  1. Configurez le déclencheur de balise:
    gcloud beta builds triggers create cloud-source-repositories \
      --trigger-config build/tag-trigger.json
    
  2. Pour examiner le nouveau déclencheur, accédez à la page Déclencheurs Cloud Build de la console.Accéder à la page Déclencheurs
  3. Créez un tag et transférez-le vers le dépôt distant:
    git tag 1.1
    git push gcp 1.1
    
  4. Pour examiner la compilation en cours, accédez à la page Historique Cloud Build dans la console.Accéder aux compilations
  5. Examinez plusieurs réponses du serveur. Exécutez la commande suivante et notez que 100% des réponses affichent la nouvelle réponse de Hello World v1.1. Cela peut prendre un moment, car les nouveaux pods sont déployés et vérifiés dans GKE.
    while true; do curl -w "\n" http://$PRODUCTION_IP; sleep 1;  done
    
    Lorsque vous serez prêt à continuer, appuyez sur Ctrl+c pour quitter la boucle.Félicitations ! Vous avez créé des déclencheurs CI/CD dans Cloud Build pour les branches et les tags afin de déployer vos applications sur GKE.

8. Nettoyage

Supprimer le projet

  1. Dans la console Cloud, accédez à la page Gérer les ressources.
  2. Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur Supprimer.
  3. Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur Arrêter pour supprimer le projet.