Ce didacticiel explique comment configurer un pipeline CI / CD à l’aide de la plate-forme GCP (Cloud Platform) de Google et de Weave Cloud. Le pipeline comprend des étapes de construction, de test, de packaging et de déploiement automatisés, du code à la validation jusqu'au déploiement dans le cluster Kubernetes.

Quand il sera opérationnel, vous pourrez attribuer un nouveau code source à votre application et le déployer immédiatement dans le cluster - le moyen le plus rapide de passer du code au déploiement en production!

Pour les différentes étapes du pipeline, nous utiliserons:  

  • Référentiel de code: référentiels sources Google Cloud Platform (GSR)
  • Intégration continue: Google Cloud Builder (GCB)
  • Registre de conteneurs: Google Container Registry (GCR)
  • Déploiement continu: Weave Cloud Deploy
  • Orchestrateur: Google Kubernetes Engine (GKE)

Voici une visualisation du pipeline de déploiement:

Tout le code de l'application et la configuration seront stockés dans un repository git. Un commit fusionné dans master déclenchera le pipeline, ce qui entraînera la création et le déploiement d'une nouvelle image de conteneur. Nous appelons cette méthode de travail «GitOps» car elle rend le fonctionnement de Kubernetes simple, reproductible et réversible.  

Vous aurez besoin d’un compte Google Cloud Platform auquel vous pourrez vous inscrire et d'un MacBook avec la CLI de Gcloud installée. Allez dans la console GCP et créez un nouveau projet. Pour ce tutoriel, nous utiliserons «GCP Weave CICD» avec l’ID de projet «gcp-weave-cicd».  

Créer un repository de code

Le début du pipeline est un repository de code pour notre code d'application. Nous allons stocker notre code source en utilisant GCSR.  Créez un nouveau dépôt en sélectionnant «Repository sources», puis «Repository» dans le menu de gauche. Cliquez sur le lien en haut de la page intitulé «Créer un repository» et créez un repository appelé go-hello-world. La page suivante vous propose trois options:

Sélectionnez l'option du milieu: «Clonez votre référentiel Cloud dans un référentiel Git local», puis procédez comme suit (et comme indiqué dans l'écran ci-dessus en fonction de votre projet :

1. Installer le SDK Google Cloud

Suivez les instructions de votre plate-forme sur votre système d’exploitation pour installer Google Cloud SDK.  

2. Ouvrir un terminal et s'authentifier avec GCP Définissez le projet en tant que gcp-weave-cicd ou quel que soit le nom que vous lui avez donné.  

gcloud init 

3. Clonez votre repo Cloud vide dans un repo Git local.  

gcloud source repos clone go-hello-world --project=gcp-weave-cicd

4. Basculez dans votre nouveau repo Git local

 cd go-hello-world 

Vous avez maintenant créé un référentiel git local lié à votre repository source Google Cloud.  

Construire Hello World avec GCB

La prochaine étape consiste à ajouter du code. Pour ce tutoriel, nous allons créer un simple serveur HTTP «Hello World» pour construire le pipeline. Nous allons créer un fichier Docker et donner des instructions à Google Cloud Builder (GCB) pour générer le code dans une image Docker.

Les étapes sont:  

1. Créez un répertoire "src"  

mkdir src 

2. Créez un fichier “src / hello-world.go” avec le contenu suivant

package main

import (
    "fmt"
    "log"
    "net/http"
    "os"
)

func main() {
    port := "8080"
    if fromEnv := os.Getenv("port"); fromEnv != "" {
        port = fromEnv
    }

    server := http.NewServeMux()
    server.HandleFunc("/", hello)
    log.Fatal(http.ListenAndServe("0.0.0.0:"+port, server))
    log.Printf("Listening on 0.0.0.0:%s", port)
}

func hello(w http.ResponseWriter, r *http.Request) {
    log.Printf("Serving request: %s", r.URL.Path)
    host, _ := os.Hostname()
    fmt.Fprintf(w, "Hello world!\n")
    fmt.Fprintf(w, "Hostname: %s\n", host)
}

