1. Présentation
Cet atelier présente des fonctionnalités et des capacités conçues pour simplifier le workflow de développement des ingénieurs logiciels chargés de développer des applications NodeJS dans un environnement conteneurisé. Le développement de conteneurs typique exige de l'utilisateur qu'il comprenne les détails des conteneurs et du processus de création de conteneurs. De plus, les développeurs doivent généralement interrompre leur flux de travail et quitter leur IDE pour tester et déboguer leurs applications dans des environnements distants. Grâce aux outils et technologies mentionnés dans ce tutoriel, les développeurs peuvent travailler efficacement avec des applications conteneurisées sans quitter leur IDE.
Objectifs de l'atelier
Dans cet atelier, vous allez découvrir des méthodes de développement avec des conteneurs dans GCP, y compris :
- Créer une application Node.js de démarrage
- Configurer l'application Nodejs pour le développement de conteneurs
- Coder un service REST CRUD simple
- Déployer sur GKE
- Déboguer un état d'erreur
- Utiliser des points d'arrêt / journaux
- Déployer à chaud les modifications sur GKE
- Facultatif : Intégrer Cloud SQL pour la persistance du backend
2. Préparation
Configuration de l'environnement d'auto-formation
- Connectez-vous à la console Google Cloud, puis créez un projet ou réutilisez un projet existant. (Si vous ne possédez pas encore de compte Gmail ou Google Workspace, vous devez en créer un.)



