It Runs on My Cluster - IV - La première année

It Runs on My Cluster - IV - La première année

Ça y est! On a nos clusters Kubernetes Up and Running, mais pas encore d'application métier dessus. Il a fallut attendre trois mois pour avoir la première application qui débarque sur nos clusters de production. Une application ayant juste un composant backend en Java utilisant le framework Spring. Ce n'était pas énorme mais justement ça nous a aidé. Nous étions toujours en train de monter en compétences, nous avions tout de même réussi à engranger pas mal de connaissances sur la façon de monter un cluster Kubernetes de toutes pièces (et en Infrastructure as Code) mais pas encore sur son exploitation au quotidien. Donc avoir trois mois sans application, suivi d'une seule pendant six autres mois c'était finalement une très bonne chose pour démarrer.

Toujours à trois dans l'équipe, nous ne nous sommes pas ennuyé pour autant! Nous continuions d'ajouter et d'affiner des composants essentiels à l'exploitation d'une plateforme comme celle-ci. En effet, c'est bien d'avoir des clusters qui tournent mais si ce n'est pas pour être intégré à un Système d'Information existant ce n'est pas super utile. Nous avons donc travaillé sur trois points extrêmement importants au cours de cette première année :

  • La sécurité que ce soit réseau ou système
  • L'observabilité avec, dans un premier temps, le monitoring, le logging et l'alerting
  • Le déploiement des applications pour les équipes

La sécurité

On le sait tous, dans le monde où l'on vie et d'autant plus dans l'informatique, la sécurité est devenu un enjeu majeur, c'est le point le plus critique que nous devons aborder en priorité sur le projet. Comme je l'avais dis dans un précédent poste, nous tentons le plus possible de répondre aux standards du marché mais aussi d'être à l'état de l'art, pour l'aspect sécurité. C'est une pratique qui va nous permettre de suivre les préconisations du marché auxquelles nous nous conformons par exemple en suivant le benchmark CIS pour Kubernetes.

Les clusters que nous avons installés utilisent la distribution RKE2 qui permets d'être conforme à ce benchmark, il est tout de même parfois utile de modifier quelques configurations pour être totalement en adéquation avec ce dernier. Cela demande un effort continue, ainsi qu'une veille perpétuelle. Heureusement, des équipes de sécurité sont à l'affut des bonnes pratiques et des nouvelles failles potentielles. D'ailleurs qui dit faille dit fix de sécurité. C'est dans ce cadre que l'Infrastructure as Code montre encore des avantages indéniables. En effet, mettre à jour rapidement et surtout de façon très rythmée une infrastructure telle que la notre demanderai beaucoup trop de travail pour une équipe comme la notre. C'est aujourd'hui un (quasi) non événement et cela nous permet d'avoir une infrastructure à jour du sol au plafond sans trop de difficulté. Je dis quasi, car il y a toujours des risques et un peu de travail de contrôle à effectuer, mais généralement tout ce passe bien. J'en parlerai peut être dans un futur poste.

Bon, avoir un cluster configuré aux petits oignons c'est bien, mais si c'est pour mettre du pod à gogo sans contrôle, ca ne va pas servir à grand chose. C'est dans ce cadre que nous avons mis en place différentes policies (as Code bien sur 😛) afin de contrôler efficacement ce qu'il y a dans nos clusters. Comme je vous l'ai dit précédemment, nous avons plusieurs clusters chacun d'un environnement différent. Cela nous permets entre autre de mettre des policies à différents niveaux d'exigence. Pour les policies nous utilisions dans un premier temps OPA Gatekeeper, que nous avons remplacé par la suite... Nous avions différents types de policies, nous allons nous concentrer sur les policies de sécurité. En gros nous mettions en place tout un tas de normes pour interdire au pod de remonter sur les noeuds du cluster, que ce soit à cause d'un privileged, d'un hostpath (partage du file system host/pod), d'un hostnetwork (partage des interfaces réseaux host/pod) ou encore de tout un tas de choses 😉.

Après avoir configuré notre cluster et nos politiques de sécurité pour nos objets Kubernetes, il fallait encore sécuriser les flux réseaux! Pour ce faire nous avions plusieurs choix, celui que nous avions fait c'est d'utiliser les NetworkPolicies et GlobalNetworkPolicies proposées par Calico notre CNI. Je ne détaillerai pas précisément la politique de sécurité que nous avons mis en place. En gros, tout es en Deny par défaut et nous nous basons sur des labels des namespaces et des pods afin que ceux-ci puissent communiquer ou pas entre eux. Par exemple si j'ai une application qui est composée de plusieurs namespaces alors ceux-ci pourront communiquer ensemble mais pas avec les autres namespaces. Nous autorisons aussi certains service par défaut, par exemple le DNS (port 53) vers notre CoreDNS interne au cluster. Ça c'est pour les échanges internes au cluster. Pour les échanges externes c'est une autre paire de manche! En effet, avec Calico Open Source (en tout cas à cette époque là), les flux réseaux qui partaient des pods sortaient sur notre réseau externe au cluster avec une IP d'un noeud et ça c'était compliqué à gérer chez nous! Nous nous sommes donc affairé à concevoir et développer un opérateur qui synchronise les règles internes à notre cluster (GlobalNetworkPolicy) avec les FIrewall de l'entreprise via API. Résultat, cela fonctionne très bien!

