Déployer et exécuter un conteneur avec Cloud Run sur Node.js

Cloud Run est une plate-forme de calcul gérée qui permet d'exécuter des conteneurs sans état accessibles via des requêtes HTTP. Cloud Run est sans serveur. Il élimine toute gestion de l'infrastructure pour vous permettre de vous concentrer sur ce qui compte le plus : créer des applications de qualité. Il est basé sur Knative, ce qui vous permet d'exécuter vos conteneurs avec Cloud Run (entièrement géré) ou Cloud Run pour Anthos. L'objectif de cet atelier de programmation est de créer une image de conteneur et de la déployer dans Cloud Run.

Prérequis

N/A

Configuration de l'environnement au rythme de chacun

Si vous ne possédez pas encore de compte Google (Gmail ou Google Apps), vous devez en créer un. Connectez-vous à la console Google Cloud Platform (console.cloud.google.com) et créez un projet :

Screenshot from 2016-02-10 12:45:26.png

Mémorisez l'ID du projet. Il s'agit d'un nom unique permettant de différencier chaque projet Google Cloud (le nom ci-dessus est déjà pris ; vous devez en trouver un autre). Il sera désigné par le nom PROJECT_ID tout au long de cet atelier de programmation.

Vous devez ensuite activer la facturation dans la console Cloud pour pouvoir utiliser les ressources Google Cloud.

Suivre cet atelier de programmation ne devrait pas vous coûter plus d'un euro. Cependant, cela peut s'avérer plus coûteux si vous décidez d'utiliser davantage de ressources ou si vous n'interrompez pas les ressources (voir la section "Effectuer un nettoyage" à la fin du présent document).

Les nouveaux utilisateurs de Google Cloud Platform peuvent bénéficier d'un essai sans frais avec 300$de crédits.

Cloud Shell

Bien que Google Cloud puisse être utilisé à distance depuis votre ordinateur portable, vous allez utiliser Cloud Shell, un environnement de ligne de commande exécuté dans Google Cloud.

Cette machine virtuelle basée sur Debian contient tous les outils de développement dont vous aurez besoin. Elle intègre un répertoire d'accueil persistant de 5 Go et s'exécute sur Google Cloud, ce qui améliore nettement les performances du réseau et l'authentification. Cela signifie que tout ce dont vous avez besoin pour cet atelier de programmation est un navigateur (oui, tout fonctionne sur un Chromebook).

Pour activer Google Cloud Shell, cliquez simplement sur le bouton en haut à droite de la console de développement (le provisionnement de l'environnement et la connexion ne devraient prendre que quelques minutes) :

activateCloudShell.png

Cliquez sur le bouton "Démarrer Cloud Shell" :

Capture d'écran du 2017-06-14 à 10.13.43 PM.png

Une fois connecté à Cloud Shell, vous êtes normalement déjà authentifié et le projet PROJECT_ID est sélectionné :

gcloud auth list

Résultat de la commande

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

Résultat de la commande

[core]
project = <PROJECT_ID>

Par défaut, Cloud Shell définit certaines variables d'environnement qui pourront s'avérer utiles pour exécuter certaines commandes dans le futur.

echo $GOOGLE_CLOUD_PROJECT

Résultat de la commande

<PROJECT_ID>

Si, pour une raison quelconque, le projet n'est pas défini, exécutez simplement la commande suivante :

gcloud config set project <PROJECT_ID>

Vous recherchez votre PROJECT_ID ? Vérifiez l'ID que vous avez utilisé pendant les étapes de configuration ou recherchez-le dans le tableau de bord de la console :

Project_ID.png

IMPORTANT : Pour finir, définissez la configuration du projet et de la zone par défaut :

gcloud config set compute/zone us-central1-f

Vous pouvez choisir parmi différentes zones. Pour en savoir plus, consultez la documentation sur les régions et les zones.

Activez l'API Cloud Run

Dans Cloud Shell, activez l'API Cloud Run.

gcloud services enable run.googleapis.com

Un message semblable à celui qui suit s'affiche pour vous indiquer que l'opération s'est correctement déroulée :

Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.

Vous allez créer une application Node.js simple basée sur Express et répondant aux requêtes HTTP.

Pour compiler votre application, utilisez Cloud Shell pour créer un répertoire nommé helloworld-nodejs et accédez-y.

mkdir helloworld-nodejs
cd helloworld-nodejs

Créez un fichier package.json avec le contenu suivant :

{
  "name": "cloudrun-helloworld",
  "version": "1.0.0",
  "description": "Simple hello world sample in Node",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "author": "",
  "license": "Apache-2.0",
  "dependencies": {
    "express": "^4.17.1"
  }
}

Le fichier ci-dessus contient principalement une commande de script de démarrage et une dépendance associée au framework d'application Web Express.

Dans le même répertoire, créez ensuite un fichier index.js et copiez-y le contenu suivant :

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  console.log('Hello world received a request.');

  const target = process.env.TARGET || 'World';
  res.send(`Hello ${target}!`);
});

