Travailler avec des Helm charts open-source

Thomas Decaux
7 min readDec 27, 2021

--

Ce dimanche de noël me donner envie de faire une petite story rapide, en français pour changer un peu!

Je vais vous expliquer comment nous utilisons chez Datatok consulting, les charts Helm communautaires, provenant de github (par example), comment nous arrivons à mêler le côté pratique de l’open-source (je prends , j’utilise, gratuitement) et le côté business (je travaille pour le use-case de mon business).

L’architecture

Petit tour rapide pour expliquer comment on en arrive la, focus sur le deploiment.

La grande majorité de nos clients utilisent un cloud pour avoir un environnement kubernetes, avec github privé ou un gitlab hosté, nous arrivons en tant que conseil à ce moment la:

Nous conseillons d’abord des concepts , à la limite de la philosophie:

open-source mais pas trop

Mettre son travail en open-source dispo à tous c’est super, mais déjà ça peut intéresser .. personne ^^ surtout si c’est un use-case très métier. Ensuite il peut avoir un risque de sécurité: “merde j’ai leak des IPs dans le code”, ça arrive vite. Et aussi, business is business $$ , “coup de fil des actionnaires, y a notre code sur github”. Donc on ne va pas tout mettre sur github, y a des choses à garder secret.

gitops: utiliser git en tant que source de vérité pour objet k8s

Tant de chose à dire sur gitops, déjà faisable avec des outils comme Ansible, et à son paroxisme avec kubernetes. Je vous invite à chercher sur le net, il y a déjà beaucoup de choses sur ce sujet.

package : toute chose à déployer doit être packagé

  • améliore la portabilité : 1 code à maintenir pour être à jour avec la version de kubernetes
  • améliore la lecture / compréhension (grâce au découplage templates/values)
  • permet de faire des tests facilement
  • séparation des roles (team A produit un package, team B utilise ce package), permet de monter en compétence + facilement

sécurité : toute chose déployée doit respecter un cahier des charges stricts

  • garantir la sécurité de l’application (no root)
  • garantir la sécurité de l’infra k8s (dossier en lecture seule, définition des resources mémoire et CPU, throttle CPU, restrictions flux réseau)

Nous arrivons dans 90% des cas à l’architecture:

  • argoCD : pour déployer sur k8s des resources (Helm , manifest YAML k8s) hébergées dans un repository git (ex: repo privé sur github)
  • gitlab registry ou harbor ou github registry: pour héberger nos images des containers
  • chartMuseum ou harbor ou github pages: pour héberger des charts Helm
  • polaris: pour faire respecter des best practices et l’ordre dans k8s https://github.com/FairwindsOps/polaris
  • network policy : pour sécuriser nos flux réseau
architecture déploiement — focus sur packaging

Travailler avec des charts Helm OSS

La majorité des ressources charts Helm sont open-source, sur github. Vous allez donc déployer dans votre infra du code “third party” ou “vendor” que vous ne maitrisez pas; or même si k8s est un standard, vous aurez besoin de personnaliser les charts Helm que vous trouverez sur github, pour matcher votre architecture (surtout pour les règles Polaris …).

Qui n’a jamais “modifié un code vendor” en Php pour envoyer un fix rapide en prod ? Et bien avec Helm ça va vite devenir la même chose:

“le Helm elasticsearch ne marche pas avec Polaris”

“Comment je peux mettre une network policy dans mon cluster RabbitMQ”

bref le besoin est la, maintenant on passe à la pratique!

Ma recette magique

… ou presque ! Rappel des besoins:

  • récupérer du code vendor au sein de notre infra
  • mettre à jour ce code depuis l’origine
  • utiliser ce code dans notre infra
  • modifier ce code selon nos besoins infra & business
  • contribuer parce que c’est ça l’open source!

Let’s go! on va prendre pour example le repo https://github.com/elastic/helm-charts (dont je suis contributeur).

récupérer du code vendor au sein de notre infra

