Mettre en place une CI/CD avec GitLab et GKE: Infrastructure

Mettre en place une CI/CD avec GitLab et GKE: Infrastructure

Suite au WeSpeakCloud organisé par WeScale le 28 mai dernier, voici un résumé de notre présentation sous forme d’articles, afin de partager ce retour avec un maximum de monde.

(*) Le WeSpeakCloud est un meetup organisé par WeScale, une fois par mois sur des sujets autour du cloud computing.

Sans plus tarder, je vous présente le slot Architecture.

Infrastructure GitLab & GKE :

Dans ce chapitre, j’aborderai les différentes étapes de réalisation pour mettre en place l’infrastructure GCP, mettre en place GitLab et GitLab CI/CD.

L’intégration de GitLab avec Kubernetes peut se faire de deux façons :

  • GitLab à l'extérieur de Kubernetes et la CI à l’intérieur du cluster.
  • GitLab et la CI dans Kubernetes.

Le but de cette intégration est de bénéficier de l'élasticité et la haute disponibilité de votre CI gérée par Kubernetes.

GitLab à l'extérieur, la CI dans GKE :

Vous avez un GitLab, et vous voulez le connecter avec un cluster Kubernetes afin de monter une CI/CD.

L’architecture peut varier d’un cas d’usage à un autre, mais le schéma classique de cette première solution contient généralement :

  • Deux instances Compute Engine GitLab, idéalement sur deux zones différentes.
  • Uneinstance profile permettant aux instances d’écrire sur GCS.
  • Unauto-scaling qui garde un nombre minimum d’instances disponibles.
  • Unload balancer en frontal des instances pour répartir le trafic entre les deux instances.
  • Unehosted Zone dansCloud DNS pour la résolution DNS. Il faut prévoir son nom de domaine public pour le brancher avec cette zone.
  • Un cluster GKE, dans lequel on fait tourner la CI.
  • Un bucket GCS, afin de stocker les backups GitLab.

Le schéma suivant illustre les différents services utilisés :

Capture-d-e-cran-2019-07-05-a--15.42.13

Mise en place :

  1. Sur l’interface GitLab, dans un projet, aller sur l’onglet à gauche opérations.
  2. Choisissez Kubernetes.
  3. Add cluster Dans cette fenêtre vous avez deux choix : créer un nouveau cluster GKE en suivant la documentation GitLab, ou choisir un cluster existant. Dans ce cas vous pouvez choisir un cluster hébergé ailleurs.
  4. Dans mon cas j’ai préféré choisir un cluster existant créé par terraform, plutôt que de donner à GitLab les droits GCP pour créer un GKE. Si vous êtes dans ce cas ignorez l’étape 6. sinon allez directement sur cette étape détaillée sur GitLab.
  5. Remplissez l’ensemble des champs pour trouver votre cluster. Notez qu’il faut avoir des certificats valides côté GitLab et Kubernetes, sinon cela risque de ne pas fonctionner.
  6. Si vous fournissez les droits (service account GCP), gitlab créera le cluster pour vous.
  7. Si la communication est réussie, vous allez avoir la possibilité d’installer le Helm pour GitLab ainsi que d’autres outils proposés commele GitLab Runner qui nous intéresse dans cette partie.
  8. Faites attention au token(k8s service account) que vous donnez à GitLab pour qu’il installe le tiller Helm dans k8s, créez un service account non admin sur le cluster avec des droits bien définis, par exemple.

Une fois le Runner déployé, vous pouvez lancer un premier test sur votre CI GitLab, mais elle n’est pas encore prête à 100%. Ceci est un ensemble de points que j’ai eu à traiter pour que la CI soit prête :

  • Gestion de backup, il faut penser à sauvegarder régulièrement votre base de code.
  • Gestion du cache, artifacts, etc .., permet de passer des dépendances, des résultats etc entre les stages.
  • Configuration du Runner: il faut mettre à jour la configuration pour que le cache spot soit pris en charge.

Pour le sujet CD, j’en parlerai dans la prochaine partie, puisque c’est déployé de la même façon.

Pour résumer :