3. Créez un fichier Docker à la racine du repository

FROM alpine:3.5

COPY ./hello-world /hello-world
WORKDIR /

EXPOSE 8080

CMD [ "/hello-world", "-port", "8080"]

4. Demander à GCB de créer le fichier Dockerfile

La norme est d'appeler le fichier GCB "cloudbuild.yaml":

steps:
  - name: 'gcr.io/cloud-builders/go'
    args: ['build', '-o', 'hello-world', 'src/hello-world.go']
  - name: 'gcr.io/cloud-builders/docker'
    args: ['build', 
         '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:$BRANCH_NAME-$SHORT_SHA',
         '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:latest',
         '-f', 'Dockerfile', '.']
images:
  - 'gcr.io/$PROJECT_ID/$REPO_NAME:$BRANCH_NAME-$SHORT_SHA'
  - 'gcr.io/$PROJECT_ID/$REPO_NAME:latest'

Comme vous pouvez le voir, il y a deux étapes de construction; la première compile le fichier source Go, la seconde construit le fichier Docker.  Une fonctionnalité intéressante de GCB est la possibilité d'utiliser des variables d'environnement dans le fichier de demande de construction. Quel que soit le nom que vous avez choisi pour votre projet et votre nom de dépôt, le fichier ci-dessus fonctionnera. Dans notre exemple, le projet s'appelait «GCP Weave CICD». Par conséquent, la construction entraînera la création d'une image de conteneur dans Google Container Registry, avec un chemin ressemblant à ceci: «gcr.io/gcp-weave-cicd/go -hello-world: master-9709e0e ”.  

5. Commit et push

Validez vos modifications locales et appuyez sur le dépôt GCSR distant:  

git stage --all 
git commit --message "initial commit"
git push --set-upstream origin master

Vous allez vous retrouver avec un repository contenant les éléments suivants:

Créer un Build Trigger

Pour déclencher automatiquement la construction de la source à chaque nouveau commit, nous utilisons un Build Trigger.  

  • Dans Google Cloud, sélectionnez Container Registry → Build Triggers dans le menu principal.
  • Cliquez sur Créer un Trigger dans la zone de contenu principale.
  • Sélectionnez le repository comme source
  • Sélectionnez go-hello-world (le dépôt git avec le code)
  • Dans les paramètres du Trigger, accédez à la section Build Configuration et sélectionnez cloudbuild.yaml. Notez que vous devrez peut-être spécifier l'emplacement précis du fichier /cloudbuild.yaml.
  • Créer un Trigger pour finaliser l'assistant

Vérifiez que le Build et le Trigger fonctionnent en cliquant sur Run Trigger. Les résultats seront placés dans les pages Build History→ Images, à partir de la navigation de gauche. Vous devriez avoir une paire d’étiquettes d’image, intitulées latest et une similaire à master-7c6ce76.

Configurer les manifestes Kubernetes

L'étape suivante consiste à créer un fichier de configuration (un manifest) indiquant à Kubernetes comment déployer l'application. Chaque fois que nous déployons une nouvelle version du code, nous mettrons à jour ces manifests.

Nous allons stocker ces fichiers de configuration opérationnelle dans un dépôt Git séparé, cette fois sur GitHub.  

1. Créez un dépôt dans Github appelé go-hello-world-config. Cochez la case Initialiser ce repository avec un fichier README.  

2. Clonez-le dans un dépôt git local sur votre mac

git clone <github repo url> go-hello-world-config

3. Basculez vers votre nouveau repository Git local: créez un répertoire appelé manifests dans le repository. Nous ajouterons dans ce répertoire quelques fichiers décrivant le mode d’exécution de l’application sur le cluster:

cd go-hello-world-config
mkdir manifests

4. Créez un fichier appelé manifests/hello-world-dep.yaml. Le premier fichier décrit le mode de déploiement de l’application, appelé «déploiement» dans la terminologie de Kubernetes. Le contenu du fichier est:

