Mesure de l'impact environnemental des développements

greenframe.io

Le numérique et son impact sur l'environnement

Le 6ème rapport du GIEC (Groupe d'experts intergouvernemental sur l'évolution du climat) d'août 2021 prévoit que le réchauffement planétaire de 1,5°C sera atteint avant 2040.

Pour limiter et stabiliser le réchauffement climatique sous la barre des 2°C d'ici 2100, le GIEC réaffirme qu'il faut sensiblement et rapidement baisser les émissions de CO2 mais aussi de tous les autres gaz à effet de serre.

Aujourd'hui, le digital c'est 10% de la consommation électrique dans le monde et représente de 3% à 4% des émissions gaz à effets de serre. Ces émissions pourraient représenter, en 2040, jusqu'à 6,7%, soit une hausse de plus de 60%.

image.png Distribution de la consommation d’énergie finale du numérique par poste pour l’utilisation (55%) et la production (45%) en 2017

On distingue deux phases dans le cycle de vie du digital, la production et l'utilisation. Même si en tant que développeurs nous avons un petit rôle à jouer sur la fabrication en veillant à ne pas amplifier l'obsolescence des terminaux, c'est sur l'utilisation que nous avons un plus grand rôle à jouer.

La phase d'utilisation implique (quasiment) trois tiers :

  • Terminaux
  • Datacenters
  • Réseaux

Nous, architectes et développeurs, devons donc être vigilants à l'impact qu'aura la conception d'une application sur ces trois tiers, quelque soit le type d'application (web, mobile, client lourd, embarquée, etc...) :

  • Ne pas faire exploser le besoin en CPU / mémoire / stockage pour les terminaux et les datacenters
  • Réduire au maximum l'impact sur les réseaux en réduisant le nombre et le volume des échanges

Comment analyser les développements ?

Je vais considérer que les bonnes pratiques en termes d'éco-conception sont acquises (si jamais ce n'est pas le cas, un article dédié aux bonnes pratiques est en cours de rédaction) et que les référentiels suivants sont connus :

et passer directement à notre sujet : comment vérifier tout ça ?

L'idéal pour notre métier de développeur, c'est d'arriver à vérifier le plus rapidement possible que nos développements respectent bien les concepts de l'éco-conception, le but étant de réagir et d'effectuer les modifications nécessaires le plus tôt possible.

De plus en plus d'outils existent aujourd'hui et nous permettent d'effectuer des vérifications. Le problème c'est que la plupart des outils sont :

Ces outils sont bien pour quelques vérifications de temps en temps, mais ce n'est pas ce qui se fait de mieux pour suivre l'évolution de l'impact environnemental tout au long du cycle de développement.

Nous avons donc besoin d'un outil qui pourrait s'exécuter automatiquement, à chaque fois que l'on développe une nouvelle fonctionnalité. Ce qui tombe plutôt bien, c'est que j'ai un gestionnaire de dépôts GIT (celui avec la tête de renard orange comme logo, j'ai nommé "gitlab") avec sa chaine d'intégration continue intégrée, qui me permet d'exécuter des outils automatiquement

gitlab-logo-500.png

On sait à quel moment exécuter des analyses, on sait où, mais avec quoi ?

greenframe . io

Mon besoin est donc d'analyser l'impact environnemental des développements, pour :

  • de multiples projets
  • un nombre en constante augmentation de développeurs
  • une chaine d'intégration continue sur gitlab
  • et, cerise sur le gâteau, des runners gitlab dans des clusters kubernetes (plusieurs runners par cluster et ISO 27001 oblige, un cluster par projet)

Après avoir fait un tour d'horizon des outils qui existent, mon choix s'est porté (presque) instantanément sur greenframe.io. C'est un des rares (sinon le seul) à avoir des possibilités d'analyse complètes :

  • Sur les postes des développeurs ou depuis une CI (initialement github avec l'inclusion d'une application pour travis)
  • Qui affichent les performances, la consommation énergétique et l'équivalent CO2

