Début 2020, un projet DevOps a été initié chez un de nos clients pour répondre à plusieurs besoins. Nous sommes dans un contexte où l’équipe d’exploitation (Ops) gère un grand nombre d’applications métier très hétérogènes avec un scope de responsabilités assez vaste, allant des facilities (gestion des salles serveurs), du provisionnement de serveurs virtuels (VMs,) jusqu’au déploiement des applications en production, en intégrant évidemment le monitoring applicatif, le stockage SAN, le backup disques/LTO7.
Les processus en place n’étaient plus suffisamment efficients et les demandes d’hébergement, de déploiement en production grandissant, il fallait repenser certaines méthodes de travail. Cette perte d’efficacité était en quelque sorte liée au turn-over régulier dans l’équipe d’Ops scope d’intervention mais aussi et surtout, au manque de dialogue avec les (nombreuses) équipes de développeurs.
La première phase de ce projet a été de faire en sorte que l’equipe des Ops adopte la méthodologie DevOps (mais surtout GitOps) pour la faire gagner en agilité, afin de pouvoir ensuite migrer sur une architecture résiliente et automatisée.
La phase suivante a été de reprendre les processus d’exploitation de l’infrastructure legacy et de trouver la meilleure solution qui s’offrait pour répondre à tous les besoins du client.
A partir de là, le choix s’est rapidement porté sur la solution
Kubernetes 
Dans cet article, nous allons expliquer ce choix et présenter les problématiques rencontrées sur sa mise en place dans l’infrastructrure on premise du client.
Choix de la solution Kubernetes 
A quels besoins Kubernetes permet-il de répondre et à quelles contraintes s’expose-t-on dans un environnement on premise ?
Kubernetes
est avant tout une solution open source initiée par Google pour orchestrer énormément de conteneurs en interne, puis le projet a été ouvert et est vite devenu une référence du catalogue de la CNCF (Cloud Native Computing Fundation). Ce qui fait la force de cet outil, c’est la possibilité de créer un cluster sur des hôtes qui soient on premise (datacenters internes à l’entreprise) ou dans tous les types de cloud-computing.
Kubernetes
est maintenant bien connu et cette notoriété se distingue facilement lorsqu'on se penche sur les différents services managés, proposés par les principaux fournisseurs de Cloud du marché actuel (EKS chez Amazon, AKS chez Azure, GKE chez Google). De plus en plus d’entreprises migrent vers ce type d’infrastructure et les profils sur le marché de l’IT sont de plus en plus recherchés pour assurer le Build & Run autour de cette solution.
La communauté GitOps autour de Kubernetes
est très active, tout comme la fréquence des sorties de versions :
| TIP |
– une majeure tous les 3 mois – une mineur tous les mois |
| WARNING |
– une majeure tous les 3 mois – une mineur tous les mois |
En introduction, nous soulignions le fait que les processus en place dans l’équipe d’Ops nétaient plus assez efficients en comparaison du nombre de demandes et qu’il manquait une certaine « agilité ».
Les mécanismes internes de Kubernetes, s’ils sont bien utilisés et en respectant la démarche DevOps, doivent normalement permettre de palier à plusieurs de ces difficultés…à condition d’avoir une équipe d’Ops qui soit suffisament bien dimensionnée mais surtout bien qualifiée !
C’est pourquoi dans notre contexte client, pour accélérer la montée en compétence de l’équipe, un mentor DevOps avec une expertise avancée de Kubernetes | Helm | IaC (Infrastructure As Code) a été détaché directement dans l’équipe d’Ops.
Le client avait plusieurs besoins initiaux :
- Conserver les données en interne
- Maîtrise des coûts liés à l’infrastructure
- Améliorer la fréquence et la qualité des déploiements des applications métier via pipelines CI/CD
- Résilience accrue des applications (qu’on peut obtenir grâce à Kubernetes avec le self-healing, liveness/readyness…)
- Rendre les équipes de développeurs plus autonomes
- Conteneuriser ce qui peut l’être et repenser les applications en micro-service
- Faciliter la gestion de l’infrastructure et des OS liés au contexte client
- Décrire l’infrastructure As Code
- Mutualiser les bonnes pratiques entre les Dev et les Ops
Avoir la gestion complète d’un cluster Kubernetes
sur un environnement on-premise est bien différent d’un cluster Elastic Kubernetes Service (EKS) chez Amazon AWS par exemple. Avec AWS, le déploiement d’un cluster est simplifié au maximum et vous n’avez pas à vous préoccuper du control-plane contenant les masters-nodes. Tout est géré par les équipes IT d’Amazon AWS.
Sur une infrastructure on-premise, il faut
gérer l’installation et le déploiement complet du cluster, d’où
l’importance d’avoir des équipes d’Ops qualifiées, avec une bonne
connaissance des mécanismes et des composants internes de Kubernetes
.
Voici les principaux composants d’un cluster Kubernetes
:
| Etcd | Base clé/valeur qui stocke les données d’état du cluster, elle est généralement déployée en mode cluster sur les nœuds du control-plane. |
| Kube-scheduler | Contenu de la cellule |
| Ligne 3 | Contenu de la cellule |
| Ligne 4 | Contenu de la cellule |
Infrastructure As Code
Cette phase du projet a été cruciale car il fallait absolument être capable de déployer (ou de redéployer) un cluster Kubernetes
en quelques minutes,
chose inenvisageable à la main car il y a trop de sources d’erreur, manque de reproductibilité…
La société HashiCorp en a fait son businness en proposant notamment deux outils libres et open source, capables de déployer de l’infrastructure à partir de fichiers descriptifs :
Un troisième outil libre et open source a été utilisé pour faire de la gestion de configuration soit pour provisionner des fichiers sur les machines, soit pour modifier la configuration des OS, démarrer des services avec systemD ou encore installer des paquets YUM :
Un troisième outil libre et open source a été utilisé pour faire de la gestion de configuration soit pour provisionner des fichiers sur les machines, soit pour modifier la configuration des OS, démarrer des services avec systemD ou encore installer des paquets YUM :
Pour faciliter la bonne tenue des objectifs et conserver une organisation efficace sans cadre figé, des limites WIP (Work in Progress) sont fixées. Le principe ? Limiter le travail en cours : une tâche par développeur (voire moins pour qu’il y ait toujours quelqu’un de disponible pour une revue de code) et tant que cette tâche n’est pas terminée, la personne ne passe pas à autre chose. L’objectif est tout simplement de finir ce qui a été commencé. Si les équipes ne parviennent pas à rester en dessous du WIP, alors c’est qu’il est temps de programmer un moment d’échange pour corriger le processus.
Remplir le pipe régulièrement permet de résoudre ce problème de rythme saccadé mais aussi de reprioriser certaines tâches grâce à une meilleure visibilité. Puisque le cloisonnement entre les itérations n’existe plus, il est en effet plus simple d’optimiser les tâches. Bien entendu, il est nécessaire de veiller à la bonne productivité de l’équipe. C’est en effet l’un des travers de Scrumban : avoir l’impression d’avoir plus de temps pour réaliser chaque tâche et tomber dans une sorte de perfectionnisme qui peut nuire au projet global. Pour pallier ce problème, il est important que les tâches soient découpées en sous-tâches et que le temps soit estimé pour éviter les dérives.
A quoi servent-ils respectivement ?
| Packer |
Terraform |
Ansible |
| Il est utilisé pour la création d’images immuables multi-plateformes (templates de VMs). |
Il permet aux Ops de prédire de manière certaine, la création, le changement et l’évolution de l’infrastructure via du code versionné. |
Les playbooks et les rôles Ansible servent à provisionner les fichiers de configuration ou les fichiers système. |
Ce qui fait la force de ces outils, c’est l’utilisation des API REST pour dialoguer avec les infrastructures et sont donc compatibles avec pratiquement tous les providers du marché (VMware, AWS, OpenShift…).
Le gros avantage de ces outils orientés GitOps, c’est justement l’utilisation de Git et le fait de bénéficier d’un système de branching et de versionning. Tout le code qui décrit notre infrastructure Kubernetes est alors stocké dans le GitLab hébergé en interne.
Dans notre contexte client, l’infrastructure en place repose sur un cluster constitué de 10 hôtes ESXi VMware vSphere 6.7, la rendant compatible avec ces trois outils.
Architecture du cluster client
Le cluster du client a été déployé avec kubeadm et en respectant les bonnes pratiques de la documentation Kubernetes :
cluster_k8s
Tout le travail d’IaC effectué en amont avec la stack | Packer | Terrraform | Ansible | nous a permis d’avoir un cluster qui se déploie et s’initialise en quelques minutes seulement.
Bien entendu, pour que tout cela fonctionne, nous avons été obligés d’intégrer plusieurs éléments importants dans nos templates de VMs Packer :
- l’installation via YUM des binaires
docker, kubelet et kubeadm dans /usr/local/bin
- les certificats SSL ainsi que les autorités de certification du client (Root CA) dans /etc/pki/tls/certs/
- les scripts Bash et les clés SSH
- les différents fichiers de configuration (kube-config, calico…)
Gestion des registry Docker / Helm
Le contexte client impliquait l’abscence d’accès direct à Internet sur l’ensemble de l’infrastrcuture. Il a donc fallu récupérer toutes les images Docker nécessaires à la création du cluster Kubernetes et aux Charts Helm dans un espace GitLab prévu à cet effet.
Cette fonctionnalité intégrée à GitLab est connue sous le nom de shared-registry. Elle s’active au sein d’un projet GitLab et est ensuite accessible sur le port 5050.
Utilisation de la shared-registry pour nos images Docker :
registry_dockers
Docker login :