---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  annotations:
    flux.weave.works/automated: "true"
  name: hello-world
  labels:
    name: hello-world
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: hello-world
    spec:
      containers:
      - name: hello-world
        image: gcr.io/gcp-weave-cicd/go-hello-world:master-9709e0e
        ports:
    - containerPort: 8080

Modifiez la ligne d’image du conteneur afin qu’elle contienne le nom de votre projet, le nom du repository et le tag créée à l’aide du Build Trigger ci-dessus. Pour le trouver, allez dans le menu Container Registry de GCP. Dans la section Build History, chaque Build affiche des artefacts. Coupez et collez votre configuration spécifique dans la ligne d’image de votre fichier hello-world-dep.yaml.

Remarque: Si vous modifiez la ligne d'image de manière incorrecte, le déploiement échouera.

5. Créer un manifest de service Créez ensuite un service qui indique à Kubernetes comment l’application doit être exposée au monde entier. Créez un fichier manifests/hello-world-svc.yaml:

---
apiVersion: v1
kind: Service
metadata:
  name: hello-world
  labels:
    name: hello-world
spec:
  type: LoadBalancer
  ports:
  - port: 8080
    targetPort: 8080
  selector:
    name: hello-world

Cela demandera à Kubernetes d’exposer l’application nommée «hello-world», créée par le «Déploiement» ci-dessus, sur le port 8080 d’une adresse IP attribuée au cluster.  

Exécuter l'application sur GKE

Si vous n'en avez pas déjà un, créez un cluster dans Google Kubernetes Engine (GKE). Suivez l’assistant pour créer un cluster à 3 nœuds.

Dans la fenêtre de votre terminal, connectez-vous au cluster, la commande se trouve dans le bouton Connecter du cluster. Vous n'avez besoin que de la première commande à ce stade.

Votre ordinateur local est maintenant connecté au cluster. Nous pouvons déployer l'application à l'aide des manifests que nous avons créés ci-dessus. Dans la racine du référentiel git go-hello-world-config, exécutez la commande suivante:

kubectl apply -f ./manifests/

Vous devriez voir le résultat de la commande comme ceci:

kubectl apply -f ./manifests/
deployment "hello-world" configured
service "hello-world" configured

Pour vérifier l'état du déploiement, procédez comme suit:

MBP-de-admin:go-hello-world-config admin$ kubectl get deployments
NAME          DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-world   1         1         1            1           13s

Pour vérifier l'état des services, procédez comme suit:

MBP-de-admin:go-hello-world-config admin$ kubectl get services
NAME          TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)          AGE
hello-world   LoadBalancer   10.39.244.251   35.228.179.228   8080:31555/TCP   2h
kubernetes    ClusterIP      10.39.240.1     <none>           443/TCP          2h

L’application est assez simple, il ne faut donc pas longtemps pour qu'elle soit prête. On peut utiliser curl pour le vérifier, en utilisant EXTERNAL-IP à partir de la sortie ci-dessus. L'application fonctionne sur le port 8080:

MBP-de-admin:go-hello-world-config admin$ curl http://35.228.179.228:8080
Hello world!
Hostname: hello-world-544bf4cf67-wmfxl

La dernière étape consiste à pousser les manifests vers le dépôt GitHub:

MBP-de-admin:go-hello-world-config admin$ git stage --all
MBP-de-admin:go-hello-world-config admin$ git commit --message "Initial go-hello-world manifests"
[master db25aea] Initial go-hello-world manifests
 2 files changed, 35 insertions(+)
 create mode 100644 manifests/hello-world-dep.yaml
 create mode 100644 manifests/hello-world-svc.yaml

Et pour finir le git push :

MBP-de-admin:go-hello-world-config admin$ git push
Username for 'https://github.com': gabrielsagnard
Password for 'https://gabrielsagnard@github.com': 
Énumération des objets: 6, fait.
Décompte des objets: 100% (6/6), fait.
Compression par delta en utilisant jusqu'à 8 fils d'exécution
Compression des objets: 100% (5/5), fait.
Écriture des objets: 100% (5/5), 739 bytes | 739.00 KiB/s, fait.
Total 5 (delta 0), réutilisés 0 (delta 0)
To https://github.com/gabrielsagnard/go-hello-world-config.git
   bbed9b3..db25aea  master -> master