On commence par forker la bête ! Même si vous utilisez un gitlab hosté chez vous, le fork vous permettra par la suite de proposer vos changements et ainsi de contribuer à ce magnifique projet:

Si vous utilisez gitlab, créer un nouveau projet vide, nous allons le remplir ensuite à partir de l’origine (voir la partie suivante).

example de topologie 1 repo four-tout

Il est important de garder 1 projet git gitlab == 1 projet git github, et non pas de faire un gros projet git four-tout synchronisé avec votre hébergement chart Helm. Cette dernière technique va devenir très rapidement le “bordel” et vous découragez de toute synchronisation avec le repo original.

mettre à jour ce code depuis l’origine

Pour mettre à jour un fork depuis le repo d’origine, git propose un moyen très simple: ajouter un “remote” (un remote git est un repo distant, un projet local git peut avoir plusieurs remotes).

a ce stade la, on va se retrouver comme ça:

pour mettre à jour, un excellent article de nos amis github: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

L’idée est de mettre à jour l’upstream, puis de faire des merges ou des cherry-picks pour mettre à jour notre branch de release.

utiliser ce code dans notre infra

Maintenant que nous avons du code, nous allons voir comment l’utiliser dans notre infra. Le hosting des charts Helm est très simple:

  • un fichier “index.yaml” qui sert de listing
  • un ficher tar.gz qui sert de package

On peut utiliser github pour héberger ses charts, très simplement, avec https://github.com/helm/chart-releaser-action , mais aujourd’hui, github n’est pas (encore) fait pour ça. Il y a aussi https://goharbor.io/ qui offre cette possibilité (en + d’héberger des images Docker).

ChartMuseum

Pour cet article nous allons utiliser chartmuseum, une app très simple, faite par Helm exprès pour ça, https://chartmuseum.com/ .

Je vous laisse voir pour l’installation , paramétrage du storage backend etc… nous, nous allons faire un peu de CI pour automatiser le workflow de développement de chart Helm: “en tant que devop, je créé un chart Helm, je veux le déployer sur chartmuseum lors d’un git push”.

Versionning

Etape très importante, comprenez bien que nos charts packagés doivent être “immutables”, c’est à dire qu’une version une fois déployée ne peut pas être modifié. (enfin en best practice, dans les faits c’est possible …).

Je vous conseille d’adopter le schéma de versionning suivant, compatible avec semver utilisé par Helm:

version = “${VERSION_VENDOR}-${MY_PATCH_VERSION}”

pour ne pas altérer le fichier “Chart.yaml”, vous pouvez stocker la version dans un fichier VERSION, dans le dossier du chart ou root si les charts sont alignés (même version).

On va utiliser l’outils https://github.com/chartmuseum/helm-push/ pour pousser sur chartmuseum un chart directement depuis son dossier:

Ici:

  • on utilise une image Docker avec helm et le plugin cm-push
  • on utilise un fichier VERSION pour garder dans git la VERSION des charts, <!> le chart est immutable, on ne modifie pas, on bump la version <!>

NB: on peut aussi en profiter ici pour remplacer des valeurs à la volée, avec l’outils “yq” , comme l’URL des images Docker par défault.

Pour utiliser ce chart, il suffit de le référencer dans une application argoCD:

ici je mélange un chart de github , et un chart privé.

modifier ce code selon nos besoins infra & business

De base, certains charts ne vont pas fonctionner directement, on va devoir faire de petites modifications comme ajouter un securityContext sur un container, ajouter des volumes etc…

Nous avons donc une branche de travail , connectée via de la CI à un hébergement de chart. On peut facilement faire notre popote sur cette branche, incrémenter VERSION et pusher.

Evidement je vous conseille d’utiliser un git-flow feature branch pour ensuite proposer votre bout de code sur le projet original.

contribuer parce que c’est ça l’open source!

Et oui! Soyons un peu sympa, si on a fait un super fix pour notre projet business, dont be greedy. On va pousser notre feature branch sur notre fork github, et faire une Pull Request:

ET la normalement, vous devez être tout content!

--

--