const port = process.env.PORT || 8080;
app.listen(port, () => {
  console.log('Hello world listening on port', port);
});

Ce code crée un serveur Web de base qui écoute le port défini par la variable d'environnement PORT. Votre application est maintenant prête à être conteneurisée, testée et importée dans Container Registry.

Pour conteneuriser l'exemple d'application, créez un fichier nommé Dockerfile dans le même répertoire que les fichiers sources, puis copiez le contenu suivant :

# Use the official lightweight Node.js 12 image.
# https://hub.docker.com/_/node
FROM node:12-slim

# Create and change to the app directory.
WORKDIR /usr/src/app

# Copy application dependency manifests to the container image.
# A wildcard is used to ensure both package.json AND package-lock.json are copied.
# Copying this separately prevents re-running npm install on every code change.
COPY package*.json ./

# Install production dependencies.
RUN npm install --only=production

# Copy local code to the container image.
COPY . ./

# Run the web service on container startup.
CMD [ "npm", "start" ]

Créez ensuite votre image de conteneur à l'aide de Cloud Build. Pour cela, exécutez la commande suivante à partir du répertoire contenant le fichier Dockerfile :

gcloud builds submit --tag gcr.io/$GOOGLE_CLOUD_PROJECT/helloworld

$GOOGLE_CLOUD_PROJECT est une variable d'environnement contenant l'ID de votre projet Google Cloud lorsque vous exécutez Cloud Shell. Vous pouvez également l'obtenir en exécutant gcloud config get-value project.

Une fois l'image transférée vers le registre, un message SUCCESS contenant le nom de l'image (gcr.io/$GOOGLE_CLOUD_PROJECT/helloworld) s'affiche. L'image est stockée dans Container Registry et peut être réutilisée si vous le souhaitez.

Exécutez la commande suivante pour lister toutes les images de conteneur associées à votre projet actuel :

gcloud container images list

Si vous souhaitez exécuter et tester l'application en local depuis Cloud Shell, vous pouvez la démarrer à l'aide de cette commande docker standard :

docker run -d -p 8080:8080 gcr.io/$GOOGLE_CLOUD_PROJECT/helloworld

Dans Cloud Shell, cliquez sur Aperçu sur le Web et sélectionnez Prévisualiser sur le port 8080.

Une fenêtre de navigateur s'ouvre et affiche le message Hello World!

Vous pouvez également utiliser simplement curl localhost:8080.

Pour déployer votre application conteneurisée sur Cloud Run, exécutez la commande suivante (assurez-vous de l'adapter au nom d'image approprié pour l'application que vous avez créée ou utilisez l'image prédéfinie gcr.io/cloudrun/hello) :

gcloud run deploy helloworld \
  --image gcr.io/$GOOGLE_CLOUD_PROJECT/helloworld \
  --platform managed \
  --region us-central1 \
  --allow-unauthenticated

L'option de déploiement --allow-unauthenticated vous permet d'accéder à l'application sans authentification. L'option de déploiement --platform managed \ signifie que vous demandez l'environnement entièrement géré (et non l'infrastructure Kubernetes via Anthos).

Patientez quelques instants jusqu'à la fin du déploiement. Une fois le déploiement effectué, la ligne de commande affiche l'URL du service.

Service [helloworld] revision [helloworld-00001] has been deployed
and is serving traffic at https://helloworld-wdl7fdwaaa-uc.a.run.app

Vous pouvez maintenant accéder au conteneur déployé en ouvrant l'URL du service dans un navigateur Web :

Cloud Run effectue un scaling automatique et horizontal de votre image de conteneur pour traiter les requêtes reçues, puis un scaling à la baisse lorsque la demande diminue. Vous ne payez que pour le processeur, la mémoire et le réseau utilisés lors du traitement des requêtes.

Bien que Cloud Run ne facture pas lorsque le service n'est pas utilisé, il se peut que des frais vous soient facturés pour le stockage de l'image de conteneur générée.

Afin d'éviter que des frais ne vous soient facturés, vous pouvez soit supprimer votre projet Google Cloud, ce qui arrêtera la facturation de toutes les ressources qui y ont été utilisées, soit supprimer votre image helloworld en exécutant la commande suivante :

gcloud container images delete gcr.io/$GOOGLE_CLOUD_PROJECT/helloworld

Pour supprimer le service Cloud Run, utilisez cette commande :

gcloud run services delete helloworld \
  --platform managed \
  --region us-central1

Félicitations ! Vous avez déployé une application empaquetée dans une image de conteneur sur Cloud Run.

En savoir plus

Une bonne prochaine étape serait de consulter Démarrage rapide : Déployer sur Cloud Run pour Anthos sur Google Cloud.

Pour savoir comment créer un conteneur HTTP sans état pour Cloud Run à partir du code source et le transférer dans Container Registry, consultez les ressources suivantes :

Pour en savoir plus sur Knative, le projet Open Source sous-jacent, consultez Knative.