Petite vérification dans le repository Github en question :

Set-up Weave Cloud

Si vous n'avez pas encore installé Weave Cloud via Google Launcher, faites-le maintenant. Voir Weave Cloud sur Google Container Engine pour les différentes étapes.

Configurer le déploiement continu

Pour que Weave Cloud puisse déployer automatiquement les nouvelles versions de l’application, il doit savoir où sont stockés les manifests Kubernetes. Chaque fois qu'un déploiement a lieu, il met à jour le manifest avec la nouvelle balise d'image de conteneur avant de les appliquer au cluster.

Dans Weave Cloud, cliquez sur l’icône cog de la barre du haut pour accéder à la zone de configuration. Sous Config, cliquez sur le menu Deploy.  Il y a deux étapes dans la mise en place:  

  • Donne accès à Weave Cloud au repository Github
  • Autoriser l'agent du cluster à déployer la dernière version

Configuration GitHub

Pour que Weave Cloud puisse accéder aux archives de gestion de Kubernetes et les écrire, nous lui indiquons l'emplacement du repository git sur GitHub.  

Basculez les onglets sur la page GitHub de votre repository go-hello-world-config et sélectionnez le bouton Cloner ou télécharger. Assurez-vous qu’il affiche Cloner avec SSH, puis copiez l’URL du référentiel.  

Revenez à l'onglet Weave Cloud et collez-le dans la zone URL de la section Référentiel de configuration. Supprimez le .git à la fin pour qu’il s’agisse d’une URL appropriée. Définissez le chemin d'accès aux fichiers de configuration sur manifests, qui correspond au répertoire dans lequel nous avons stocké les manifests. Il convient de définir Branch pour que master soit automatiquement sélectionné.

Faites défiler la page un peu et cliquez sur le bouton PUSH KEY.

Cela vous mènera à une page sur Github qui vous demande d'autoriser Weave Cloud. Ces autorisations permettent à Weave Cloud de lire et d'écrire les manifestes Kubernetes à partir de Github. Une fois que vous les avez acceptés, vous serez ramené à Weave Cloud.

Configurez l'agent (déjà vu)

Ensuite, configurez les agents du cluster. Cliquez sur l'icône Cog dans la barre principale pour accéder à la page de configuration. Prenez le menu Config → Deploy.  Remplissez à nouveau la section Repository de configuration avec l'URL et le chemin d'accès aux fichiers de configuration. Ce faisant, il mettra à jour l'extrait de code ci-dessous. Copiez l'extrait de code de la page (utilisez le bouton Copier à droite) et exécutez-le dans votre terminal:

$ kubectl apply -f "https://cloud.weave.works/k8s/flux.yaml?t=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&flux-version=%5E1&k8s-version=$(kubectl version | base64 | tr -d '\n')&git-label=flux-muddy-fire-55&git-url=git%40github.com%3Auser_name%2Fgo-hello-world&git-path=manifests&git-branch=master"

serviceaccount "weave-flux" configured
clusterrole "weave-flux" configured
clusterrolebinding "weave-flux" configured
secret "flux-git-deploy" configured
deployment "weave-flux-memcached" configured
service "weave-flux-memcached" configured
deployment "weave-flux-agent" configured

Retournez à la page Weave Cloud Config, faites défiler l'écran et cliquez sur le bouton PUSH KEY. Pour vérifier qu’il est correctement configuré, vous pouvez cliquer sur le lien situé à côté du bouton qui vous mènera à la section Déployer les clés de Github dans un nouvel onglet.

Nous avons maintenant expliqué aux agents du cluster comment accéder au référentiel et configurer une clé de déploiement. Lorsque les agents se reconfigureront, un avertissement jaune s’affichera sur la page. Cela peut prendre quelques instants, puis un avis vert avec AGENTS CONFIGURED apparaît.

Lorsque vous avez l'avis vert, cliquez sur le bouton Déployer dans la navigation principale. Vous verrez maintenant une liste des services du cluster. Sélectionnez celui intitulé default: deployment/hello-world et vérifiez qu’il indique DEAUTOMATE. Si le bouton indique AUTOMATE, cliquez dessus pour le changer.