Cette méthode présente certains avantages comme :

  • L’indépendance de GitLab de GKE, si vous rencontrez des problèmes dans votre cluster, seule la CI sera affectée.
  • auto scaling pour implémenter la scalabilité et la haute disponibilité de votre machine GitLab, comme votre cluster GKE.

Mais les inconvénients suivants :

  • La mise en place est un peu complexe, surtout la partieautoscaling.
  • Après la mise en place, votre CI n’est pas encore prête à 100%, il faut encore :
  • Mettre en place une solution de cache, Minio par exemple pour sauvegarder vos caches, artifacts, ...etc entre lesstage de votre CI.
  • Mettre à jour la configuration de votre runner dansgitlab.tom pour qu’il puisse communiquer avecMini.
  • Gérer les backups, le load balancing etc ...

GitLab et la CI dans GKE :

Cette méthode est la plus simple à mettre en place en utilisant le Chart Helm fourni par GitLab. Une fois ce chart est installé, votre CI est déjà prête à être utilisée, il vous reste juste à gérer les backups. On en parlera plus loin dans l’article.

Mise en place :

  1. Lancez votre cluster GKE. Ceci est un exemple Terraform qui vous permet de lancer un cluster avec un noeud de type n1-standard-4, dans la zone europe-west1-b avec l’autoscaling activé. L'auto scaling est géré en toute transparence par GCP, et vous permet de scaler vos nodes assez facilement, en définissant le min_node_count et max_node_count de votre cluster.
  2. Une fois le cluster UP, récupérez les paramètres client_certificate, client_key ,cluster_ca_certificate et endpointpour configurer le client kubectl sur votre machine.
  3. Installez Helm, et initialisez le client avec helm init. Helm se base sur la configuration kubectl dans ~/.kube/config afin de lancer son serveur appelé tiller sur k8s. Ce tiller est utilisé pour déployer les applications dans GKE.
  4. Il faut aussi créer les composants réseau nécessaires pour exposer GitLab à l'extérieur. Une adresse IP publique et une hosted zone branchée avec un domaine public. Ceci est un exemple Terraform qui vous permet de créer le nécessaire.
  5. Maintenant, vous pouvez lancer le chart Helm de GitLab. Vous pouvez le personnaliser en lui passant des paramètres au lancement. Dans notre cas, on a utilisé le nom de domaine, l’adresse IP publique créés précédemment et une adresse email pour signer les certificats déployés avec le chart.
    Exemple:
helm install gitlab/gitlab --name=gitlab --namespace=gitlab --set global.hosts.domain=gcp.mydomain.com --set global.hosts.externalIP=35.X.X.X
 --set certmanager-issuer.email=myemail@wescale.fr
  1. Vous remarquez qu’on a utilisé un nouveau namespace gitlab. Si vous avez les droits rbac activés dans votre cluster, votre déploiement risque d’échouer, puisque le tiller n’a pas les droits pour utiliser ce nouveau namespace. Il faut modifier/créer un serviceAccount et l’attacher au tiller.

Capture-d-e-cran-2019-06-08-a--23.30.41

Après quelques minutes, si tout fonctionne bien, votre GitLab sera accessible depuis l’adresse gitlab.gcp.mydomain.com. Pour avoir les différents accès :

  • Récupérez le mot de passe de l’utilisateur root avec :
kubectl get secret gitlab-gitlab-initial-root-password -ojsonpath='{.data.password}' -n gitlab | base64 --decode

Minio est accessible depuis l’addresse minio.gcp.my-domain.com.

  • Le user/password de Minio sont visibles avec :
kubectl get secret minio-secret -ojsonpath='{.data.password}' -n gitlab | base64 --decode

En détails :

Le chart Helm de GitLab, se repose sur d’autres charts pour déployer les différents composants afin de faire fonctionner le service. Je vous invite à regarder la documentation officielle si vous voulez en savoir plus.