L'observabilité

L'observabilité est un autre aspect extrêmement important dans nos environnements de production mais aussi de test et de développement. Nous utilisons Rancher qui fourni un ensemble de chart Helm permettant de répondre rapidement à nos besoins. Nous avons donc pris le parti d'installer une stack Prometheus/Grafana pour les métriques, dashboard et alerting et l'utilisation du Logging Operator (fluentd/fluentbit) afin de déverser nos logs dans nos outils internes (telle que la suite ELK). Il a fallut configurer tout ce petit monde pour avoir a minima des dashboard de métriques consolidés (merci Grafana) mais aussi d'intégrer la collecte de logs et d'alertes à notre Système d'Information. Pour ce qui est du logging, c'était assez "simple", un Output pour Elasticsearch, quelques Flow pour filtrer les pods qui nous intéressent et envoyer le tout sous forme de JSON et le tour est joué. Pour la partie Alerting, ce fût un peu plus conplexe, bien que les rules Prometheus fournies par Rancher étaient déjà très pertinentes, nous en avions créés quelques autres adaptées à nos besoin. Mais il a fallut développer un petit webhook pour recevoir ces alertes et les envoyer directement dans le bac d'évènements de l'entreprise (BEM). Donc encore un peu de développement à faire au sein de l'équipe. Nous avions choisi le langage Go qui est le plus utilisé dans le monde Kubernetes et surtout qui est rapidement utilisable par notre équipe. Étant ancien développeur, c'était plus facile pour moir d'apprendre à l'utiliser qu'un SysAdmin, néanmoins, tout le monde dans l'équipe l'a appris et pratiqué! C'est la force de cette équipe, l'adaptabilité.

Nous ne traitons pour le moment pas les traces, c'est aujourd'hui à la charge des équipes de développement d'intégrer dans leur déploiement un outil d'APM pour envoyer tout ce beau monde dans l'ELK d´entreprise.

À cette époque, nous avions une stack logging, monitoring et alerting par clusters, ce n'était pas le plus efficace ni le plus simple à utiliser, mais c'était le plus rapide à mettre en place. Donc pour 5 clusters nous avions 5 Grafana, 5 stack Prometheus, 5 Logging Operator, etc... Nous n'avions pas non plus de problème de performance n'ayant que très peu d'applications à cette époque (2 dans l'année).

Le déploiement

Rappelez-vous, nous sommes maintenant des fanas de l'Infrastructure as Code, alors nous souhaitions qu'il en soit de même pour nos futurs utilisateurs. De plus, mon expérience laborieuse sur Kubernetes dans mes années passées m´ont appris une chose : Si tu ne contrôles pas ce que tu déploies, cela va vite devenir le BORDEL!

J'avais entendu parlé d'ArgoCD, ca semblait super mais bien trop compliqué et avancé pour notre équipe. L'opportunité que nous avions eu c'est que notre outil Rancher proposait un composant nativement en place qui permettait de faire (presque) la même chose qu'ArgoCD. Ce conposant c'était Rancher Fleet, un outil très (trop?) simple qui permet de faire du GitOps. C´est à dire, écouter un dépôt Git contenant des manifests Kubernetes et/ou Helm pour en déployer son contenu dans Kubernetes de facon automatisée, sûr et rapide. En effet, chaque application avait un dépôt Git avec une branche par environnement/cluster et chaque branche donnait lieu a un namespace dans lequel était déployé les manifests de l'équipe. La partie Workflow se situait donc dans Git et nul par ailleurs. Nous avions donc la possibilité de tracer chaque déploiement.

Pour être complet, nous déployons nos différents Helm chart d'infrastructure (Monitoring, Logging, Alerting, Opérateurs, Webhook, RBAC, etc) avec Fleet aussi. Donc une fois que les clusters étaient provisionnés par Terraform, tout le reste l'était via Fleet en GitOps. Fleet a été pour nous un tremplin vers le monde du GitOps. Je parlerai un peu plus en détails de Fleet dans un futur poste (oui encore un à écrire!).

D'ailleurs tout n'était pas totalement automatisé, en effet, pour qu'une nouvelle application atterisse dans Kubernetes, son équipe de développement devait nous faire un ticket sur l'outil de ticketing de l'entreprise, afin de nous demander la cŕeation de dépôt Git et de son paramétrage, de la création du déploiement Fleet, la création du namespace dans chaque clusters, la création du groupe AD pour donner les droits, etc. Nous avions donc développé un petit Terraform réalisant toutes ces actions, nous devions alors justre créer un fichier YAML avec les différentes informations de la nouvelle application et le lancer. Et Hop tout est à dispo et l'équipe de développement se retrouve enfin autonome.

Tout cela nous a pris un peu plus d'un an après la mise en production des premiers clusters. Nous devions déjà faire face aux premiers upgrade de Kubernetes et de tous nos charts mais à par cela, nous avions assez peu de RUN. Il a fallut faire tout de même pratiquer un nouvel aspect de notre travail : La communication, expliquer ce qu'est Kubernetes, pourquoi l'utiliser et comment. Cette première année était le théâtre d'une multitude de présentations, de vidéos et d'échanges avec différentes équipes. Ce n'était finalement que le début de nos aventures...