- Le nom du projet est le nom à afficher pour les participants au projet. Il s'agit d'une chaîne de caractères qui n'est pas utilisée par les API Google, et que vous pouvez modifier à tout moment.
- L'ID du projet doit être unique sur l'ensemble des projets Google Cloud et doit être immuable (vous ne pouvez pas le modifier une fois que vous l'avez défini). Cloud Console génère automatiquement une chaîne unique dont la composition importe peu, en général. Dans la plupart des ateliers de programmation, vous devrez référencer l'ID du projet (généralement identifié comme
PROJECT_ID), donc s'il ne vous convient pas, générez-en un autre au hasard ou définissez le vôtre, puis vérifiez s'il est disponible. Il est ensuite "gelé" une fois le projet créé. - La troisième valeur est le numéro de projet, utilisé par certaines API. Pour en savoir plus sur ces trois valeurs, consultez la documentation.
- Vous devez ensuite activer la facturation dans Cloud Console afin d'utiliser les ressources/API Cloud. L'exécution de cet atelier de programmation est très peu coûteuse, voire sans frais. Pour arrêter les ressources afin d'éviter qu'elles ne vous soient facturées après ce tutoriel, suivez les instructions de nettoyage indiquées à la fin de l'atelier. Les nouveaux utilisateurs de Google Cloud peuvent participer au programme d'essai sans frais pour bénéficier d'un crédit de 300$.
Démarrer l'éditeur Cloudshell
Cet atelier a été conçu et testé pour être utilisé avec l'éditeur Cloud Shell. Pour accéder à l'éditeur :
- Accédez à votre projet Google à l'adresse https://console.cloud.google.com.
- En haut à droite, cliquez sur l'icône de l'éditeur Cloud Shell.

- Un nouveau volet s'ouvre en bas de la fenêtre.
- Cliquez sur le bouton "Ouvrir l'éditeur".

- L'éditeur s'ouvre avec un explorateur à droite et un éditeur dans la zone centrale.
- Un volet de terminal doit également être disponible en bas de l'écran.
- Si le terminal n'est PAS ouvert, utilisez la combinaison de touches "ctrl+`" pour ouvrir une nouvelle fenêtre de terminal.
Configurer gcloud
Dans Cloud Shell, définissez votre ID de projet et la région dans laquelle vous souhaitez déployer votre application. Enregistrez-les en tant que variables PROJECT_ID et REGION.
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
Configurer un cluster GKE et une base de données
- Téléchargez le script d'installation et rendez-le exécutable.
wget https://raw.githubusercontent.com/GoogleCloudPlatform/container-developer-workshop/main/labs/nodejs/setup.sh
chmod +x setup.sh
Provisionner l'infrastructure utilisée dans cet atelier
Dans cet atelier, vous allez déployer du code sur GKE et accéder aux données stockées dans une base de données Spanner. Le script de configuration ci-dessous prépare cette infrastructure pour vous.
- Ouvrez le fichier
setup.shet modifiez les valeurs des mots de passe actuellement définis sur "CHANGEME". - Exécutez le script de configuration pour créer un cluster GKE et une base de données Cloud SQL que vous utiliserez dans cet atelier.
./setup.sh
- Dans Cloud Shell, créez un répertoire nommé
mynodejsapp.
mkdir mynodejsapp
- Accédez à ce répertoire et ouvrez-le en tant qu'espace de travail. L'éditeur est alors rechargé en créant une configuration d'espace de travail dans le dossier nouvellement créé.
cd mynodejsapp && cloudshell workspace .
- Installez Node et NPM à l'aide de NVM.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
# This loads nvm bash_completion
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
nvm install stable
nvm alias default stable
3. Créer une application de démarrage
- Initialiser l'application
Créez un fichier package.json en exécutant la commande suivante :
npm init
Choose the entry point: (index.js) src/index.js and default values for the rest of the parameters. This will create the file with following contents
{
"name": "mynodejsapp",
"version": "1.0.0",
"description": "",
"main": "src/index.js",,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
- Ajouter un point d'entrée
Modifiez ce fichier pour inclure la commande de démarrage dans le script "start": "node src/index.js",. Une fois la modification effectuée, les scripts devraient ressembler à l'extrait de code ci-dessous :
"scripts": {
"start": "node src/index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
- Ajouter la dépendance Express
Le code que nous allons ajouter utilise également express. Ajoutons donc cette dépendance à ce fichier package.json. Une fois toutes les modifications effectuées, le fichier package.json devrait se présenter comme suit.
{
"name": "mynodejsapp",
"version": "1.0.0",
"description": "",
"main": "src/index.js",
"scripts": {
"start": "node src/index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Your Name",
"license": "ISC",
"dependencies": {
"express": "^4.16.4"
}
}
- Créer le fichier index.js
Créez un répertoire source appelé "src".
Créez src/index.js avec le code suivant
const express = require('express');
const app = express();
const PORT = 8080;
app.get('/', (req, res) => {
var message="Greetings from Node";
res.send({ message: message });
});
app.listen(PORT, () => {
console.log(`Server running at: http://localhost:${PORT}/`);
});
Notez que le PORT est défini sur la valeur 8080.
Générer des fichiers manifestes
Skaffold fournit des outils intégrés pour simplifier le développement de conteneurs. Dans cette étape, vous allez initialiser Skaffold, ce qui créera automatiquement des fichiers YAML Kubernetes de base. Exécutez la commande ci-dessous pour commencer le processus.
Exécutez la commande suivante dans le terminal.
skaffold init --generate-manifests
Lorsque vous y êtes invité :
- Saisissez 8080 pour le port.
- Saisissez y pour enregistrer la configuration.
Deux fichiers sont ajoutés à la visualisation de l'espace de travail : skaffold.yaml et deployment.yaml.
Modifier le nom de l'application
Les valeurs par défaut incluses dans la configuration ne correspondent pas au nom de votre application. Mettez à jour les fichiers pour qu'ils fassent référence au nom de votre application plutôt qu'aux valeurs par défaut.
- Modifier des entrées dans la configuration Skaffold
- Ouvrir
skaffold.yaml - Sélectionnez le nom de l'image actuellement défini sur
package-json-image. - Effectuez un clic droit et sélectionnez "Modifier toutes les occurrences".
- Saisissez le nouveau nom, par exemple
mynodejsapp.
- Modifier les entrées de la configuration Kubernetes
- Ouvrir le fichier
deployment.yaml - Sélectionnez le nom de l'image actuellement défini sur
package-json-image. - Effectuez un clic droit et sélectionnez "Modifier toutes les occurrences".
- Saisissez le nouveau nom, par exemple
mynodejsapp.
Notez que dans le fichier skaffold.yaml, la section build utilise buildpacks pour conteneuriser l'application. Ce code ne comporte pas de fichier Dockerfile et le développeur n'a pas besoin de connaître Docker pour conteneuriser cette application.
De plus, la synchronisation à chaud est automatiquement activée entre l'éditeur et le conteneur en cours d'exécution par cette configuration Skaffold. Aucune configuration supplémentaire n'est requise pour activer la synchronisation rapide.
4. Parcourir le processus de développement
Dans cette section, vous allez suivre quelques étapes à l'aide du plug-in Cloud Code pour découvrir les processus de base et valider la configuration de votre application de démarrage.
Cloud Code s'intègre à Skaffold pour simplifier votre processus de développement. Lorsque vous déployez sur GKE lors des étapes suivantes, Cloud Code et Skaffold créent automatiquement votre image de conteneur, la transfèrent vers Container Registry, puis déploient votre application sur GKE. Cela se produit en arrière-plan, en masquant les détails du flux de développement. Cloud Code améliore également votre processus de développement en fournissant des fonctionnalités de débogage et de synchronisation à chaud traditionnelles pour le développement basé sur des conteneurs.
Déployer sur Kubernetes
- Dans le volet situé au bas de l'éditeur Cloud Shell, sélectionnez Cloud Code .

- Dans le panneau qui s'affiche en haut, sélectionnez Exécuter sur Kubernetes. Si vous y êtes invité, sélectionnez "Oui" pour utiliser le contexte Kubernetes actuel.

- La première fois que vous exécutez la commande, une invite s'affiche en haut de l'écran pour vous demander si vous souhaitez utiliser le contexte Kubernetes actuel. Sélectionnez "Oui" pour accepter et utiliser le contexte actuel.

- Une invite s'affiche ensuite pour vous demander quel registre de conteneurs utiliser. Appuyez sur Entrée pour accepter la valeur par défaut fournie.

- Sélectionnez l'onglet "Sortie" dans le volet inférieur pour afficher la progression et les notifications.

- Sélectionnez "Kubernetes: Run/Debug - Detailed" (Kubernetes : Exécuter/Déboguer – Détails) dans le menu déroulant à droite pour afficher des informations supplémentaires et les journaux diffusés en direct depuis les conteneurs.

- Pour revenir à la vue simplifiée, sélectionnez "Kubernetes : Exécuter/Déboguer" dans le menu déroulant.
- Une fois la compilation et les tests terminés, l'onglet "Résultat" indique
Resource deployment/mynodejsapp status completed successfullyet une URL est listée : "URL transférée depuis l'application de démonstration du service : http://localhost:8080". - Dans le terminal Cloud Code, pointez sur l'URL dans la sortie (http://localhost:8080), puis dans l'info-bulle qui s'affiche, sélectionnez "Ouvrir l'aperçu sur le Web".
La réponse sera la suivante :
{"message":"Greetings from Node"}
Hot reload
- Accédez à
src/index.js. Modifiez le code du message d'accueil pour'Hello from Node'
Vous remarquerez immédiatement que, dans la fenêtre Output, vue Kubernetes: Run/Debug, le détecteur synchronise les fichiers mis à jour avec le conteneur dans Kubernetes.
Update initiated File sync started for 1 files for gcr.io/myproject/mynodejsapp:latest@sha256:f554756b3b4d6c301c4b26ef96102227cfa2833270db56241248ae42baa1971a File sync succeeded for 1 files for gcr.io/myproject/mynodejsapp:latest@sha256:f554756b3b4d6c301c4b26ef96102227cfa2833270db56241248ae42baa1971a Update succeeded
- Si vous passez à la vue
Kubernetes: Run/Debug - Detailed, vous remarquerez qu'elle reconnaît les modifications apportées aux fichiers et redémarre le nœud.
files modified: [src/index.js] Copying files:map[src/index.js:[/workspace/src/index.js]]togcr.io/myproject/mynodejsapp:latest@sha256:f554756b3b4d6c301c4b26ef96102227cfa2833270db56241248ae42baa1971a Syncing 1 files for gcr.io/myproject/mynodejsapp:latest@sha256:f554756b3b4d6c301c4b26ef96102227cfa2833270db56241248ae42baa1971a Watching for changes... [mynodejsapp] [mynodejsapp]> mynodejsapp@1.0.0 start /workspace [mynodejsapp]> node src/index.js [mynodejsapp] [mynodejsapp]Server running at: http://localhost:8080/
- Actualisez votre navigateur pour afficher les résultats mis à jour.
Débogage
- Accédez à la vue Déboguer et arrêtez le thread actuel
. - Cliquez sur
Cloud Codedans le menu du bas, puis sélectionnezDebug on Kubernetespour exécuter l'application en modedebug.
- Dans la vue
Kubernetes Run/Debug - Detailedde la fenêtreOutput, notez que Skaffold déploie cette application en mode débogage. - La création et le déploiement de l'application prennent quelques minutes. Cette fois, vous remarquerez qu'un débogueur est associé.
Port forwarding pod/mynodejsapp-6bbcf847cd-vqr6v in namespace default, remote port 9229 -> http://127.0.0.1:9229 [mynodejsapp]Debugger attached.
- La couleur de la barre d'état inférieure passe du bleu à l'orange, ce qui indique qu'elle est en mode Débogage.
- Dans la vue
Kubernetes Run/Debug, notez qu'un conteneur débogable est démarré.
**************URLs***************** Forwarded URL from service mynodejsapp-service: http://localhost:8080 Debuggable container started pod/mynodejsapp-deployment-6bc7598798-xl9kj:mynodejsapp (default) Update succeeded ***********************************
Utiliser les points d'arrêt
- Ouvrez
src/index.js. - Recherchez l'instruction
var message="Greetings from Node";. - Ajoutez un point d'arrêt à cette ligne en cliquant sur l'espace vide à gauche du numéro de ligne. Un indicateur rouge s'affiche pour indiquer que le point d'arrêt est défini.
- Rechargez votre navigateur et notez que le débogueur arrête le processus au point d'arrêt et vous permet d'examiner les variables et l'état de l'application qui s'exécute à distance dans GKE.
- Cliquez sur la section des variables jusqu'à trouver la variable
"message". - Exécutez la ligne en appuyant sur Passer
. - Observez la valeur actuelle de la variable
"message"qui passe à"Greetings from Node". - Double-cliquez sur le nom de la variable "target" (cible), puis, dans le pop-up, remplacez la valeur par une autre valeur, par exemple
"Hello from Node". - Cliquez sur le bouton "Continuer" dans le panneau de configuration du débogueur.
- Examinez la réponse dans votre navigateur. Elle affiche désormais la valeur modifiée que vous venez de saisir.
- Arrêtez le mode "Débogage" en appuyant sur le bouton d'arrêt
, puis supprimez le point d'arrêt en cliquant à nouveau dessus.
5. Développer un service REST CRUD simple
À ce stade, votre application est entièrement configurée pour le développement conteneurisé et vous avez parcouru le workflow de développement de base avec Cloud Code. Dans les sections suivantes, vous allez mettre en pratique ce que vous avez appris en ajoutant des points de terminaison de service REST qui se connectent à une base de données gérée dans Google Cloud.
Configurer les dépendances
Le code de l'application utilise une base de données pour conserver les données du service REST. Assurez-vous que les dépendances sont disponibles en ajoutant les éléments suivants dans le fichier package.json.
- Ajoutez deux autres dépendances,
pgetsequelize, au fichierpackage.jsonpour créer une application CRUD Postgres. Une fois les modifications effectuées, la section des dépendances se présentera comme suit.
"dependencies": {
"express": "^4.16.4",
"pg": "^8.7.3",
"sequelize": "^6.17.0"
}
Coder le service REST
- Ajoutez le code de l'application CRUD à cette application.
wget -O app.zip https://github.com/GoogleCloudPlatform/container-developer-workshop/raw/main/labs/nodejs/app.zip
unzip app.zip
Ce code a
- Dossier models avec le modèle d'entité pour
item - Dossier controllers contenant le code qui effectue les opérations CRUD
- Dossier routes qui achemine des formats d'URL spécifiques vers différents appels
- Dossier config contenant les informations de connectivité de la base de données
- Notez que la configuration de la base de données dans le fichier
db.config.jsfait référence aux variables d'environnement qui doivent être fournies pour se connecter à la base de données. Vous devez également analyser la requête entrante pour l'encodage d'URL. - Ajoutez l'extrait de code suivant dans
src/index.jspour pouvoir vous connecter au code CRUD à partir de votre fichier JavaScript principal, juste avant la dernière section qui commence parapp.listen(PORT, () => {.
const bodyParser = require('body-parser')
app.use(bodyParser.json())
app.use(
bodyParser.urlencoded({
extended: true,
})
)
const db = require("../app/models");
db.sequelize.sync();
require("../app/routes/item.routes")(app);
- Modifiez le déploiement dans le fichier
deployment.yamlpour ajouter les variables d'environnement permettant de fournir les informations de connectivité à la base de données.
Mettez à jour l'entrée de spécification à la fin du fichier pour qu'elle corresponde à la définition suivante :
spec:
containers:
- name: mynodejsapp
image: mynodejsapp
env:
- name: DB_HOST
value: ${DB_INSTANCE_IP}
- name: DB_PORT
value: "5432"
- name: DB_USER
valueFrom:
secretKeyRef:
name: gke-cloud-sql-secrets
key: username
- name: DB_PASS
valueFrom:
secretKeyRef:
name: gke-cloud-sql-secrets
key: password
- name: DB_NAME
valueFrom:
secretKeyRef:
name: gke-cloud-sql-secrets
key: database
- Remplacez la valeur DB_HOST par l'adresse de votre base de données.
export DB_INSTANCE_IP=$(gcloud sql instances describe mytest-instance \
--format=json | jq \
--raw-output ".ipAddresses[].ipAddress")
envsubst < deployment.yaml > deployment.new && mv deployment.new deployment.yaml
Déployer et valider l'application
- Dans le volet situé au bas de l'éditeur Cloud Shell, sélectionnez
Cloud Code, puisDebug on Kubernetesen haut de l'écran. - Une fois la compilation et les tests terminés, l'onglet "Résultat" indique
Resource deployment/mynodejsapp status completed successfullyet affiche l'URL "URL transférée depuis le service mynodejsapp : http://localhost:8080". - Ajoutez quelques éléments.
Dans le terminal Cloud Shell, exécutez les commandes ci-dessous.
URL=localhost:8080
curl -X POST $URL/items -d '{"itemName":"Body Spray", "itemPrice":3.2}' -H "Content-Type: application/json"
curl -X POST $URL/items -d '{"itemName":"Nail Cutter", "itemPrice":2.5}' -H "Content-Type: application/json"
- Testez la méthode GET en exécutant $URL/items dans le navigateur. Vous pouvez également exécuter curl à partir de la ligne de commande.
curl -X GET $URL/items
- Test de suppression : essayez maintenant de supprimer un élément en exécutant la commande suivante. Modifiez la valeur de item-id si nécessaire.
curl -X DELETE $URL/items/1
This throws an error message
{"message":"Could not delete Item with id=[object Object]"}
Identifier et résoudre le problème
- Redémarrez l'application en mode débogage et identifiez le problème. Voici quelques conseils :
- Nous savons que quelque chose ne va pas avec la méthode DELETE, car elle ne renvoie pas le résultat souhaité. Vous devez donc définir le point d'arrêt dans la méthode
itemcontroller.js->exports.delete. - Exécutez l'exécution pas à pas et observez les variables à chaque étape pour voir les valeurs des variables locales dans la fenêtre de gauche.
- Pour observer des valeurs spécifiques telles que
request.params, ajoutez cette variable à la fenêtre "Watch".
- Notez que la valeur attribuée à
idestundefined. Modifiez le code pour résoudre le problème.
L'extrait de code corrigé se présente comme suit.
// Delete a Item with the specified id in the request
exports.delete = (req, res) => {
const id = req.params.id;
- Une fois l'application redémarrée, réessayez de supprimer le fichier.
- Arrêtez la session de débogage en cliquant sur le carré rouge dans la barre d'outils de débogage
.
6. Nettoyage
Félicitations ! Dans cet atelier, vous avez créé une application Node.js à partir de zéro et l'avez configurée pour qu'elle fonctionne en mode de déploiement à chaud avec des conteneurs. Vous avez ensuite déployé et débogué votre application sur un cluster GKE distant en suivant le même flux de développement que celui utilisé dans les piles d'applications traditionnelles.
Pour effectuer le nettoyage une fois l'atelier terminé :
- Supprimer les fichiers utilisés dans l'atelier
cd ~ && rm -rf mynodejsapp && rm -f setup.sh
- Supprimer le projet pour supprimer toute l'infrastructure et les ressources associées