Lorsqu'il est configuré pour automatiser le nom du service sur la gauche, une icône de petit camion apparaîtra:

En le mettant en mode automatisé, nous disons à Weave Cloud que nous souhaitons que ce service:  

  • Surveille l'image de conteneur spécifiée dans le déploiement, pour les nouvelles versions de tag
  • Chaque fois qu'un nouveau tag apparaît, mette à jour les manifests de déploiement.
  • Commit et Push le changement de git
  • Applique le manifest mis à jour au cluster Kubernetes

Déployer un changement et ce, complètement automatiquement!

Le moment est venu de déployer une nouvelle version du serveur Web conteneurisé «hello world», en commettant simplement une modification du code de l'application.  

1. Changer le code source de l'application

Dans votre terminal, accédez au repository go-hello-world/src/source. Dans hello-world.go, changez le texte de la déclaration de sortie de «Hello world!» En quelque chose de nouveau:

func hello(w http.ResponseWriter, r *http.Request) {
    log.Printf("Serving request: %s", r.URL.Path)
    host, _ := os.Hostname()
    fmt.Fprintf(w, "Hello! The CICD pipeline works!\n")
    fmt.Fprintf(w, "Hostname: %s\n", host)
}

2. Commit et lancer le pipeline

Lorsque nous nous engageons et que nous transférons le nouveau code dans le repository source, le pipeline est automatiquement lancé.

$ git add src/hello-world.go
$ git commit -m 'change text'
[master 840c5ed] change text
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git push
Counting objects: 4, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 354 bytes | 354.00 KiB/s, done.
Total 4 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2)
To https://source.developers.google.com/p/$PROJECT_NAME/r/go-hello-world
   7c6ce76..840c5ed  master -> master

3. Vérifiez chaque étape de l'automatisation du pipeline

Nous pouvons vérifier que chaque étape du pipeline de déploiement a bien fonctionné.  

  • Vérifiez que le code est poussé en visitant les repository sources sur GCP.
  • Accédez au code source pour afficher le repository de code. Vérifiez un Build effectué en accédant au Container Registry sur GCP. Archiver le Build History pour un nouveau Build.
  • Vérifiez également qu'une nouvelle image de conteneur a été créée dans le Container Registry. Dans «Images», accédez au repository go-hello-world où vous devriez voir une nouvelle image de conteneur avec de nouveaux tags.

4. Vérifiez que Weave Cloud a déployé la nouvelle version

Allez dans «Deploy» sur Weave Cloud dans le service par défaut: deployment/hello-world. Dans la section «Conteneurs» de la page, vous trouverez des informations sur le conteneur qu'il a déployé, par exemple gcr.io/gcp-weave-cicd/go-hello-world:master-cc97017, qui devraient être identiques à celles du registre de conteneurs de GCP. .  

Dans l'historique à droite, vous verrez quelque chose comme Synced to cluster: default: deployment/hello-world(4c5837b022ff), cliquez sur le git qui doit être transféré dans le repository de configuration sur GitHub où vous pouvez voir le changement dans le manifest.

5. Testez l'application  

Une fois la nouvelle image déployée, vous pouvez tester l’application:

$ curl http://35.202.175.232:8080/
Hello! The CICD pipeline works!
Hostname: hello-world-256096363-3dkxt

Comme vous pouvez le constater, nous recevons le nouveau message mis à jour! Notez que le nom du pod a été modifié, car Kubernetes a déployé un nouveau pod lors de la mise à jour de l'image.  

Conclusion

Félicitations, vous disposez maintenant d’un pipeline CI/CD entièrement automatisé - le moyen le plus rapide du Commit au déploiement en production!

Le pipeline regroupe les repository sources Google, Google Cloud Builder, Google Container Registry et Weave Cloud.

Pour aller plus loin, ajoutez votre propre application et construisez des déploiements plus complexes via le pipeline, ce que nous ferons dans un tout prochain article.