Certes les chiffres mis en avant peuvent interroger par rapport à des chiffres issus d'autres outils, mais les chiffres de greenframe même s'ils sont probablement faux (on parle ici d'estimation, de formule de calcul sur une base de recherches), permettent de suivre automatiquement une évolution. Parce que c'est bien ici tout l'intérêt d'un outil implémenté dans une chaine d'intégration continue : vérifier que les développements n'aggravent pas l'empreinte environnementale.

Tout le détail du mode de calcul ici marmelab.com/blog/2021/03/04/argos-comparin..

L'outil permet d'exécuter un scénario de type "end user" (je vais sur la homepage, je clic sur tel lien, je scroll vers le bas, j'attends, etc...), scénario qui est exécuté dans un navigateur (chrome) à l'intérieur d'une image docker.

Pendant ce temps, l'outil va "capter" l'utilisation des ressources (equivalent de docker stats) :

  • Du navigateur qui exécute le scénario
  • Mais aussi de toutes les briques sollicitées par le test (serveur web, base de données, serveur de cache, moteur de recherche, etc...)

Vous l'aurez donc compris, il faut que l'applicatif à tester soit "dockerisé", sinon l'outil ne pourra pas montrer l'ampleur de son analyse.

Est-ce que toutes les cases sont cochées ? Pas vraiment, la grosse case "gitlab + cluster k8s" ne l'était pas, je parle bien ici au passé, puisqu'après un échange avec les équipes de greenframe, nous (Niji) avons décidé de financer en partie le développement de l'analyse greenframe de conteneur au sein d'un cluster kubernetes.

A ce moment-là, l'outil n'était capable que d'analyser des conteneurs docker, lancés par docker. Maintenant l'outil est en mesure d'analyser un pod dans un cluster kubernetes.

Comment implémenter l'outil

Etant donné que les runners sont lancés dans les clusters kubernetes, que la pipeline gitlab CI s'exécute dans un conteneur, que l'outil greenframe créé un conteneur docker pour lancer son analyse ... inception ... on se retrouve donc avec du docker in docker, "dind" pour les intimes.

inception

Il faut donc autoriser le pod du runner à faire du "dind". Je ne vais pas m'étendre sur ce sujet, il y a déjà beaucoup de littérature là-dessus :

Il nous faut maintenant une image docker qui embarque l'outil greenframe. A l'heure actuelle, greenframe ne propose pas son outil embarqué dans une image docker. J'ai donc construit ma propre image

FROM node:16

RUN apt update && apt install -y \
        apt-transport-https \
        bash \
        ca-certificates \
        curl \
        git \
        gnupg2 \
        lsb-release \
        python3 \
        software-properties-common \
    && rm -rf /var/lib/apt/lists/*

# Install docker
RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
RUN add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian buster stable"
RUN apt update && apt install -y \
        containerd.io \
        docker-ce \
        docker-ce-cli \
        docker-compose-plugin \
    && rm -rf /var/lib/apt/lists/*

# Install gcloud cli
RUN curl https://dl.google.com/dl/cloudsdk/release/google-cloud-sdk.tar.gz > /tmp/google-cloud-sdk.tar.gz
RUN mkdir -p /usr/local/gcloud \
  && tar -C /usr/local/gcloud -xvf /tmp/google-cloud-sdk.tar.gz \
  && /usr/local/gcloud/google-cloud-sdk/install.sh
ENV PATH $PATH:/usr/local/gcloud/google-cloud-sdk/bin
RUN gcloud components install gke-gcloud-auth-plugin

# Install kubectl cli
RUN curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
RUN chmod +x ./kubectl
RUN mv ./kubectl /usr/local/bin/kubectl

# Install greenframe cli
RUN cd /root \
        && curl https://assets.greenframe.io/install.sh | bash
ENV PATH $PATH:/root/.local/bin

RUN mkdir /app
RUN git config --global --add safe.directory /app
WORKDIR /app

Maintenant que j'ai une image pour la CI, il me faut un scenario de test :

async (page) => {
  await page.goto("", {
    waitUntil: "networkidle",
  });
  await page.waitForLoadState("domcontentloaded");

  await page.goto("page1", {
    waitUntil: "networkidle",
  });
  await page.waitForTimeout(2000);
  await page.goto("page2", {
    waitUntil: "networkidle",
  });
  await page.waitForTimeout(2000);
  await page.goto("page3", {
    waitUntil: "networkidle",
  });
  await page.waitForTimeout(2000);
};

Avec ce scenario, je simule une navigation, un utilisateur arrive sur le site, il attend que tout soit chargé, ensuite il clic sur le lien de la page1, il attend 2 secondes, il clic sur un autre lien, etc, etc...

Avant de pouvoir lancer une première analyse, il me faut définir quelques paramètres pour l'outil :

scenario: "./.greenframe-scenario.js"
baseURL: https://my-url
projectName: my-project-name
samples: 2
distant: false
kubeContainers:
  - "my-namespace:app=my-name"
dockerdHost: "127.0.0.1"
dockerdPort: 2375

Tous les paramètres sont très bien documentés sur docs.greenframe.io Les seuls paramètres particuliers dans notre contexte d'exécution k8s sont :

  • kubeContainers : la liste des containers à surveiller
  • dockerdHost et dockerdPort : le hostname et le port pour accéder au deamon docker

J'ai maintenant tout ce qu'il faut pour pouvoir lancer une analyse depuis gitlab.

greenframe:
  stage: greenframe
  tags:
    - dind
  image:
    name: my-greenframe-image:1.4.4
    entrypoint: [""]
  services:
    - docker:19.03.1-dind
  script:
    - echo ${GCLOUD_GITLAB_RUNNER_SERVICE_KEY} | base64 -d > ~/gcloud-gitlab-runner-service-key.json
    - gcloud auth activate-service-account gitlab-runner@${GCLOUD_PROJECT_ID}.iam.gserviceaccount.com --key-file ~/gcloud-gitlab-runner-service-key.json
    - gcloud config set project ${GCLOUD_PROJECT_ID}
    - gcloud container clusters get-credentials devcluster --zone europe-west3-b --project ${GCLOUD_PROJECT_ID}
    - greenframe --version
    - greenframe kube-config
    - greenframe analyze
  only:
    - develop

Il faut bien sûr faire en sorte que le runner ait un accès complet au cluster kubernetes, d'où toutes les commandes gcloud ...

La commande greenframe kube-config va permettre d'initialiser un pod cadvisor dans chaque node du cluster kubernetes. L'outil greenframe va s'appuyer sur ces pods pour capter les ressources utilisées lors de l'exécution des scénarios de test.

Et voilà le résultat

Gitlab output

greenframe result

Pour conclure

Le seul moyen d'améliorer la performance énergétique des développements, c'est de tester et mesurer.

Greenframe nous propose donc un outil qui permet d'inclure cette mesure tout au long du cycle de développement.

Je tiens à remercier l'équipe Greenframe et plus particulièrement Guillaume Billey que j'ai sollicité très souvent pour arriver à faire fonctionner notre première analyse d'un cluster kubernetes.

Aujourd'hui nous avons un premier projet avec une analyse systématique de l'empreinte environnementale. L'ensemble de notre factory va suivre et tous nos projets vont avoir cette analyse dans leurs cycles de développement.