Maintenant, allons voir ce qui s’est passé dans le cluster :

  • Vous remarquerez que plusieurs disques ont été créés sur votre compte. Oui, c’est normal, ce sont les différents disques utilisés par les différents pods qui assurent le service GitLab.
  • Un load balancer attaché a votre DNS gcp.mydomaine.com et qui a comme target l’adresse ip publique que vous avez créée et attachée au node GKE. Pour accéder à GitLab depuis l'extérieur.
  • Si vous regardez dans le namespace gitlab avec kubectl get pods -n gitlab , vous allez voir plusieurs pods qui sont créés. Cela ressemble à ce schéma non exhaustif :

Capture-d-e-cran-2019-06-08-a--23.34.01

  • Des ingress-Controller nginx, servent à exposer les différents micro-services.
  • Cert-manager, utilise letsencrypt.com pour générer des certificats valide pour gitlab, registry etc …
  • Redis, pour la gestion du cache.
  • Postgres, gestion de données GitLab.
  • Prometheus, pour la remontée de métriques.
  • Registry, Pour la gestion des images de conteneurs.
  • Minio, Il a plusieurs rôles :
    • La gestion du cache entre les stages GitLab CI.
    • Le stockage des backups GitLab.
    • La gestion des artifacts etc ...
  • Runner, c’est le pod maître qui lance les build GitLab CI en lançant d’autres pods runner.
  • Gitlab-processes, c’est un ensemble de pods pour assurer le service (Core, UI, ...).

Gestion de backup :

Dans cette deuxième implémentation, les backups sont poussés sur Minio plutôt que sur GCS. Ce choix est lié au fait que l’intégration est déjà faite dans le chart Helm de GitLab, avec toute la configuration nécessaire.

Un petit bonus, Minio peut être paramétré comme une gateway et utiliser le GCS.

Le reste à faire est d'ajouter un job qui tourne en continue pour créer et pousser les backups dans Minio. Cela nous mène au schéma suivant :

Capture-d-e-cran-2019-06-10-a--18.30.06

Notre Job est configuré comme suit :

  • Un CronJob Kubernetes qui se lance deux fois par jour, du lundi au vendredi, à 13h et à 20h: 00 13-20 * * 1-5.
  • Le CronJob lance un job/pod qui exécute la commande GitLab backup-utility dans le pod gitlab-task-runner-*.
  • Ce dernier crée le backup en format zip et le pousse sur Minio.
    Vous pouvez voir l’exemple de mise en place ici.

Et la CD ?

Notre application est déployée dans un cluster GKE, et on a choisi Helm comme outil de déploiement. L’idée est d’avoir un tiller (Helm) propre à chaque cluster Kubernetes, avec un service account attaché en lui permettant d’utiliser des namespaces spécifiques. Le tillersera utilisé par GitLab (le client Helm configuré dans un pod en vrai) pour déployer l’application. Cela est présenté par le schéma suivant :

Capture-d-e-cran-2019-06-25-a--15.50.14

Nous reviendrons avec plus de détails sur cette partie dans le 2ème article qui expliquera en détails la CI/CD.

Pour résumer :

Cette méthode présente des avantages :

  • La mise en place est très rapide.
  • On bénéficie des avantages de Kube pour gérer la haute disponibilité et la résilience.
  • Autoscaling à deux niveaux, au niveau pods et au niveau nodes (VM) gérés par GKE.
  • Sur GKE c’est encore plus simple, il se connecte bien avec les autres services GCP et ça simplifie le déploiement des applications.
  • Vous pouvez avoir un cluster k8s dédié pour GitLab, pour faciliter la gestion et la maintenance.

Les limitations :

  • Sur la version gratuite de GitLab, vous ne pouvez pas connecter plus d’un cluster Kubernetes. Il faut basculer sur une version payante pour connecter plusieurs clusters.
  • D’autres limitations liées à cette version du chart sont mentionnées dans la doc officielle.

La suite :

Dans cet article, j’ai présenté les deux possibilités pour avoir une CI/CD avec GKE et GitLab. J’ai fait un focus sur la deuxième méthode, que j’ai trouvée plus simple et plus rapide pour la mise en place. Pour le prochain article, Bassem et Alexis nous détaillerons la partie CI/CD de ce projet.